The basic principles of ZX video are fairly simple but there are many details that I'd rather not have to learn.
Someone who does fully understand ZX81 video - the remarkable Andy Rea - pointed me to articles written by an earlier expert, Wilf Rigter, in the ZXirQLiveAlive magazine:
Vol 6 No 4 page 19 (part 1)
Vol 7 No 1 page n27 (part 2)
Vol 10 No 3 page 7 (part 4)
Googling around, I found it in HTML (and German) and got Chrome to translate it. This gives a more readable form than the scanned magazine articles. There are a few errors such as figure numbers so I polished it up to my own style.
I've learned some interesting tricks that I'd like to incorporate into my own future designs.
- A normal 16K DRAM expansion appears when A14 is high and as a non-executable alias when A15 is high, which is fine when you have just 16K. If you have a 32K RAM expansion, half is usually wasted by tying A14 high or low. A handy and easy mod is to feed A15 and /M1 into an AND gate and wiring the result to A14 of the 32K RAM. Two diodes and a pull-up resistor will do. This means the CPU will get bytes from the lower half when it 'executes' the display file, but can read and write data to the upper half. You can't run machine code there, but you have 16K for storing data.
- Normal ZX80/81 logic forces a nop code whenever A15 is high. If you are recreating a ZX80/81, you can limit this to the last 16K (A15 and A14 high). You can then run machine code between 32K and 48K.
- The hi-res graphics methods in the article involve ANDing the /RD signal with /RFSH and feeding the result to the RAM. This reads the RAM during refresh cycles as well as the usual read cycles.
It also ties the /RFSH pin of the RAM expansion high, which prevents any refresh cycles happening on dynamic RAM boards. You are probably limited to static RAM expansion. - The address lines are driven by the I and R registers, so each video line has to execute a row of NOP codes while the I and R registers point to an "H-file".
- The G007 was designed to not need mods, the LS374 latch is there to store the bus data when a video byte "opcode" is read, and then present it to the bus during the refresh pulse when the shift register is being loaded. The address lines are driven by the program counter, using a "D-file" in a similar way as low-res video.
- The G007 method seems the best, but I'd like to be able to support both methods if possible, because there are many old programs using the Wilf Rigter method.
- Comparing the G007 and ZX80 logic looking for common circuitry, I can see a couple.
- The signal that latches the video byte is identical: MREQ & /RFSH * /CLK
and it latches the data at the end of T2.
I think it could work with just the rising edge of /RD or /M1. The ZX81+38 circuit uses /RD. Signal /M1 happens less often than /RD and thus generate less RF noise, but /RD rises sooner. - The signal selecting the latch output is /RFSH on the ZX80, and /RFSH during high-res graphics mode.
- D7 and D7 are forced low when high-res graphics mode, A15 high, and /M1 low.
It looks like G007 U7A, U9A, U1B and U1C exist just to prevent the expansion memory board D7 and D6 from being pulled low. I thought I could do Sinclair's trick of using resistors to limit the conflict (resistorplexing?), but there are already resistors in the D7/D6 signal path. If I'm integrating the G007 logic into the ZX81 logic, maybe I could pull D7 and D6 low at the CPU side of the resistors and then omit the isolation circuitry.
- The signal that latches the video byte is identical: MREQ & /RFSH * /CLK
- Most of the circuit does the memory patching. If using a pre-patched ROM, maybe this can be omitted?
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.