The invalid 68030 instruction that accidentally allowed the Mac Classic II to successfully boot up

Tracking down why the Mac Classic II would not boot on MAME.

https://www.downtowndougbrown.com/2025/01/the-invalid-68030-instruction-that-accidentally-allowed-the-mac-classic-ii-to-successfully-boot-up/

This is the story of how Apple made a mistake in the ROM of the Macintosh Classic II that probably should have prevented it from booting, but instead, miraculously, its Motorola MC68030 CPU accidentally prevented a crash and saved the day by executing an undefined instruction.
[…]
I didn’t get very far while testing the command+power shortcut in MAME’s emulated Classic II, because I observed something very odd. It booted up totally fine in 24-bit addressing mode, but I could not get it to boot at all if I enabled 32-bit addressing, which I needed in order for MacsBug to load. It would just pop up a Sad Mac, complete with the Chimes of Death. On this machine, the death chime is a few notes from the Twilight Zone theme song.
[…]
So why was the Classic II failing to boot in 32-bit mode in MAME? What was broken? Arbee also reproduced the issue, so at least I knew I wasn’t losing my mind. I assumed it was a random bug in MAME, so I started looking deeper into it to try to understand what needed to be fixed.
[…]
I’ve discovered an undocumented MC68030 instruction that performs a read-modify-write bus cycle and also changes the value of the A1 register.

This newly-discovered instruction turns out to be the glue that’s accidentally holding the Classic II together. Without this instruction modifying A1, the Classic II can’t boot. I’m confident that it was a mistake and not something intentional. A totally understandable mistake, at that. If the pesky 68030 hadn’t been hiding the bug from Apple’s ROM developers, there is no doubt they would have caught it before the Classic II shipped.

1 Like

Nice article! At the end we read

Oh, and as for the original reason I somehow managed to pull myself into this investigation in the first place: the command+power key combination does not work in MAME. Now that I have a real Classic II, I have been able to confirm that the keystroke does indeed work on hardware. It only works with MacsBug installed, which is likely due to what I said earlier about the Egret disabling it by default. Either way, it really should work in MAME when MacsBug is installed. I suppose that’s another MAME fix for me to work on!

I haven’t heard of MacsBug before, so I went looking - it has a Wikipedia page, and the name doesn’t mean what I expected:

MacsBug is a low-level (assembly language/machine-level) debugger for the classic Mac OS operating system. MacsBug is an acronym for Motorola Advanced Computer Systems Debugger, as opposed to Macintosh debugger (The Motorola 68000 Microprocessor is imprinted with the MACSS acronym). The original version was developed by Motorola as a general debugger for its 68000 systems — it was ported to the Mac as a programmer’s tool early in the project’s development.

2 Likes

I love the rabbit hole of “keystore isn’t working” … “spelunk up and down in machine language and disassemblers and CPU registers” … “buy and revive old original hardware to verify the issue” … “yup, a CPU from 40 years ago had an undocumented broken instruction that magically worked the right way”.

2 Likes

That’s an amazing story.

Of course, the bug would have been found and fixed in 5 minutes if the 68030 had an illegal instruction trap. But that takes a lot of logic, and in those transistor-limited days the proposal to implement such a thing would have been met by “OK, what feature are we giving up to make space on the die for that?”

I wonder when in the development of microprocessors the various vendors starting having illegal opcode traps?

Between the 6502 with its undefined (or illegal, or undocumented) instructions and the 65C02 with NOPs in all the remaining spaces, that changed.

There 68030 did have illegal instruction exceptions. I am guessing it depends on how complete the illegality detection is.

“8.1.5 Illegal Instruction and Unimplemented Instruction Exceptions
An illegal instruction is an instruction that contains any bit pattern in its first
word that does not correspond to the bit pattern of the first word of a valid
MC68030 instruction or is a MOVEC instruction with an undefined register
specification field in the first extension word.”

https://www.nxp.com/docs/en/reference-manual/MC68030UM.pdf

(caveat: I am out of my depth here, not a CPU-level guy by any measure)

“The 68030 …” I cannot typo.

“Reserved for future use”, please! :slight_smile:

Officially, there’s still a single NOP. The unofficial NOPs, AKA “future reserved” ones, come in various byte lengths and cycle counts, somewhat analogous to the “illegal opcodes” of the 6502.

The additional NOPs of the 65C02, as per count:

  • 30 1-byte 1-cylce,
  • 7 2-bytes 2-cycles,
  • 1 2-bytes, 3-cycles,
  • 3 2-bytes 4-cycles,
  • 2 3-bytes 4-cycles and
  • 1 3-bytes 8-cycles

So there’s still something going on regarding decoding and T-phases, but any effects are inhibited. (Somewhat interesting in this context are the 30 single-byte single-cycle ones, since these behave like actual NOPs, which doesn’t come from nowhere. Meaning, there has to be dedicated circuitry for this.)

*) This is the NOP count as with the Rockwell extensions included. I have no idea what the respective byte/cycle counts were for these, before BBR, BBS, RMB and SMB were added. (These are 32 instruction codes in total, as they come as a dedicated instruction for any of the 8 bits of a byte, each.)

1 Like