SkoolKit 8.9 has been released. To get a copy, please head over to the download page, the Python Package Index, or GitHub.

I am aware that Z80 instruction set simulation has been a recurring theme here lately, so let me apologise up front to readers who have no interest in the topic that this article continues - out of necessity - with the simulation motif. Perhaps it will have faded by the time 8.10 arrives; we shall see.

So with that apology out of the way, let’s get started. First, the good old --sim-load option of tap2sna.py. Not content with the fourfold increase in its performance from 8.7 to 8.8, I have added support for accelerating the tape-sampling loop of the most common loading routines out there: Speedlock, BleepLoad, Alkatraz, to name but three. To give an idea of the improvement in simulated LOAD times that this feature brings, here are some examples showing the performance of 8.8 and 8.9 on my computer using Python 3.11:

  • 0m25s (8.8) v. 0m16s (8.9) - Fairlight (Alkatraz)
  • 0m49s (8.8) v. 0m12s (8.9) - Black Lamp (BleepLoad)
  • 0m35s (8.8) v. 0m08s (8.9) - Satan (Dinaload)
  • 0m35s (8.8) v. 0m17s (8.9) - Skool Daze (Microsphere loader)

tap2sna.py in 8.9 also comes with improved support for TZX files, specifically for loops, pauses, and unused bits in data blocks. This along with the new --tape-start and --tape-stop options (for snipping redundant parts off each end of a tape) means that --sim-load now works with more games than ever before. In fact, in a recent test of over 6800 TAP and TZX files that the Fuse emulator is able to LOAD correctly, --sim-load produced a working snapshot from all but three of them:

  • 1999 - the TZX file fails to LOAD, but the TAP file LOADs successfully; interestingly, I have a copy of an older TZX file named ‘1999 (Alternative).tzx’ that has different pulse timings and LOADs perfectly
  • Blood Brothers - the TZX files for the Spanish releases of this game fail to LOAD, but the TZX file for the Gremlin Graphics release LOADs successfully
  • Gold Mine - this one fails because the loader depends on timing-accurate simulation of code running in contended memory, which is not supported at the moment (and may never be)

In other simulation-related news, trace.py now sports an --interrupts option, which switches on the execution of interrupt routines. This new feature enables us to answer such important questions as: What does the screen look like after Skool Daze (whose main loop depends on interrupts being enabled) has loaded and 10 million instructions have been executed without any keyboard input?

$ tap2sna.py --sim-load --start 24288 skooldaze.tzx sd.z80
$ trace.py -i --max-operations 10000000 --dump sd-10m.z80 sd.z80
$ sna2img.py -s 2 sd-10m.z80 sd-10m.png

So now we know. And now you know all the good stuff about SkoolKit 8.9. There were a few other changes and several bug fixes since 8.8 that are not detailed here, but if you wish you can consult the changelog for information on those. Let me keep you no longer from downloading a copy of 8.9 and converting your collection of 48K TAP/TZX files into pristine snapshots.