Pico MZ-700 – First release
When I first started thinking about writing an emulator for the Sharp MZ-80K in September 2024, I decided that I was only going to attempt that model and no more. 15 months later (and a surprising RetroChallenge 2024/10 win)1 and here I am with an MZ-80A and MZ-700 emulator as well. Never say never, I suppose.
The code is scruffier than I’d like it to be, but it does seem to work reasonably well. The main changes / additions compared to the MZ-80K and MZ-80A emulators were:
- Colour. The VGA module needed to be upgraded to cope with the 8 colours available. This was easier to achieve than I initially thought.
- 512, rather than 256 characters. The first 256 characters are dealt with in the same way as the earlier MZs, the second character set is only accessible through POKEs when S-BASIC is running. These characters are flagged using one of the spare bits in the colour VRAM and are dealt with at the same time as setting the colour information. The clunky way in which the second character set is handled in software has all the hallmarks of a last minute hardware addition!
- USB keyboard -> Sharp keyboard mapping. Different again to the MZ-80A and MZ-80K. There are also five function keys to deal with (and for backward compatibility reasons with the early MZ emulators I’ve mapped USB F5 – F9 onto the Sharp’s F1 – F5).
- Banked RAM. This is implemented differently to the method used on the MZ-80A (of course). It’s split into two banks – one of 4K and the other 12K. The 4K bank can be used to replace the monitor ROM at address 0x0000, the 12K bank can be used to replace the VRAM, devices and other ROMs between addresses 0xD000 and 0xFFFF. Each bank works independently and are ‘all or nothing’ – the bank is either active or inactive. Most software I’ve found only ever seems to use the 4K RAM bank. I guess that’s not too surprising given that using the 12K bank means that you lose access to the VRAM and devices!
- Sound. This took a while to figure out. On the MZ-80K and A, address 0xE008 is used purely for outputting sounds. The note frequency (pitch) is stored as a 16 bit divider for a counter running at 1Mz on the internal 8253. The length of the note is determined by the value stored in the counter multiplied by another value to determine the tempo. The note is played for as long as it takes for the counter to reach zero, by setting and resetting the least significant bit of 0xE008. My implementation was simple – every time E008 was accessed I simply decremented its value. This isn’t good enough on the MZ-700 as E008 is shared by the optional joystick(s), making the other bits of the address significant. The counter frequency is slightly different too. A fix seemed trivial (as I’m not currently emulating joysticks) – alternating the return value of the function to read E008 between 0xFF and 0xFE rather than decrementing it. But as I have a delay in this routine to slow down the Pico, that method didn’t work properly for rest notes! Much hair pulling later and I have a solution that only triggers the delay in rdE008() if the counter is active. Solo Software’s ‘Demon Driver’ and Zat Software’s ‘Painful Man’ were invaluable in making sure that I’d got this right.

I took the opportunity to clean up some pieces of code that also affect the MZ-80K and MZ-80A emulation, so I needed to put the emulator through regression testing and benchmarking. With the exception of the RC2014 VGA boards running as a MZ-80K2, all of the MZ variants are within +/-0.32% of the run time on a real machine when tested with a BASIC program that finds the primes up to 7,500.

The full benchmark results are in the project’s documentation directory if you’re interested, along with completely re-written notes explaining how to install and use the Pico MZ as a MZ-80K, MZ-80A or MZ-700.
The current release (v3.0.0 as of me writing this post) for Pico/Pico 2 on a Pimoroni VGA demo base and the Pico on RC2014 VGA cards can be found in the usual place.
Have fun – and do let me know if you find any issues. (I guarantee that I will find a showstopper within an hour of hitting the ‘publish’ button …)
Anyway, I’m taking December off from working on the Pico MZ to have some fun with Advent of Code. Depending on the implementation difficulty of the problems, I may even try to solve a couple with S-BASIC.
- I believe that I’m the only person ever to come dead last in the 10 liner BASIC competition and win a RetroChallenge prize, a record that I’m certain will never be equaled. ↩︎
- I’m really not sure why this is the case. The MZ-80A result on this board was perfect! It’s around 3.5% too slow, but I’m reluctant just to increase the Pico’s clock speed. My guess is there’s an inefficiency somewhere that needs fixing for the MZ-80K emulation, so I will leave that to version 3.0.x next year. ↩︎