Last November, Scott Swazey asked why I made my own boot loader instead of using the original M9312 code.
I knew that the sources for M9312 were available, and I did have a look at them a long time ago. At that point, I was not sure I would ever get the CPU running, let alone booting from disks. And the code looked, well, complex and unlikely to run unless the hardware would mimic the original exactly. Also that seemed hardly possible at that time.
Later, when I got the first disk controller working, I just copied the boot loader from the simh sources – which I studied to get an idea of which parts of the disk controller were essential and which I could skip. And after the second and third disk controllers came into being, I just followed that pattern. Eventually that turned into T44 – the boot loader so far, the one that will announce itself with ‘Hello world’ and then proceed to boot from the first disk on the first available controller it knows about – RK05, RL02, RP06, in that order. Since in most cases the systems have one SD card only, and thus only one controller, that conveniently works for most cases. But Scott was building a system with both an RL and RH controller, so wanting to boot from a specific disk made total sense. So we looked into the challenge of making the original M9312 code work.
The first issue was that the M9312 code used absolute psects – as in, code to be fixed at a specific address. I knew there was an issue with that in my macro11 toolchain, but I never found what it was. Scott found it quickly though, it was a rather embarrassing mistake I made in the replacement of the macro11 linker that I modified to output the VHDL source for the boot roms.
After that, it was surprisingly simple. Just a question of adding the secondary boot rom at 165000, and I restructured the original device boot roms into one source – so it will fit into a single rom image. A bit later, I also changed the interpreter to accept lower case input – the original only works with upper case, which is a bit awkward.
- L <octal value> : set address
- D <octal value> : deposit value at address
- E <space> : examine data at address
- S : start program
It also accepts the name of the four device bootroms as command:
- DL<#> : boot from RL disk #
- DK<#> : boot from RK disk #
- DB<#> : boot from RP disk #
- ZZ : run diagnostic
To make space for the lower case input, I had to remove some of the code from the original interpreter source – a bit of diagnostic code that would run on first boot. That also leaves some leftover room to reintroduce the ‘Hello world’ message – I’ve become used to that, and I’m missing it now. Or maybe some more user friendliness in the command interpreter, it’s very historic in the original state – and although it is somewhat fun to have it work in that way, it also makes for a lot of typing mistakes.
Next to his work on the booting stuff, Scott also found a mistake in the RL controller. The adders for the sector address were not wide enough, so an access to the fourth disk could wrap around to the first. That’s fixed now. He also made a suggestion to offset the disk images on the card, and use a standard MBR to address those images. After some long and hard thought, I decided not to include this – it may be convenient in some cases, but it also conflicts with the future plans I have for the disk controllers.
I haven’t decided yet if I will include the new boot loader into all prebuilt bitstreams. For the simple setups at least, the old boot loader scheme still makes sense. What I’ll definitely do is integrate both to use a joint code base for the device boot roms.
Updated sources will be published in a couple of weeks, I’m currently working to include Terasic’s C5G board into the distribution. After that is finished, I’ll post the new sources.