• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

ROM hacking in the 68040 Macs

Well, the ROM I am using to test with is the LC475/Q605. Offset 1278 is the named resource that the INITNETBOOT routine attempts to open automatically. So I believe this takes care of executing the Open routine.

My issue is with within the Open routine, getting the drive added to the queue. I am sure this is user error on my part 😜, just need to learn a bit more about how the class Mac handles the drive queue. All the information shared here is just what I needed.
Make sure you're posting a disk inserted event to tell mac os about the new drive - code for that is located in the bootrec of my example. That particular structure makes sense given how a bootable pds card works, but in your case you probably want to send that in your open routine after you add to the drive queue.

Older romdisk drivers sidestepped this by directly trying to mount the volume, but that's not correct behavior and will definitely crash the system if a valid HFS is not present.
 
It's a INIT ROM resource. There are INIT ROM resources in the ROM. Does something load those other INITs but not new INITs?

The only INIT in the Quadra ROM is INIT 18, which is responsible for loading bits of AppleTalk. It's only implemented as an INIT, per the comments in SuperMario, so it can be overloaded by the running System file, and (although this is not in the comments) I think because it needs to be loaded after disk-based atlk/adrvs. This isn't where a storage driver should be loaded. I'm genuinely unsure why this is in ROM at all, since it's small and has to load after disk-based components.

Same question for DRVR ROM resources. Does something load all of them (run's their Open routine) or are they loaded specifically?

This is why people like replacing the netboot driver, because the server software to drive it has not survived so it's not any use, and it's loaded relatively early in boot, so it's suitable for storage drivers that might want to be bootable. A nicer, perhaps slightly more generic option would be to build a kind of switchboard driver that would chainload some number of other drivers based on ... something. Handwave some kind of resource discovery here.
 
The only INIT in the Quadra ROM is INIT 18, which is responsible for loading bits of AppleTalk. It's only implemented as an INIT, per the comments in SuperMario, so it can be overloaded by the running System file, and (although this is not in the comments) I think because it needs to be loaded after disk-based atlk/adrvs. This isn't where a storage driver should be loaded. I'm genuinely unsure why this is in ROM at all, since it's small and has to load after disk-based components.



This is why people like replacing the netboot driver, because the server software to drive it has not survived so it's not any use, and it's loaded relatively early in boot, so it's suitable for storage drivers that might want to be bootable. A nicer, perhaps slightly more generic option would be to build a kind of switchboard driver that would chainload some number of other drivers based on ... something. Handwave some kind of resource discovery here.
Isn't the AppleTalk code in question required to enable netboot? And then once you're booted, there's no need for the (likely out of date) INIT code, so the System file overwriting it with a more recent version is a feature.
 
Isn't the AppleTalk code in question required to enable netboot? And then once you're booted, there's no need for the (likely out of date) INIT code, so the System file overwriting it with a more recent version is a feature.

It'd run too late for that; INITs only run after the System file has been found and the boot code in it has begun executing. Netboot, I gather, makes its own arrangements.
 
So just out of curiosity, I threw my driver into the IIsi ROM and burned that to a SIMM. Works just fine in a IIsi but not the LC475. Maybe the code I am using is better suited for the 68030 than the 68040. Back to the drawing board.
 
So just out of curiosity, I threw my driver into the IIsi ROM and burned that to a SIMM. Works just fine in a IIsi but not the LC475. Maybe the code I am using is better suited for the 68030 than the 68040. Back to the drawing board.

I've tested my NuCF driver to work (in binary form, unmodified) from SE30, IIsi, LC2, through LC475, and the template driver is a distilled version of that code. I'd sooner expect an issue with how you are loading the driver or some other assumption that is being made.

For troubleshooting, you can hijack the SCC and push bytes to it to get some serial logging going. Might help here. I will try to remember to post an example later.
 
Some stupid questions:
*You have changed the MMU tables to map up 8MB?
*Romdisk located at 40900000? (40880000 at 512kb ROMs)
*Romdisk size <7MB (maximum 6.99MB, this is different from IIsi where you can use the whole 8MB, on 1MB ROMs there must be a few bytes to spare)
*Driver numbering correct (they are different for IIsi and 1MB ROMs)?
So just out of curiosity, I threw my driver into the IIsi ROM and burned that to a SIMM. Works just fine in a IIsi but not the LC475. Maybe the code I am using is better suited for the 68030 than the 68040. Back to the drawing board.
 
OK did a bit more poking at my driver today. Turns out 030 vs 040 was not the problem. My disk driver works great with System 7.0 and 7.1. But not with 7.5+. I really think this boils down to how I am adding the drive to the queue.

I am using the Retro68 toolchain to compile my driver. I want to try switching to Braun's asm RomDrvAddDrive() method below. But I am not sure how to get the m68k-apple-macos-gcc compiler to accept this in-line assembly. Any pointers on this?

Once I figure this out, I'll clean up my code and share it out. There are some specific extensions that I also want to test out to make sure they work as well.


// AddDrive is declared in Files.h, but it's defined in MacOS.lib, which we don't want,
// so just shortcut the whole thing here.

asm RomDrvAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) {
fralloc +
CLR.L D0
MOVE.W drvNum, D0
SWAP D0
MOVE.W drvrRefNum, D0
MOVEA.L dq, A0
0xA04E
frfree
RTS
}
 
OK did a bit more poking at my driver today. Turns out 030 vs 040 was not the problem. My disk driver works great with System 7.0 and 7.1. But not with 7.5+. I really think this boils down to how I am adding the drive to the queue.

I am using the Retro68 toolchain to compile my driver. I want to try switching to Braun's asm RomDrvAddDrive() method below. But I am not sure how to get the m68k-apple-macos-gcc compiler to accept this in-line assembly. Any pointers on this?

Once I figure this out, I'll clean up my code and share it out. There are some specific extensions that I also want to test out to make sure they work as well.


// AddDrive is declared in Files.h, but it's defined in MacOS.lib, which we don't want,
// so just shortcut the whole thing here.

asm RomDrvAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) {
fralloc +
CLR.L D0
MOVE.W drvNum, D0
SWAP D0
MOVE.W drvrRefNum, D0
MOVEA.L dq, A0
0xA04E
frfree
RTS
}
This helping? https://bus-error.nokturnal.pl/article2-Incorporating-m68k-assembly-code-GNU-GAS-in-GCC-C-C-programs
 
This is why people like replacing the netboot driver, because the server software to drive it has not survived so it's not any use
Has anyone actually tried to figure out how NETBOOT works so a modern netboot solution could be made?

It would probably be of no use whatsoever, but interesting nevertheless because, unless I'm mistaken, none of the 68k Macs (nor many early PowerMacs) officially supported netbooting (official support I think came much later, during the G3 era or thereabouts).

c
 
OK did a bit more poking at my driver today. Turns out 030 vs 040 was not the problem. My disk driver works great with System 7.0 and 7.1. But not with 7.5+. I really think this boils down to how I am adding the drive to the queue.

I am using the Retro68 toolchain to compile my driver. I want to try switching to Braun's asm RomDrvAddDrive() method below. But I am not sure how to get the m68k-apple-macos-gcc compiler to accept this in-line assembly. Any pointers on this?

Once I figure this out, I'll clean up my code and share it out. There are some specific extensions that I also want to test out to make sure they work as well.


// AddDrive is declared in Files.h, but it's defined in MacOS.lib, which we don't want,
// so just shortcut the whole thing here.

asm RomDrvAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) {
fralloc +
CLR.L D0
MOVE.W drvNum, D0
SWAP D0
MOVE.W drvrRefNum, D0
MOVEA.L dq, A0
0xA04E
frfree
RTS
}
While I am cheating a little by declaring registers, this is how I did it which is not retro68-specific https://github.com/ZigZagJoe/Mac-St...4d5e26227990053466b/drvr/Drvr_OpenClose.c#L83

Your example routine is making assumptions on registers for parameters, so it would be more aligned with @Melkhior's routine by using retro68's register definitions: https://github.com/MelkhiorVintageC...0/DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c#L11

And a more generic example of inline assembly.

Code:
static inline void cf_readsector (volatile Ptr card, volatile Ptr destination) {
    asm volatile (
        "moveq.l #15, %%d0       " "\n"
        "1:                     " "\n"
        ".rept  16              " "\n"
        "move.w (%0),(%1)+      " "\n"
        ".endr                  " "\n"
        "dbra   %%d0, 1b        " "\n"
    :
    :"a" (card), "a" (destination)
    :"d0", "memory"
    );
}

See also https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
And https://bus-error.nokturnal.pl/article2-Incorporating-m68k-assembly-code-GNU-GAS-in-GCC-C-C-programs
 
It would probably be of no use whatsoever, but interesting nevertheless because, unless I'm mistaken, none of the 68k Macs (nor many early PowerMacs) officially supported netbooting (official support I think came much later, during the G3 era or thereabouts).
The developer note for the original LC mentions that netbooting has some support in the ROM and may be supported later. If I'm remembering correctly the Apple IIe Card supports netbooting the IIe, which was likely their major use case. (The Apple II Workstation Card and the Apple IIgs both supported netbooting).
 
Your example routine is making assumptions on registers for parameters, so it would be more aligned with @Melkhior's routine by using retro68's register definitions: https://github.com/MelkhiorVintageC...0/DeclROM/NuBusFPGARAMDskDrvr_OpenClose.c#L11
So incredibly helpful! I did try to use the AddDrive() without any luck, and the comment below is probably why. AddDrive() is missing in the Retro68 library.

/* FYI, missing in library with Retro68 */
/* void AddDrive(short drvrRefNum, short drvNum, DrvQElPtr qEl); */

Thanks all!
 
OK did a bit more poking at my driver today. Turns out 030 vs 040 was not the problem. My disk driver works great with System 7.0 and 7.1. But not with 7.5+. I really think this boils down to how I am adding the drive to the queue.

I am using the Retro68 toolchain to compile my driver. I want to try switching to Braun's asm RomDrvAddDrive() method below. But I am not sure how to get the m68k-apple-macos-gcc compiler to accept this in-line assembly. Any pointers on this?

Once I figure this out, I'll clean up my code and share it out. There are some specific extensions that I also want to test out to make sure they work as well.


// AddDrive is declared in Files.h, but it's defined in MacOS.lib, which we don't want,
// so just shortcut the whole thing here.

asm RomDrvAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) {
fralloc +
CLR.L D0
MOVE.W drvNum, D0
SWAP D0
MOVE.W drvrRefNum, D0
MOVEA.L dq, A0
0xA04E
frfree
RTS
}
I was more impressed that you managed to squeeze in 7.5 on a rom :), I’ve always used 7.1 with enabler since it takes up a lot less space.
 
I was more impressed that you managed to squeeze in 7.5 on a rom :), I’ve always used 7.1 with enabler since it takes up a lot less space.
I think I am having way too much fun these days with 68Ks. A much younger version of myself is very envious of what we can do today with these machines!
 
OK I am calling it a night.... But made REAL progress today. Importantly, I have a question for all the smart people here. Have any of you tried overwriting the NETBOOT driver specifically on the 1024KB / 68040s?

After using @zigzagjoe's nifty code to add the drive to the queue, I still could not get Sys 7.5+ to boot (ie, not boot-to-ROM) even with the accrun turned off.

So I decided to pivot, and left NETBOOT as is (from the STOCK ROM). Instead I re-compiled my driver to use the FREE resource starting at 60080. Using the exact same driver that I used previously for NETBOOT (with of course the changes to the dispatching routine offsets...), the FREE resource works flawlessly. See all the screenshots below. Absolutely no issues using R for boot-to-ROM, RA for boot-to-RAM, 24-bit vs 32-bit memory addressing, or any System 7.5+ or higher.

Based on this, I am just wondering if NETBOOT is indeed behaving differently than expected. Tomorrow I will do this same exercise with ATBOOT, to see if that works OK. But I do think it probably will be OK, because the BBRAUN/CAYMAC driver uses ATBOOT. So maybe there is something going on here behind the scenes with NETBOOT??

Also want to do just a bit more testing with some different INITs that @JDW pointed out, and also clean up my code a little. Then I will share the code and the modified LC475 ROM to see what y'all think.

71.jpg81.jpg755.jpg761.jpg
 
Could be something interesting like system 7.5 trying to patch the Netboot driver in that particular iteration of the ROM.
 
Yes this could very well be the case. Just out of curiosity, I did a little digging using Resorcerer:
  • OS 8.1- SYSTEM file contains a reference to NETBOOT in the BOOT3 resource.
    • I could not get OS 8.1 to boot with the ROM disk inserted as NETBOOT. It wasn't until I just moved to the FREE resource at offset 60080. Importantly, I did not use the name NETBOOT. I used the name to ROMDISK, as the screenshots above indicate.
  • SYS 7.1- SYSTEM file does NOT contain a reference to NETBOOT in the BOOT3 resource.
  • SYS ENABLER 040- Does contain a reference to NETBOOT in the BOOT3 resource.
  • SYS ENABLER 065 v1.2- Does NOT contain a reference to NETBOOT in the BOOT3 resource.
    • This Enabler is for the LC475/Q605 running Sys 7.1. It appears that neither Sys 7.1 nor this Enabler are doing any patching to NETBOOT during the boot sequence. Perhaps this is why I could not only overwrite NETBOOT, but keep that same name intact freely.
  • Still want to look at 7.5.X -> 7.6.1 to see if those SYSTEM files reference NETBOOT in the BOOT3 resource.
As a comparison, I noticed that Garrett's Workshop uses the NETBOOT resource for their 512KB ROM. But they have renamed the resource and driver to GWRDisk. This could be why I do not have any issues with their ROM SIMM on my IIsi going from 7.5.X -> 7.6.1.

So maybe the lesson here is it is OK to overwrite NETBOOT, but also make sure to change the name of the resource and the driver? :)
 
Last edited:
Just as a point of reference: I remember a Mac Plus lab in 1993 that had a bootstrap floppy that would do a partial boot and then kick in NETBOOT to System 7.1. The annoying thing was that you needed to boot the floppy in order to kick off the NETBOOT session -- so why not just have the OS on the floppy and load it to a RAM disk, like everyone else did? I guess it enabled the sysadmin to manage a single image but have multiple bootstrap floppies floating around that didn't need to be maintained....

The other annoying thing is I can't recall anything else about how that netboot floppy worked.
 
Back
Top