As far as I know the odd address exceptions happen even on loads/stores, not just execution. So the check (basically if (address & 1) for a 16-bit transaction, and if (address & 3) for a 32-bit transaction) would have to happen on every memory access. I wouldn't be surprised if the emulator omitted generating those exceptions since software doing that wouldn't run on a real 680x0, Amiga-like tricks aside.
The odd address exception for data fetches won't happen for the 68020 or later. "The 68020 has no alignment restrictions on data access"
en.wikipedia.org
I've just been reading a bit about exceptions on the M88K user manual (I'll come to PowerPC next) and found that the M88K does generate exceptions for odd address, >8-bit accesses and for odd bit-1, 32-bit accesses, but you can suppress the exception in the PSR. This means, I think, that the Davidian Emulator started out having to trap odd addresses, because it was initially emulating a Mac SE, so that didn't need to be part of the main loop; but when emulating an LC, would mask out the odd address data trap and have to emulate unaligned 16-bit data access (but not unaligned jumps).
So, there are IMHO two basic ways to do this, either you load a 16-bit value by either doing: dest=((*(uint8_t*)src)<<8)| (((uint8_t*)src)[1]); or if((uint32_t)src)&1) HandleUnaligned16Bit(); else dest=(uint16_t*)src; . And I think it would choose the latter, because a test and a skipped jump is cheaper than a double load byte, shift and or, but also because unaligned 16-bit access on a Mac will be very uncommon, because it's not supported on the original 68000 (and so even 68020 or 68030 software would normally align 16-bit data on 16-bit boundaries).
But 32-bit access on 680x0 emulation is different, because the 68000 could do it and it was normal not to try and align 32-bit data on 32-bit boundaries, but normal to align 32-bit data on 16-bit boundaries. So, then the emulator has a basic choice of:
dest=((*(uint16_t*)src)<<16)| (((uint16_t*)src)[1]);
Or:
if((uint32_t)src)&2) HandleUnaligned32Bit(); else dest=(uint32_t*)src;
Then it all depends upon whether a jump, 50% of the time or two loads / stores is more costly (the M88K has a Branch Target Cache).
The LC's memory map very much requires working 24-bit mode so I can see the M88K needing 24-bit support.
Correct, the 68K Davidian emulator on M88K needed to support that. I think though that it would handle it using the MMUs. For all I know, you know everything about the M88K in which case I'm just reflecting back my understanding. The 88200 has a Block Address Translation Cache, which caches 10x 512kB block addresses; and a 56 entry ATC which caches 4kB pages. The actual translation (one each for User/Supervisor) is a 1024 x 4MB segment table which indexes into 1024 4k Pages. So, 24-bit addressing support can be done by mapping SegmentTable[x] to the same page table as SegmentTable[x&3].
From
BitSavers.
The PPC machines are cleaner and may have been able to get away without that.
Correct, 24-bit mode isn't supported, though, as per your later comment:
My assumption is that since the ROM code and the System 7 boot code are both 32-bit clean that it could run that "24 bit stub" (it just checks and sets the PRAM flag for 32-bit mode) in 32-bit mode and nothing would care.
..it may have to modify the PRAM if it finds it's in 24-bit mode on boot.