ROM Hacking: Classic-style ROM Disks for every machine?

eharmon

Well-known member
I recently determined the Classic's built-in ROM Disk uses the same driver and format as the Portable's extensible ROM Disk, and added support for examining them in my ROM template: https://68kmla.org/bb/index.php?thr...clrom-and-system-rom-parser.46053/post-516329

You can find full documentation of the format here: https://wiki.preterhuman.net/HW_13_-_Macintosh_Portable_ROM_Expansion

Essentially, creating the proper header at any 64k boundary within ROM space enables the ROM disk to function. This was originally designed for the Portable to support expansion through ROM disks (like a really weird, non-removal cartridge system, I guess), but it appears the exact same functionality was used in the Classic, since we can see the same header structure and appended disk within it's ROM structure:

1704154564118.png

What's interesting is that we can see from later ROMs that the .EDisk driver that makes this work is still included in the resources and active for all devices. Which means, theoretically, it's loaded and usable if a disk is appended, without modifying any resources.

While in some ways less flexible than bbraun's custom ROM disk driver, this has some interesting elements:
- Theoretically it can work by just appending a disk with the correct format to an existing ROM image and flashing it. This makes it easier to modify ROMs for each machine to add a ROM disk.
- Theoretically it supports multiple disks, based on the documentation.
- It might be better supported on a wider variety of machines, if it was still being supported. Or it could be abandoned by the Universal period and work worse, who knows!
- It supports optional checksums to verify integrity.

So I gave it a try on my Quadra and hit the dumbest possible issue...I can't figure out how to activate it. Opt+Command+X+O does nothing, which isn't surprising because that might be specific to the Classic (XO) ROM branch. And removing all disks to see if it's just a fallback disk doesn't work either. But a skim of the Portable documentation doesn't reveal any way to activate the ROM disk! Maybe I'm just missing something obvious, but after putting the harder pieces together, the easier ones are elusive! Or the driver has an early exit on a Quadra...

Before I go decompiling, any ideas, or thoughts on the potential of this ROM Disk driver?

(Bonus points: the Pippin has ANOTHER ROM Disk driver as well that I haven't fully reverse engineered yet -- but it stores it's disk images in the resource list which seems significantly more limiting -- some of the Pippin folks have been using it, but only to substitute a 1:1-sized image).
 

zigzagjoe

Well-known member
Looking through the ROM source is probably the best bet - easier than disassembly. https://github.com/elliotnunn/sys7.1-doc-wip

Of particular interest is the edisk driver source. Interestingly it seems like it was kept updated and (potentially) functional even for PPC machines.

For booting, there seems to be a feature flag "SupportsROMDisk" (in OS\UniversalTables.a) which has only been set for "InfoMacLC". This flag gets checked in CheckForROMDisk in StartBoot.a, ROMDisk stuff seems to be entirely skipped if flag not set.

So, I think modify your ROM to add that flag would be the first step. Given these are static tables, it should be easy to figure out what they look like when compiled into the ROM and from there make the necessary tweaks.
 

eharmon

Well-known member
Looking through the ROM source is probably the best bet - easier than disassembly. https://github.com/elliotnunn/sys7.1-doc-wip

Of particular interest is the edisk driver source. Interestingly it seems like it was kept updated and (potentially) functional even for PPC machines.

For booting, there seems to be a feature flag "SupportsROMDisk" (in OS\UniversalTables.a) which has only been set for "InfoMacLC". This flag gets checked in CheckForROMDisk in StartBoot.a, ROMDisk stuff seems to be entirely skipped if flag not set.

So, I think modify your ROM to add that flag would be the first step. Given these are static tables, it should be easy to figure out what they look like when compiled into the ROM and from there make the necessary tweaks.
Ah good sleuthing, thanks! I'll give that a go.

Odd that it's set for the LC at all...
 

eharmon

Well-known member
Ah good sleuthing, thanks! I'll give that a go.

Odd that it's set for the LC at all...
That flag actually looks like it might be for a THIRD different ROM Disk format, "Ginty", with its own signature and slightly different format. Curious...
 

eharmon

Well-known member
Okay, Ginty makes things even more interesting. Summarizing the drivers:

- .EDisk -- A driver included in the System ROM resources, present on all Universal ROMs, and at least the Portable/Classic before that. Uses a fixed EDisk header appearing at any 64k-alignment in the ROM memory, which describes the disk image. Originally introduced for Portable and used on the Classic.
- .STBDiskDriver -- A driver included in the Interactive Television Box (STB) System ROM resources. Uses a "disk" resource containing the ROM disk image. (I misspoke earlier when I mentioned Pippin...I meant the STB.)
- "Ginty" -- Initialized by the CheckForROMDisk routine. Uses almost identical headers to EDisk, however this header describes its own .EDisk driver location(!).

Specifically, it's interesting that Ginty detection might be built into all ROMs, bringing back my hope this can be easily installed into any ROM. Essentially if I'm understanding the flow control correctly:

- StartManager initializes and calls CheckForROMDisk.
- CheckForROMDisk searches for Ginty headers.
- If Ginty headers are found, the DRVR resource is loaded from the header's indicated location.
- The ROM Disk is loaded.

It appears these ROM Disks are potentially selectable with Startup Disk which is SUPER handy, too. It ALSO appears this continued to be supported long into Power PC which opens up it's own possibilities!
 

dougg3

Well-known member
I never got a chance to test it out, but I thought I should mention that during some of my research a while ago, I saw that the Ginty driver seems to be present in the Color Classic ROM too. $40A4C1FA is labeled as "ROMDISKPATCH1" in the Color Classic ROM listing included with MPW. It seems to search twice for the ROM disk. It searches once, then toggles some bits in one of Apple's chips, and then searches again. $40A4C262 is FINDROMDISK which searches for the Ginty headers. Will definitely be watching this thread in interest!
 

SuperSVGA

Well-known member
This was originally designed for the Portable to support expansion through ROM disks (like a really weird, non-removal cartridge system, I guess),
There was actually a removable system as well. Two card slots above the floppy drive, likely similar to PCMCIA slots in size and shape, insertable and ejectable while the system is running. It never made it out and was likely abandoned judging by the "lazy" design decision on the M5126 that would cut the 4MB of space down to just 3MB.

So I gave it a try on my Quadra and hit the dumbest possible issue...I can't figure out how to activate it. Opt+Command+X+O does nothing, which isn't surprising because that might be specific to the Classic (XO) ROM branch. And removing all disks to see if it's just a fallback disk doesn't work either. But a skim of the Portable documentation doesn't reveal any way to activate the ROM disk! Maybe I'm just missing something obvious, but after putting the harder pieces together, the easier ones are elusive! Or the driver has an early exit on a Quadra...
I'm not sure if that driver actually works right on a Quadra, at least not the regular search part. It starts searching at the base of the ROM 4000 0000 then checks to see if it's reached the end 00E0 0000 (immediately reaching the end), which isn't very useful unless there's some sort of conversion from 24-bit to 32-bit going on.
 

Phipli

Well-known member
Would any of these ROM Image things search the memory range covered by the useless ROM socket range on the classic II FPU expansion cards?
 

eharmon

Well-known member
There was actually a removable system as well. Two card slots above the floppy drive, likely similar to PCMCIA slots in size and shape, insertable and ejectable while the system is running. It never made it out and was likely abandoned judging by the "lazy" design decision on the M5126 that would cut the 4MB of space down to just 3MB.


I'm not sure if that driver actually works right on a Quadra, at least not the regular search part. It starts searching at the base of the ROM 4000 0000 then checks to see if it's reached the end 00E0 0000 (immediately reaching the end), which isn't very useful unless there's some sort of conversion from 24-bit to 32-bit going on.
It looks like it searches from RomBase to the RomBase+RomSize, not RomSize, which should work...except that throws a wrench... So, three wrenches I see right now:

1) I was wrong, there's two routines to find the images, and at least the one used in later ROMs checks the SupportsROMDisk flag. So that branch would need to be patched out. Not too bad, but no "concatenate and you're done".
2) The search space is limited by the rom size set in the header. So that also needs to be patched, or the search needs to be patched to increase the search space.
3) I think the Ginty-style driver might do some special setup and as far as I know, no one has ever seen one.

Doable, but maybe no dreams of a concatenate-only solution using Ginty. Except maybe on the LC...I don't have one, but maybe someone can give it a try.
 
Last edited:

Phipli

Well-known member
Doable, but maybe no dreams of a concatenate-only solution using Ginty. Except maybe on the LC...I don't have one, but maybe someone can give it a try.
I have an LC in the other room, what needs doing? Or do you mean actual custom ROMs? I don't have the parts to hand.
 

SuperSVGA

Well-known member
It looks like it searches from RomBase to the RomBase+RomSize, not RomSize, which should work
Maybe we're not looking at the same code. From the Quadra 650/800 for example:
Code:
    movea.l (ROMBase),A2                ; Load ROM starting address
ROMDiskLoop:
    bsr.w   CheckForROMDisk             ; Look for a ROM disk
    bne.b   NextROMDisk
    moveq   #0,D1
    move.l  A2,D2
    move.l  A2,D3
    bsr.b   CreateEDrive
    lea     SecondaryROMDisk
NextROMDisk:
    adda.l  #65536,A2
    cmpa.l  #$E00000,A2
    bcs.b   ROMDiskLoop                 ; Continue if we haven't reached the end
 

eharmon

Well-known member
Maybe we're not looking at the same code. From the Quadra 650/800 for example:
Code:
    movea.l (ROMBase),A2                ; Load ROM starting address
ROMDiskLoop:
    bsr.w   CheckForROMDisk             ; Look for a ROM disk
    bne.b   NextROMDisk
    moveq   #0,D1
    move.l  A2,D2
    move.l  A2,D3
    bsr.b   CreateEDrive
    lea     SecondaryROMDisk
NextROMDisk:
    adda.l  #65536,A2
    cmpa.l  #$E00000,A2
    bcs.b   ROMDiskLoop                 ; Continue if we haven't reached the end
Oh interesting. What's your reference source? What I saw was:

Code:
            movea.l    RomBase,a2
            move.l    a2,d1
            addi.l    #ROMSize,d1

Where d1 is used as the maximum search range.

FWIW I think the code you're looking at might work, if that ROMBase is still oriented around $0 because the memory space hasn't been shifted yet?
 

SuperSVGA

Well-known member
Oh interesting. What's your reference source? What I saw was:

Code:
movea.l RomBase,a2
move.l a2,d1
addi.l #ROMSize,d1
That's for the Ginty ROM code, which isn't present in most Quadra ROMs it seems, it is in the 660av and 840av ROMs though.

FWIW I think the code you're looking at might work, if that ROMBase is still oriented around $0 because the memory space hasn't been shifted yet?
The only way I think it might work is if the system is in 24-bit addressing mode at that time, which if I understand correctly it would shift the ROM addresses around making 00E0 0000 the end of the expansion ROM space. It's not clear if the system is in 24-bit mode at this time, or whether that driver even works when switching to 32-bit mode.
 

eharmon

Well-known member
That's for the Ginty ROM code, which isn't present in most Quadra ROMs it seems, it is in the 660av and 840av ROMs though.


The only way I think it might work is if the system is in 24-bit addressing mode at that time, which if I understand correctly it would shift the ROM addresses around making 00E0 0000 the end of the expansion ROM space. It's not clear if the system is in 24-bit mode at this time, or whether that driver even works when switching to 32-bit mode.
What decompile/source are you using for the 650/800 ROM? I could totally believe it was added in the Super Mario series.

I'll see if I can pull up the docs, but if I understand correctly, very early in boot the ROM is mapped to $0 and some PALs are later told to remap the ROM up to $0408 0000, but I'm not sure when that occurs. That shift is regardless of addressing mode. You're probably right though that's well before this code.
 

SuperSVGA

Well-known member
What decompile/source are you using for the 650/800 ROM?
I typically just use Ghidra to decompile.

very early in boot the ROM is mapped to $0 and some PALs are later told to remap the ROM up to $0408 0000, but I'm not sure when that occurs.
Assuming it works like other systems, that's just for the reset vector, and then the first read to regular ROM address space disables that.
 

eharmon

Well-known member
I typically just use Ghidra to decompile.


Assuming it works like other systems, that's just for the reset vector, and then the first read to regular ROM address space disables that.
Ah a home decompile. If you ever post the annotations, let us all know! Would save a ton of time replicating the work.

Yeah okay, basically right after the first transfer to ROM control. Makes sense!
 

SuperSVGA

Well-known member
If you ever post the annotations, let us all know!
I would if not for the issue of redistributing copyrighted code. While I think you can export the annotations and apply them to the binary later, I don't think it quite gets everything like equates, and preferably everything would be rewritten into assembly files that are easier to read and potentially can be reassembled into a working ROM.
 
Top