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. I have since updated this to also include a section about the updates to the LOAD routines.
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.
Flicker-free games
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:
http://www.fruitcake.plus.com/Sinclair/ZX80/FlickerFree/ZX80_DisplayMechanism.htm
https://github.com/markgbeckett/zx80/tree/main/hampsons_plane
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.
Breakout
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, that is what is used in the ZX80 ROM. 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.
Space Invaders
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.
Hampson's Plane
George Beckett has produced a flicker-free implementation of Hampson's Plane for the ZX80.
https://github.com/markgbeckett/zx80/tree/main/hampsons_plane
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.
Mazogs
Paul Farrow has adapted Mazogs to run on the ZX80 with flicker-free display.
http://www.fruitcake.plus.com/Sinclair/ZX80/FlickerFree/ZX80_Mazogs.htm
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?
LOAD routine updates
The new LOAD and SAVE routines I wrote were covered in the previous post. I added a status box, which showed the address currently being loaded. This started at 4000 and went up to the end of the file.
I was thinking as I was testing these files that it would be nice if there was an actual progress bar.
It should be possible as the file size is known. That is the way LOAD knows to stop, when it gets to the end address.
The calculations involved to scale this would be a little complicated and probably too much work. I started looking at showing a bar that simply ran from 4000-7FFF, the standard 16K RAM. Only the largest programs would get to the end of the bar, so that may be interesting, but is probably not much use.
Instead I decided an easy alternative was to switch to showing bytes remaining. The user then sees a countdown of the number of bytes still to be loaded, so you can watch it could down to 0000 when it will have loaded.
It will actually start with the wrong number at first, due to the way the ZX80 works. There is a sort of file header which is actually just the RAM from 4000 upwards. This starts with system variables and includes at 400A the address of the end of the program. At the start of load, the value of the high byte is incremented, so it should be at least long enough to get passed the point where the values at 400A have been overwritten by the value stored on the tape, which is the actual end address. After that point, the displayed value will be correct.
SAVE has also been similarly updated, so a countdown to 0000 as it is saving.
Results
With the exceptions of the Kong and Pacman, all the games I have tried have worked.
There are a few games that I know will not work. The Metropolis demo (which I believe was developed on a Minstrel 2) uses a complete replacement display routine, so that will not work with this hardware. The same is true of the two Beam Software games (Super Invasion and Double Breakout) and QS Defender, as they also replace the entire display routine.
I think pretty much any other 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 keyboard routines, and does not mask off the unused bits, it may not read correctly depending on the method of testing the keys.
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 will work as long as they do not replace the entire display routine.
Any flicker-free games that use OUT FE,A in the display routine will cause the speaker click. Any that do as the ZX80 ROM does and use OUT FF,A (or can be patched to do so) will be fine.
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.
http://blog.tynemouthsoftware.co.uk/2023/12/zx80-basic-on-the-minstrel-4d-part-4.html
Advertisements
Minstrel 4D
Minstrel 4D kits and ready built units are available from thefuturewas8bit.com
https://www.thefuturewas8bit.com/shop/tynemouth-products/minstrel4d.html
Patreon
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.