P2 Space Invaders - 8080 Emulation
Here is the arcade machine emulator from Jim Bagley. It does Space Invaders, Space Rescue, and Space Invaders Part II. You'll need to go find the ROM files on the interwebs. Google something like. "MAME ROMs Space Invaders" to find the four 2KB Space Invaders ROMs.
I rewrote the original 8080 emulator that Jim had written, so that it uses XBYTE, which is very efficient and fast. The emulator can be studied to see how XBYTE can be used. It uses a 256-long jump+skip table and 224 instructions to realize the 8080 generic core emulation. It calls external hub routines for the 8080 IN and OUT instructions, which interface to real world. In this case, these IN and OUT routines read the pushbutton inputs and control sound output, as well as talk to a barrel shifter that was on the Space Invaders motherboard, which was used to speed up the ROM software.
Comments
Congratulations on getting all that working, wow
The simultaneous VGA and DVI (HDMI) is also a really nice feature
To find the ROMs you need to do as chip suggested above, you should find in the results a site that may or may not begin with the letter W, and then look for the ROMS that are for the MAME system and not the Spectrum or C64 etc, it has to be just MAME not a Android version of MAME just the word "MAME" in platform, and download those files. ( which is ok, as you obviously have the arcade PCB to be able to do this. ) then when you get the zip for "Space Invaders", "Lunar Rescue", and "Space Invaders Part 2" unzip them into the folder where you unzipped the P2_Space_Invaders.zip from above.
Then you should be able to build the it.
If you use...
The CONTROL board on pins 0-7
A/V VGA board on pins 24-31
DIGITAL VIDEO OUT board on pins 48-55
Then when you build and run it in either Pnut or Propeller Tool P2, it will output on both DVO and VGA at the same time, so you can use either to view it.
Audio comes through A/V board only not DVO.
Edit: Added Latest version
P2SpaciesVGA.zip now has the option to select either HDMI, VGA or both, and will only start the cogs required.
Also removed the very early debug cog that I used to show values whilst I started testing the 8080 emulator as it isn't required now.
Also removed the 0s at the end of the file so it now doesn't have anything where the 8080's 64K of ram is, so it loads that little bit faster.
Updated again, to change the
.av_base_pin long 24
to
.av_base_pin long VGA_BASE_PIN
😁
This sounds really neat!
is it running a MAME.exe created on a PC?
any chance it can do Galaga?
Cool stuff. Sadly XBYTE can't be used for emulation of more advanced systems, as it won't work with self-modifying code in RAM. There's still plain EXECF at least.
How come it can't work with self modifying code? I don't think it would know the difference.
The 8080 is being emulated in a 64KB space within hub RAM. It really only needs 16KB, though. The emulator runs the ROM code, while some special IN and OUT-instruction handlers deal with the I/O. There's also some code that Jim wrote that translates the video memory area of the 8080 RAM map into the HDMI and VGA signals.
Question:
Can either the VGA or HDMI cog be disabled?
ie can we run just VGA or just HDMI or does the code rely on both cogs running even if one isn't being used?
Running on: the Parallax 7" HDMI Display, 800 x 480 27390
👍️
You can just comment out the COGINIT that you don't want.
This is a deluxe example of using XBYTE to emulate a retro CPU! Really nice work Baggers & Chip!
Nice thanks Jim :)
BTW I tried to comment out the HDMI cog but it dodn't seem to run without the HDMI cog running ???
I see now the HDMI is creating the COGATN timing at the mid-screen display point. This will need to be in the VGA driver in order to remove the HDMI from running.
Here is a VGA version for RetroBlade2.
I have only tested the demo showing on the screen (ie no push buttons or audio).
Note: You will need to add the push buttons (L,R,S,F) to pins P4-7 and audio (L,R) to pins P22-23 or change the CON settings. VGA (V,H,B,G,R) uses pins P27-31.
If pnut comes up with a serial port error ("Hardware not responding") while loading just wait a little longer as it seems to mostly clear ok.
Both HDMI and VGA use the same timing. If we determined what it was, we could set up a timer interrupt on the 8080 emulator cog that would write the vectors and assert the COGATN signals.
Chip,
It’s not difficult. COGATN is raised twice, once halfway thru the screen display, and again at the end. So it’s only a matter of splitting the VGA screen into two halves and then add COGATN twice.
But it needs to be done for either VGA or HDMI. If we had #IFDEF it would be so easy. There are of course fairly simple alternatives. I’ll probably recompile under flexspin where we have #IFDEF.
Well, XBYTE pulls from the FIFO, which buffers quite a couple bytes ahead, so if it writes into code that's already fetched it will only get the change the next time it executes. I'd give an example, but typing code into the forum is impossible RN
Excellent work Jim & Chip!
Back in the early P2 development days (FPGA DE0-Nano /DE2-115) my vesrion of this game is how I learned P2 assembly.
Good times! :)
I thought all those old games used Z80 cpu, but I see now this one used 8080...
Tubular, cheers :D yeah I realised not everyone uses HDMI, so thought well I have plenty of Prop power left, so why not use a cog to generate VGA output.
Rayman, it's not running MAME, it's running my own version of what the Space Invaders board is, basically it's just an 8080 CPU with some RAM ( I've allowed up to 64K for it but it only uses up to 20K of the 8080's addressable space up to $5000 for Space Invaders part 2, then it has a couple of IO ports, which is are handled in code that is in HUB RAM so they can be changed depending on what you connect to the 8080 for other projects, should anyone need an 8080 for anything.
As for Galaga, it would need a full Z80 emulation and some sprites etc, but I do intent to extend the 8080 emu to full Z80 anyway, so yeah Galaga could be somewhere down the line.
Cluso, currently because they're in sync with each other to save creating the line buffers in two cogs, the HDMI cog controls the scan line pointer for the scan line render cog, ( I could do a version that has the VGA driving the scan line renderer though if you want.
Roy, Cheers, yeah I didn't even know about XBYTE stuff that the chip could do or the SKIPF stuff, when I wrote the emulator, it was only thanks to Chip's awesome help re-working my emulator to work with with XBYTE and it has sped it up quite a bit, not that it was slow anyway, it was already many times the speed of the original :D
dgately, that's great to see it running on the parallax 7" monitor :D
Chip, he can't comment out the HDMI cog just yet, that drives the scanline counter for the render cog, I'll change that today and upload an update here so you can then comment out either and it'll still work.
ozpropdev, cheers ;D yeah Space Invaders is a great game, and sunny you should say about learning p2 assembly because of it, as back in the day, whenever I got new computers or consoles, I used to write a clone of Space Invaders first, because I knew if I could get something up on the screen and have the input to move things around, and audio, I could then do whatever game I had to do on that machine.
Re self-modifying code, simply reload the FIFO after every RAM write instruction. I wouldn't bother testing the address to see whether it is really needed.
Here's the promised example (6502 ASM)
If this were to be executed by way of XBYTE, the first byte to be cleared would be that of the previously selected page, since the STA $0000,y would already be in the FIFO buffer when it is overwritten in memory.
Now that you say it, I remembered the FIFO reloads being slower, but the sheet says 10..17, +2 for a GETPTR makes 12..19. Huh?
I can't quote properly.
To save cycles, set D[31]=1 for RDFAST and put as many instructions as possible between RDFAST and the RET that starts the next XBYTE. However, P2 RAM accesses are many times faster than an old 8-bit CPU.
I worked on a conversion of Space Invaders (to 8-bit AVR) recently, and noticed that the top eight pixels and bottom eight pixels of the screen are never used. These are the first and last bytes on each scan line, because the display is mounted "sideways" so that the scan lines run vertically. Seems a strange choice to waste one sixteenth of the available screen area (and video RAM) - which were precious commodities back in 1978.
Clarification: if the screen were mounted in the regular way, it would be 256 pixels wide by 224 pixels high - but it's mounted sideways so that it's 224 wide by 256 high. Space Invaders uses the full 224 pixel width, but only 240 pixels of the available height.
I'd assume this is an overscan compensation, but on an arcade machine, they could have just calibrated the monitor properly, so that's indeed strange.
Ah, I hadn't considered the FIFO hiding memory writes for self-modifying code.
Yes, doing a new RDFAST after a main-memory write will refresh the FIFO. Only a minority of instructions would require this. It would still be way faster than doing discrete RDxxxx instructions everywhere, plus you would keep the benefit of XBYTE's fetch+lookup+jump+skip function.
Jim was showing me the Z80 instruction set and it would only benefit from XBYTE on the first byte of each instruction. Subsequent bytes would need to be manually processed.
Some tricky Z80 code uses PUSH to self modify code on the stack. PUSH and POP are a fast way of writing/reading memory on the Z80 because a single-byte instruction pushes/pops a 16-bit register pair on/off the stack.
Nice work Baggers and Chip ;-)
Jim, do the interrupts have to occur at exact scan line numbers? Or, does it just matter that they are separated equally in time?
Any idea what effective speed this emulator works out at, compared with the original 8080?
Not sure. Jim is going to measure it by controlling the border color as a time marker. I would guess maybe 60x faster.
If you think that, on average, it takes four times as many clocks to emulate as the original silicon required, and our clock rate is 250 x faster, then 250 / 4 is about 63x faster.
The video interrupt is used to gate the Space Invaders program loop, so there is no apparent speed increase. We just finish each loop much earlier.
Huh, I though the thing with space invaders was that the CPU load reducing as you shoot the invaders was responsible for making them speed up