While playing around with the rom disk driver, I discovered a nice way for 24-bit mode code to safely call code that makes 32-bit memory accesses. You can't just call SwapMMUMode() in the middle of 24-bit code that's executing from ROM, because the PC isn't at a valid 32-bit address, so it'll crash as soon as the addressing mode is changed. The rom disk driver gets around this by copying a small function to RAM, where 24- and 32-bit addresses are the same, and having it call SwapMMUMode() from there. I worked out an alternate way that keeps everything in ROM. Just wrap this around the code that needs to make 32-bit memory accesses:
// if we're not already in 32-bit addressing mode, then change modes
tst.b 0xCB2 // current mmu mode, 0 = 24-bit, 1 = 32-bit
bne.s _already32bit
pea 20(pc) // push address of _now32bitSafePC on the stack
move.l (sp)+, d2 // pop it into D2
andi.l #0x00FFFFFF, d2
ori.l #0x40000000, d2 // force high byte to be 0x40 = ROM
move.l d2, -(sp) // push modified address onto stack
rts // "return" to the modified address
_now32bitSafePC:
move.l d0, -(sp) // save d0
move.l #1, d0 // now the PC is a 32-bit safe address
_SwapMMUMode // OK to switch to 32-bit addressing mode without crashing
move.l (sp)+, d0 // restore d0
move.w #0, -(sp) // save old addressing mode (0) on the stack, for restoration at exit
bra _function
_already32bit:
move.w #1, -(sp) // save old addressing mode (1) on the stack, for restoration at exit
bra _function
_function:
// your code goes here
_exit:
move.w (sp)+, d0 // retrieve original addressing mode
bne.s _modeOK
_SwapMMUMode
_modeOK:
rts
Maybe this will be useful for other things somewhere...