Sunday, August 6, 2017

Fast booting the MEGA65 with custom bitstream, kickstart and ROMs

The last couple of days I have put some more work into makingg a stream-lined software development process for the MEGA65.  The goal is to make it possible to test changes to software in a few seconds, and without hassle, instead of mucking about with pulling SD cards out, flashing the SQI flash on the FPGA boards and generally forgetting what it was you were trying by the time you got your modified software loaded.

An additional motivation for this is that the SD card interface on one of our hand-modified prototypes is not working at the moment, and Falk needed another way to get bitstreams, Kickstart firmware, C65 ROMs and software he is writing onto the machine easily.

This was a new requirement, that required something more advanced than the monitor_load utility that I wrote last week to solve some of these problems. 

Specifically, it needed to be posssible to load a C65 ROM and character ROM image, without ever even initialising the SD card.

So I set about modifying monitor_load to load the ROMs into the correct memory location.  That was fairly easy, apart from a little speed bump caused by the limitation of the bulk memory upload command in the serial monitor.  That problem is that the address counter when loading only increments the bottom 16 bits of the address, combined with the start address needing to be one less than the first address.  

For example, to load memory to pre-load $20000-$2FFFF, i.e., the first 64KB of a C65 ROM, we couldn't just subtract one from the address, and say l1ffff 2ffff, because it would only increment the bottom 16 bits, and leave the "1" at the front of the address the same.  (The "l" in front of the address is the command code to tell the serial monitor to bulk load memory.)

Instead, we have to say l2ffff 2ffff: 1 is added automatically, but only to the bottom 16 bits which rotate over from $FFFF to $0000, leaving the leading "2" unchanged, for a complete address of $20000 -- exactly what we want.

The next challenge was how to tell Kickstart not to initialise the SD card, but instead to just launch the loaded ROM.  My simple solution to this problem was to add two consecutive instructions just before SD card initialisation would occur:

  BIT go64
  BIT $1234

where go64 is the label in the assembly language of the routine to launch the loaded ROM.  The monitor_load program searches for this signature, and changes the first BIT instruction into a JMP, so that it becomes JMP go64, thus exiting to the loaded ROM, without worrying about the SD card.

With this change in place, there is really very little for Kickstart to do, and it does it so quickly at 50MHz, that you don't even see the MEGA65 kickstart screen, before it drops to C65 mode, as can be seen in the following video:

What is also really nice is that the whole process takes only a few seconds.  You can see that the FPGA fires up in a couple of seconds. Much of the rest of the time is waiting for the monitor to wake up from sleep.

Combining this with the existing ability of monitor_load to load and automatically run a program in C64 mode (and C65 mode would not be hard to add), it is possible to execute a single command that loads the bitstream, kickstart, C65 ROM and program of choice, and sets it running -- all in less than 10 seconds, as can be seen in this video:

As usual, the curious can checkout the source code on github.

(Also, for the curious, the strange program that runs in this video is an old test of the hardware-accelerated proportional text mode that the MEGA65 has.  This little program takes a UTF-8 text file, and renders the variable width glyphs in text mode, which makes it both fast, and very memory efficient, as repeating the same character re-uses the glyph memory.) 

For Falk and the machine without a working SD card, the next challenge is to provide remote control of the floppy controller, so that D81 disk images can be used, without having to load them on the (in his case, not working) SD card.

The ability to automatically trap to the hypervisor already exists, and it is now a case of writing the trap code in Kickstart, and modifying monitor_load to interface to it, so that a disk image can also be specified when starting the machine, and knowning that all disk access will be redirected to it.

With that in place, the ongoing development of the MEGA65 version of GEOS will hopefully be able to proceed very quickly, with no inserting of SD cards required.

And it shouldn't take too much effort to make the disk virtualisation code, because we already have the tools to iterate on the Kickstart firmware very quickly, through monitor_load itself.

No comments:

Post a Comment