Continuing the series of posts from Patreon in November, working on getting ZX80 BASIC running on the Minstrel 4D. This one reworked from several posts.
In the previous post I got ZX80 BASIC running on the Minstrel 4D, and with the help of new LOAD and SAVE routines was able to load ZX80 games.
This is a modified ZX80 ROM running on Minstrel 4D hardware which was designed to run the Jupiter Ace ROM.
I had tried lots of programs which used the normal ZX80 display mechanism, including board games and text adventures etc. Games that suit the display - think - display type mechanism the ZX80 used.
Due to the way the screen is displayed on the ZX80, it was not possible to do the sort of fast moving shoot-em-up style games, at least not in BASIC.
I wanted to see some space invaders, and luckily back in the day some ingenious methods were found to make that happen.
All of the games I had tested up to this point used the display in the standard ZX80 way. There would normally be a screen flicker when the AI player was making there move, but here the screen remains static until it is next updated.
I am hoping that the many "flicker-free" games for the ZX80 will be usable
The idea in brief is to bypass part of the display routines in ROM, and then run short blocks of precisely timed code in the gaps at the top and bottom of the screen, returning to the ROM code to do the actual screen drawing.
Each of the blocks of code needs to take exactly the same number of cycles, so you have to be very careful with anything that is conditional (did the player fire, does that alien need to move down a row etc.) so that all paths through the code take the same number of cycles.
I will link for reference Paul Farrow and George Beckett's work on this subject:
The first one I tried was a simple demo from the article that first introduced this concept.
That was unfortunately the only one that worked at that point.
I did some more research and a bit of debugging, and was able to tweak the way my new display routines generated the display to fit with the expectations of the flicker-free games.
I started with probably the earlier games, those from Macronics (http://www.fruitcake.plus.com/Sinclair/ZX80/SoftwareArchive4K/Macronics.htm)
Breakout is working well, with a small caveat. It takes over some of the display drawing, and includes turning on and off the VSync generator. Yes, the same one that now drives the speaker. Yes it now makes a ticking sound.
The code use IN FE and OUT FE instructions to turn on and off the sync generator. The actual values used are not important on the ZX80. The IN is only decoded as IO READ where A0=0, i.e. any even address would do. The OUT is only decoded as IO WRITE, so any address could be used. FF seems the best option, as FD is used on the ZX81 to control the NMI generator (decoded as A1=0), so FF is safe as it will not trigger either of those.
See http://blog.tynemouthsoftware.co.uk/2023/10/how-the-zx80-generates-video.html for more details.
They published breakout as a type in listing. Yes, that is the entire game. The highlighted D3 FE is the relevant instruction, changing that to D3 FF will stop the clicking sound and will still work on the ZX80 and the Minstrel 4D.
George Beckett generated a patched version, and that works nicely. It is not ideal, but patching the games or modifying the hardware are the only options here. There are only a few games like this, so we can provide patched versions of any of those which use OUT FE.
Macronics released two versions of Space Invaders (or Space Intruders), a full screen one for 3K RAM which works fine.
They also produced a version which runs on an unexpanded 1K machine. To make that fit, they reduced the number of rows on the screen. Trying that version on the Minstrel 4D, the game is playing correctly, but the remnants of the BASIC program are still visible in the part of the screen that is not being updated. (note this is one of those games where you need to type GO TO 100 to start it rather than run)
I adjusted my display routine to pad out the rest with spaces, so that now works fine.
I could centre it vertically based on the number of rows being drawn, but as far as I know it is only this one game, and is how it would have looked on the ZX80, so I will just leave it for the moment.
George Beckett has produced a flicker-free implementation of Hampson's Plane for the ZX80.
It didn't initially work, but that turned out to be it not detecting that a key had been pressed. The actual display side was fine it was just waiting for the user the enter the skill level.
The keyboard differences will be an issue for a few games that implement their own keyboard routine, reading a byte from the keyboard port and then doing a comparison without masking off bits.
On the ZX80, bits 0-4 are defined for the keyboard columns. The other three are not relevant to the keyboard. Bit 7 is the tape input, and will normally be low. Bit 6 is pulled high on UK systems, but will read low on USA systems, and bit 5 is undefined so may read high or low.
On the Ace, the same bits 0-4 are defined for the keyboard. Bit 5 is the tape input, again normally low. Bits 6 and 7 are undefined but will float high on the Minstrel 4D. (see a previous blog post about the issues a similar problem caused with type 2 interrupts on the game Valkyr).
I suggested rotating a bit at a time into carry and testing that, which also worked out a bit more efficient and is consistent timing.
However, there is another issue because it has it's own keyboard scanning routine rather than the ROM one, it will misread the bottom row (see the previous post)
It would be possible to produce special builds for the 4D or possibly one that detects the system. There are various ways that could be done.
- Read of port FE, bit 7 will be high on the 4D, but is the tape on the ZX80, so will read low.
- Alternatively, and probably more reliably, pick a byte in ROM that is going to be different. The first byte in the ZX80 ROM is 21. But the new 4D version is C3, so just read 0000 to tell.
- Or maybe a more subversive method would be to add "Press C to continue" on the first screen, and then seeing if that reads as C (ZX80) or V (Minstrel 4D).
George implemented the changes (with Press C to start) and also switched to using OUT FF to get rid of the background hum and it is now running well on both the ZX80 and the Minstrel 4D.
Paul Farrow has adapted Mazogs to run on the ZX80 with flicker-free display.
I was pleased to see that ran well. It also ran without the clicking sound, I believe it uses OUT FF instructions, so does not trigger the speaker in the Minstrel 4D.
But unfortunately his versions of Kong and Pacman do not. I think this is something to do with the autostart rather than the flicker free, but I will investigate further. (they are now working, but that is a whole blog post of it's own - coming next week).
This is all I get when they load?
With the exceptions of the Kong, Pacman and the Metropolis demo (which I knew would not work), all the games I have tried have worked.
I think pretty much any ZX80 software will just work, but there are a couple of caveats.
Anything in BASIC should be fine, and even machine code as long as it calls the ROM routines for reading the keyboard reading, load and save and video generation, everything is fine.
If any code has it's own keyboard routines, then the bottom row of keys will read wrong.
If any code has it's own load routine, they will fail as the tape signal is read from a different pin.
Flicker-free games are also working, but because they have a partial display routine which includes sending the signals that now trigger the speaker, there is going to be humming without a hardware mod or patching the games to not use OUT FE,A
In the next post I will go into details of why Kong and Pacman were not working, and what was required to get them running.
Minstrel 4D kits and ready built units are available from thefuturewas8bit.com
You can support me via Patreon, and get access to advance previews of blog posts and behind the scenes updates. These are often in more detail than I can fit in here. This also includes access to my Patreon only Discord server for even more regular updates.