Thursday, January 3, 2019

More work on the MEGA65 built-in freezer

Yesterday I posted the progress on the built-in freezer for the MEGA65, and explained a bit how it works.  However, at that point in time, the freezer was not really functional -- it could save and restore some memory and IO registers, but not without problems, and thus it wasn't possible to actually resume a program after freezing.  That has changed today!  After quite a bit of fiddling, the freeze and unfreeze routines are now much better, and generally work.

The main progress is that I am able to save the main memory, the colour RAM, the VIC-IV registers (including the colour palettes), the MEGA65 Hypervisor saved state (which is really the saved state of the program being frozen, since it was saved on entry to the Hypervisor, which is what is actually doing the freezing), along with most of the new MEGA65 registers, e.g., those at $D7xx.

The result is that the program gets fairly convincingly frozen. But this is no good, if the program can't be unfrozen after.  But this also works just fine now, as the following video of me playing Krakout and freezing and resuming it multiple times shows.  (Apologies for the shaky video, I don't have my good camera and tripod here at home.  Similarly the general lack of audio due to the Zoom recorder also not being here.)

What is clear is that we can freeze and unfreeze a real game, and it resumes without any noticeable problems.  Even multiple times, is not a problem. It also works fine to freeze BASIC, as the following freezing, frozen and un-frozen images show:

Just to prove that it was still alive after, I typed some rubbish:

(Note the fun feature of the later C65 ROMs of showing error messages in red, regardless of what the cursor colour was before).

While I would like the freeze and unfreeze time to be a little faster, it is already quite acceptable.  Once we have the 8MB expansion RAM in the MEGA65 working, we will be able to freeze to expansion RAM instead of the SD card in the first instance, which should make freezing and unfreezing several times faster.

In fact, the main limitations at the moment are relatively few:

1. Like most C64 freezers, we can't really freeze the state of the SIDs, because of all those SID registers being write-only, and even if they were readable, they would only show what you wrote, not the current ADSR state of the voices etc.  I'll likely add some support for saving and resuming the internal state of the SIDs, so that freezing doesn't mess up music.

2. The CIAs are not currently backed up.  This is really just a little oversight, and should be quite trivial to fix.

3. The Hypervisor doesn't sanity-check the state of any previously mounted disk image(s), and re-mount them if still available.  Similarly, it doesn't check any other bits and pieces in the process descriptor block after loading it back in.

4. I noticed that by blindly restoring the VIC-IV registers that it is bad if the freeze occurred at a high raster line, because it is possible for the raster compare register to be programmed to an impossibly high raster number.  This would cause the program to effectively not resume after unfreezing, unless you manually modified $D011 to clear the high-bit of the raster compare register. Thus I should probably and $D011 with $7F after restoring the machine state.