Last night I had a major breakthrough for my SD card interface!
Not only does it work, it boots GS/OS on the Apple IIgs! 🎉
Switching the source code from Merlin-8 on the IIe to CC65 in Visual Studio and using an EEPROM sped up my development cycle quite a bit. This wasn't a fix for the issues, of course, but it helped. As usual, there were a lot of small things involved and I have learned some lessons.
First lesson: the disk status function uses the X- and Y-registers as return values. However, when you load these registers with the return values and then insert a function call that does not only save these registers but uses them for slot addressing, it will crash. There simply isn't a slot number 255 in the Apple II 😉
Second lesson: SDHC cards use block addressing, not byte addressing. Some weeks ago, my 512 MB card died and I replaced it with an 8 GB card. I knew before that it was initialized correctly, so I assumed it worked as well. The problem was block 0 was always loaded correctly, but when the bootloader tried to read block 2, it was garbage. But it was always the same garbage, so I searched the card for the first few bytes and found them in block 1024. After some research found a footnote in the SD card specification that said that the address in read and write commands are block addresses for SDHC cards.
After fixing this issue I was able to boot into ProDOS 8 and use it as mass storage under GS/OS.
Third lesson: trying to boot GS/OS from SD card showed the graphic boot screen and the loading gauge filled, but nothing more, except from a beep from the speaker, happened. Hitting Ctrl-Reset to get to the basic prompt revealed that a BRK instruction caused the beep and effectively halted the boot process. It turned out that the BRK instruction was caused by a jump to $FF58 where a RTS is supposed to be in the 8-bit monitor ROM. This jump is used twice in the card's firmware to establish the slot it is in. It seems that this part of ROM was not switched into memory when the card was accessed. Adding a SEI to disable interrupts fixed this issue as well and the card now boots to GS/OS just fine. I have to admit that this is even mentioned in the IIgs Firmware Reference.
What happened here? The card was probably interrupted and had the monitor ROM switched out from under its bottom when the system tried to do something else. The card has the 'no interrupt' bit set, but I guess this is only examined later in the boot process.
But why was the gauge still 'loading' when the boot process halted? The code that draws windows, buttons, dialog boxes, etc. is in ROM. That is what made the Macintosh and the IIgs special and different from PCs. It is always there. My guess is that the gauge is updated by the vertical blank interrupt and does therefore not know anything about the boot process itself. This would explain why the gauge says finished when there are still inits to load.
I have played with the card all evening and it seems to work just fine. Although I like my green IIe monitor, I can't wait to get my RGB CRT out of storage to enjoy the thousands of colours the IIgs has to offer!
I have confirmed that the card works and boots in the following combinations:
- Apple IIgs Rom 01, GS/OS 6.0.4
- Apple IIgs Rom 01, Prodos 2.4.1
- Apple IIgs Rom 01, Prodos 1.9
- Apple IIe enhanced, 128k, Prodos 2.4.1
- Apple IIe enhanced, 128k, Prodos 1.9
- Apple IIe enhanced, 64k, Prodos 1.9