I am working on an FPGA implementation of the original Space Invaders arcade machine and I'd like to implement access arbitration between the CPU and the video system. I can imagine several ways of doing it, and I would like to know how it was done on the real machine so I can implement something similar.
To recap, memory mapped to the CPU from 0x2400 to 0x4000 is an 8-bit-addressable 7K frame buffer where each byte represents 8 subsequent monochrome pixels. Obviously this memory needs to be accessible to the video system in time to draw the pixels as the electron beam sweeps across the screen.
1. Dual port RAM
In this setup, both the CPU and the video system can access the same memory at different addresses. Was this technology even available in 1978? Especially at a reasonable price?
2. Duplicate RAM with fanout writes
By using two 7K RAM modules, and fanning out writes from the CPU to both, we can have the CPU read from one and the video system read from the other, with no contention whatsoever. Of course, in a real hardware implementation, this requires an extra 7K RAM, which again is probably too expensive a solution in 1978.
3. Suspending the CPU via the
READY pin during the entire visible screen
Quite extreme, but easy to implement: only allow the CPU to run during the horizontal and vertical retrace. While wasteful of CPU cycles, I think for Space Invaders this is probably viable, since I was able to get the game in a playable state (in an emulator, with no memory arbitration) with the CPU running in the low-hundred KHz range, so there is probably enough slack to make this workable.
4. Same as #3, but using the
HOLD pin to only inhibit memory access from the CPU
This would allow the CPU to do a bit more work during the video system's VRAM access, and if I understand it right, it would require less components between the video RAM and the CPU since the CPU would electronically isolate itself from the bus.
5. Suspending the CPU (via
READY) or inhibiting memory access (via
HOLD) for every 8th pixel
Video system can read one byte at every 8th pixel into a shift register, then shift it out bit-by-bit. CPU only needs to be cordoned off from the video RAM for 1/8th of the time.
6. Suspending the CPU depending on the value on the address pins
This is the most efficient one I can think of, but also the most difficult to implement. In this scheme, the CPU is suspended (via
- The video system is accessing the VRAM (every 8th cycle during visible portion of the screen)
- The CPU is requesting a read or a write to an address that is in the interval 0x2000..0x4000.
It seems to me that this would also require separate circuitry to isolate the CPU electronically from the bus, since by the time we can discover that the CPU is trying to access the video RAM at the wrong time, it would be "too late" to ask the CPU to release the bus.
7. Tick/tock access
(from a comment by user Janka): We can interleave memory access from CPU and from the video system by running them in two different clock phases (e.g. CPU on even, video on odd).
Although this makes sense intuitively for me, it is unclear how synchronous RAM access would work in this scheme, since the RAM would always have to reply with the contents of not the last, but the second-to-last cycle's address bus contents, right?
8. Other schemes I haven't thought of yet
Obviously the most exciting category.
So my question is, which of these approaches (or something else) did Space Invaders do to solve video RAM contention?