[HN Gopher] An invalid 68030 instruction accidentally allowed th...
       ___________________________________________________________________
        
       An invalid 68030 instruction accidentally allowed the Mac Classic
       II to boot
        
       Author : todsacerdoti
       Score  : 282 points
       Date   : 2025-01-25 20:29 UTC (1 days ago)
        
 (HTM) web link (www.downtowndougbrown.com)
 (TXT) w3m dump (www.downtowndougbrown.com)
        
       | ChuckMcM wrote:
       | That is quite the journey. I find I don't have the patience these
       | days to go quite so far down the rabbit hole as the author does,
       | but I resonate with that feeling of accomplishment in _knowing_
       | something versus just thinking you know something.
        
         | dougg3 wrote:
         | Author here. Yeah, I have a tendency to go into pretty big deep
         | dives when I find stuff like this. It's so rewarding at the
         | end, even if it does take a lot of time!
        
           | mrandish wrote:
           | Finding a previously unknown undocumented instruction at this
           | late date in a line of processors as prevalent and
           | historically significant as the 68k is surprising. Congrats
           | on your achievement! If someone does dive into fully
           | characterizing the undocumented instruction so it can be
           | properly supported in emulators (as you suggested), please
           | post about it on HN. I suspect, like many undocumented CPU
           | instructions, it was probably to help the original designers
           | test or verify something during development but it would be
           | interesting to know.
           | 
           | While obviously a subjective judgement, a lot of people who
           | hand coded assembler on 68k processors regard the ISA as
           | especially elegant, powerful and fun to develop for. In many
           | ways I think of it as peak CISC, thanks to its orthogonal
           | instruction set and wildly flexible addressing modes. And of
           | course the platforms which used it are legendary, from
           | consumer (Mac/Lisa, Amiga, Atari ST, Sinclair QL) to
           | workstations (SUN, Apollo, Quantel) to gaming (Sega Genesis,
           | Neo Geo, Capcom, Atari, Namco, Sega, Taito, Konami) to
           | embedded (automation, print/network controllers,
           | synthesizers, appliances). I'm certainly biased but to this
           | day the 68k (and its 8-bit little brother the 6809) are the
           | only CPUs I still enjoy writing assembler on.
        
             | dougg3 wrote:
             | Thank you! Yes, I will definitely make another post if and
             | when someone figures out what the instruction does.
        
             | userbinator wrote:
             | _I suspect, like many undocumented CPU instructions, it was
             | probably to help the original designers test or verify
             | something during development but it would be interesting to
             | know._
             | 
             | Or simply be an emergent but unintended behaviour of the
             | implementation, as is the case for most of the undocumented
             | 6502, Z80, and x86 instructions I know of.
        
             | bell-cot wrote:
             | > a lot of people who hand coded assembler on 68k
             | processors regard the ISA as especially elegant, powerful
             | and fun to develop for. In many ways I think of it as peak
             | CISC, thanks to its orthogonal instruction set and wildly
             | flexible addressing modes.
             | 
             | I definitely agree...but I'd say Motorola really got
             | carried away with those wildly flexible addressing modes.
             | Which lead them into implementation, power draw, and gate-
             | delay hells by the late 1980's and the 68040. The future
             | was ever-rising transistor counts and clock speeds - and
             | their 68k architecture just couldn't go there.
        
               | mrandish wrote:
               | > I'd say Motorola really got carried away with those
               | wildly flexible addressing modes.
               | 
               | Yeah, while they could certainly be extremely powerful,
               | I'll admit the edges of my 68000 programmer's reference
               | card quickly got dog-eared from how often I'd need to
               | remind myself exactly how some program-counter relative
               | indexed redirection+offset instruction worked. Almost
               | made me miss the days of simple 8-bit loads, stores,
               | compares and branches being all we had.
               | 
               | > The future was ever-rising transistor counts and clock
               | speeds - and their 68k architecture just couldn't go
               | there
               | 
               | I've always wanted to understand more about why Motorola
               | abandoned the 68k architecture. I understand the broad
               | factors cited in the Wikipedia article and on
               | RetroStackExchange but I don't recall anyone citing
               | supporting the addressing modes specifically (though it
               | makes sense). I never programmed x86 assembler but my
               | sense was that ISA also had its own oddball complexities.
               | I never understood if there was some fundamental
               | conceptual difference between the 68k and x86 ISAs that
               | prevented one from being able to scale into the future
               | while the other could. Would love any more info or links
               | if you have them handy.
        
       | basementcat wrote:
       | Do the '040/060 also support this "undocumented instruction"?
        
         | dougg3 wrote:
         | On the 040, it seems to do something that actually involves D1.
         | Definitely doesn't touch A1 at all. I didn't test further, but
         | it's possible it just handles the instruction as a normal CAS.
         | 
         | It did cause a system error the first time I stepped through
         | the instruction with MacsBug on my LC 475, but then it was fine
         | after that.
        
         | mras0 wrote:
         | Have an Amiga w/ 060, and that instruction doesn't seem to
         | modify any A registers. (Only did a very quick test of those
         | exact instruction words)
        
           | basementcat wrote:
           | I appreciate that I can ask an esoteric question about the
           | behavior of a 30 year old microprocessor and multiple people
           | respond with test results on actual hardware within a few
           | hours. Can y'all also post the mask revision (if known) and
           | whether it is an EC or LC device? (In case it impacts
           | behavior)
        
             | mras0 wrote:
             | Rev5 "full" 060 (not EC/LC). Quick capture of crappy
             | methodology: https://imgur.com/a/XwQ1Tnp (PCR with revision
             | number is in d0)
        
               | ahefner wrote:
               | Today by, way of your screenshot, I discover Asm-Pro.
               | Just got into Amiga recently (by way of receiving one
               | from my uncle's closet..) and have been meaning to
               | backfill my shameful lack of 68k asm knowledge. Thanks!
        
             | dougg3 wrote:
             | My test of an 040 (no A1 change, D1 changed) was on a chip
             | with the following markings:
             | 
             | XC68LC040RC25B
             | 
             | 02E23G QEDP9348D MALAYSIA
        
       | cluckindan wrote:
       | Time to fuzz the rest of the processor.
        
       | AnimalMuppet wrote:
       | WOW.
       | 
       |  _Amazing_ work. Thanks for the exposition.
       | 
       | (I miss the 68000 line. Those were such great chips...)
        
         | aruggirello wrote:
         | I miss the assembly. It was so clear and logical, like great
         | engineering should always be. You could browse through it and
         | comprehend at a glance what was happening. By contrast x86
         | assembly looks like pure rubbish, with stuff that most of the
         | time looks like clever hacks coming from a bad night's sleep,
         | like subtracting a register from itself to get zero... c'mon!
        
           | jjuran wrote:
           | I hate to disappoint you, but the canonical way to clear a
           | 68K address register is `SUBA.L An,An`. My asm-coded
           | replacement for the Metrowerks code resource runtime uses it:
           | 
           | <https://github.com/jjuran/metamage_1/blob/master/mac/toolcha
           | ...>
        
       | TapamN wrote:
       | Does Ken Shirriff have time to look at a 68030?
        
         | kens wrote:
         | Unfortunately, not any time soon.
        
           | phibz wrote:
           | That's great. Merely speak his name and he appears.
           | 
           | Love the work you do Ken. Thank you.
        
       | Waterluvian wrote:
       | We're confident this wasn't some ROM DRM type feature?
        
         | the-rc wrote:
         | I was thinking maybe it's a way to save some bytes, like people
         | used to do with undocumented opcodes in 6502 programs.
        
         | userbinator wrote:
         | An "unintentional emulator trap" is how I would characterise
         | it.
        
         | rep_lodsb wrote:
         | Wouln't have prevented hardware clones, since they would have
         | used the same chip. It's fairly certain nobody at Apple knew
         | about this instruction.
        
       | khazhoux wrote:
       | 30+ years later, I'm still always amazed at how effective the Mac
       | debugger UI could be with such a tiny screen resolution. It's
       | really quite masterful.
        
       | 1over137 wrote:
       | This seems like it will be impossible in the future with today's
       | Macs. Apple's technical documentation is rubbish these days.
        
         | kevingadd wrote:
         | I think in modern environments the odds of this sort of bug
         | slipping into released firmware/software are much lower.
         | Address spaces are much bigger and the vast majority of
         | addresses aren't mapped so doing a memory operation on a
         | garbage address is going to fail most of the time, and invalid
         | instructions will probably fail too.
         | 
         | Reading from a jump table with an index that's too big is a
         | realistic sort of bug to have, so I could see that part making
         | it into modern shipped software. But I would expect the process
         | to fall over when it happens, not keep on trucking like it did
         | here.
         | 
         | FWIW, WebAssembly is an environment where bugs of this sort are
         | more possible, since it has a single linear address space where
         | every address is both readable and writable. So if your garbage
         | address is within range you can do an erroneous read, write or
         | CAS and get away with it. But then invalid instructions like in
         | the post will cause the WASM module to fail to load, so it's
         | still not 1:1 comparable with this issue in the mac's ROM.
        
           | 1over137 wrote:
           | Sorry, the "this" I was referring to was the ability to
           | consult docs, reverse engineer to this extent, etc.
        
             | saagarjha wrote:
             | I think you're underestimating people who do this.
        
         | grishka wrote:
         | IMO the reason Apple doesn't provide this level of hardware
         | documentation is because modern Macs don't have comparable
         | expansion capabilities. The kind that expose system buses on
         | connectors that users are supposed to plug cards into, and
         | third-party developers to interact directly with hardware to
         | make those cards work. On a modern Mac, you've got USB and
         | Thunderbolt that you can interact with from a userspace
         | program.
         | 
         | Though I'm not denying that some of the newer macOS APIs are
         | very poorly documented. As in, you know you've stumbled upon
         | _the cool shit_ when you end up on one of those old pages with
         | a blue gradient in the header that says  "Apple documentation
         | archive".
        
       | hajile wrote:
       | Was this copy protection to keep it from running on systems or
       | does this happen on all 68030?
        
         | kevingadd wrote:
         | The contents of the post make me pretty confident that this
         | wasn't copy protection, the jump table involved here is just
         | missing an entry for the machine because (most likely) everyone
         | involved in working on the ROM forgot to add a new entry to the
         | jump table and it happened to work without a table entry by
         | pure chance.
        
       | kstenerud wrote:
       | CAS has always been a bitch. I think I've received more bug
       | reports about that instruction's emulation than any other
       | instruction.
       | 
       | Incidentally, I remember another old "bug" in King of Fighters
       | that "incorrectly" checked the carry flag of the SBCD
       | instruction, which it used to decrement the round timer and end
       | the current round. Completely undocumented of course, but if you
       | don't emulate the arithmetic status flags when doing binary coded
       | decimal operations, the round timer in KOF will just keep on
       | going forever, cycling from 00 to 99 :P
       | 
       | SNK were really the gods of the 68000 chip.
        
         | mrandish wrote:
         | > SNK were really the gods of the 68000 chip.
         | 
         | As a fan of retro arcade machines and the 68k, I'd love to hear
         | more about why SNK were godly in how they maximized the 68K.
        
           | azinman2 wrote:
           | Yes - were they doing something that Apple, Amiga and the
           | Unix vendors weren't?
        
       | userbinator wrote:
       | Nearly all CPUs have undocumented instructions, and the 68k is no
       | exception; it's just that the vast majority of people with enough
       | interest and low-level knowledge at the time were focused on the
       | x86/PC instead, which was arguably a far more open and stable
       | architecture than Apple's. The 8088 and 8086 microcode was
       | disassembled and studied extensively a few years ago, and I
       | believe there's been some attempts at simulating it at the
       | transistor level already. Even before that, the structure of the
       | x86 opcode space was also explored in detail by many, with
       | documents like these resulting from such effort:
       | 
       | http://ref.x86asm.net/geek.html
       | 
       | https://gist.github.com/seanjensengrey/f971c20d05d4d0efc0781...
       | 
       |  _We don't really know the exact details of what this instruction
       | does. With some limited testing, I believe I've observed that the
       | resulting value of A1 depends on the original A1 value, the value
       | of A7, and the program counter. But I'm not sure. Maybe someone
       | can make a program that tries out a bunch of different register
       | values and memory contents, and attempt to deduce what exactly
       | the instruction does so that it can be emulated accurately. Until
       | someone decides that it's worth trying to figure out, MAME is
       | patching this bug out of the ROM in order to allow the Classic II
       | to boot._
       | 
       | IMHO this is definitely worth figuring out for accurate
       | emulation. I'm not familiar with 68k but the bits in the
       | instruction offer a good clue - my theory is that bits 5:3 of the
       | 2nd word seem like another mode field, and instead of selecting
       | one of the Dn registers via mode 000, 101 is selecting (d16, An)
       | again and the Dc field, containing 001, is being interpreted as
       | A1.
        
         | pjmlp wrote:
         | At the time Mac Classic was relevant, PC still wasn't thar
         | great in home computing, no one was bothering with this stuff
         | in x86/PC.
         | 
         | We were still bothering with demoscene stuff in 8 bit home
         | computers, and those of us busy with 16 bit home systems were
         | focused on Atari and Amiga systems.
         | 
         | PC and x86 at home only took off, meany really taking off among
         | demoscene and other home users, was when VGA and sound cards
         | became part of a standard PC.
        
           | userbinator wrote:
           | The Mac Classic was released in 1990, the Mac Classic II that
           | is the subject of this article was released in 1991. At that
           | time PCs with 286s and 386s were already common, and the 486
           | was just starting to gain marketshare at the high end. Most
           | of the undocumented 8086 instructions had already been known
           | for almost a decade; and the majority of those who knew were
           | not demosceners. Many developers used Asm exclusively, and
           | the "classic hacker mindset" was very much alive among them.
        
             | pjmlp wrote:
             | Depends on where in the globe one were and in my demoscene
             | circles PCs only took off as interesting after Windows 95,
             | folks using MS-DOS or Windows 3.x were mostly due to their
             | parents family computer.
        
           | zargon wrote:
           | This is 1992 we're talking about. You might be confusing the
           | Mac Classic II with mid-80s Macs due to the form factor.
        
             | pjmlp wrote:
             | Where Amiga and Atari were still calling the shots among
             | European demoscene.
        
           | TazeTSchnitzel wrote:
           | I think non-x86/non-PC-compatible home computers did remain
           | relevant for a bit longer in Europe and Japan than in the US
           | but by 1992 the writing must have been on the wall.
        
         | fulafel wrote:
         | nitpick: 68k of course wasn't Apple's architecture. The '030
         | was the nicest GP CPU around in its day, used in the Amiga
         | 3000, Atari Falcon, Sun 3, NeXT Cube etc.
        
       | adrianmonk wrote:
       | > _I've discovered an undocumented MC68030 instruction that
       | performs a read-modify-write bus cycle and also changes the value
       | of the A1 register._
       | 
       | Rather than a "real" instruction that CPU designers consciously
       | created and which was meant to do something useful but wasn't
       | documented, it could just be that this is an illegal instruction
       | and the logic in the CPU is doing whatever it happens to do when
       | given don't-care inputs. (Maybe this is what the author meant,
       | and I'm just catching up.)
       | 
       | Normally the CPU would detect illegal instructions and cause an
       | exception. This would mean there are certain situations where it
       | doesn't.
       | 
       | I found a manual at https://www.nxp.com/docs/en/reference-
       | manual/MC68030UM.pdf. On page 8-9 of the manual (which is page
       | 276 in the PDF file), it says:
       | 
       | > _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._
       | 
       | Note "in its first word". According to the write-up, the
       | instruction is 3 words long. The first word is normal, and the
       | weird bits occur in the second word. So quite possibly the 68030
       | doesn't validate this second word, just plows forward with the
       | logic that implements the CAS instruction, and lets whatever
       | happens happen.
       | 
       | (Great write-up and amazing dedication, by the way!)
        
         | rep_lodsb wrote:
         | It looks to me (not being an 68k expert) that only the first
         | word is considered the "opcode": the second word just selects
         | what "D" registers are used for the CAS operation. Normally one
         | would expect the zero bits to be completely ignored in that
         | case, since they don't have any role in the instruction.
         | 
         | But maybe on the 68030 in this case, the bits must be zero even
         | if they have no documented use, because there is hardwired
         | logic for another instruction that is activated by those bits
         | being set, somewhat like the 6502 illegal opcodes?
        
           | userbinator wrote:
           | This is the closest I could find to what the 68000 opcode map
           | looks like:
           | 
           | http://goldencrystal.free.fr/M68kOpcodes-v2.3.pdf
           | 
           | It's reminiscent of ARM, but the relevant part is that the
           | CAS instruction's second word bits 5:0 look like a "modrm"
           | (to use the x86 terminology) where the officially documented
           | values select only Dn, but the undocumented variant would
           | correspond to (d16,An). At least, that's my theory for why A1
           | gets modified.
        
             | userbinator wrote:
             | Update: from the linked thread at
             | https://68kmla.org/bb/index.php?threads/classic-ii-
             | possible-... there is this quote that supports my theory:
             | 
             |  _This seems to put something into A1 [...]If you clear bit
             | 3 from the second word of the instruction this stops
             | happening._
        
               | dougg3 wrote:
               | It also appears that I may not have been the first one to
               | discover that something odd was going on with that bit,
               | causing it to use A0-A7 (with weird results) instead of
               | D0-D7:
               | 
               | https://eab.abime.net/showthread.php?t=119675
        
         | sowbug wrote:
         | In college, I took a computer architecture course that briefly
         | went into CPU microcode. The fake CPU we studied divided
         | opcodes into bit fields where a certain bit caused a certain
         | primitive operation, like maybe triggering an adder. From this
         | you could see that a specific opcode was just a particular
         | composition of the right primitives. "Valid" opcodes were
         | simply the combinations that were useful enough to document,
         | and "invalid" ones were superfluous or meaningless
         | combinations. Once you understand this, illegal/invalid/mystery
         | opcodes are a lot less surprising; rather, they're inevitable.
         | 
         | I was also taking a logic course at the time and dreaming in
         | terms of truth tables, so it was quite a formative time in my
         | early understanding of processor architecture.
        
       | submeta wrote:
       | I had an Amiga 2000 with an 68000 processor when I was a kid. How
       | I got excited when I heared about the 68020, or even 68030! And
       | then even RISC architecture. Those were things that got me
       | excited back in those days. I could let my Amiga say a sentence
       | like ,,Hello, how are you?", in a robotic tone, and my friends
       | were baffled as if they'd been to the moon and back. I couldn't
       | have imagined that less then four decades later I'd be talking to
       | my computer in natural language using llms. And with Python, VS
       | Code, and LLM in my toolbelt I can automate almost anything I
       | wish to. Crazy times!
        
       | fredoralive wrote:
       | Re Egret and Command-Power, I'm pretty sure the key combination
       | (and the command-control-power hard reset combo) is always
       | active, and not a Macsbug thing. ISTR you can trigger sad Macs on
       | boot with it, which would be before Macsbug is loaded (I think),
       | and also access the mini debugger if Macsbug isn't loaded. At
       | least from what I remember about my old LCII (would have to dig
       | it out to double check though).
        
         | dougg3 wrote:
         | I've been trying it out a bunch lately. From what I've seen,
         | machines with Egret don't have it enabled by default, but
         | machines with the newer Cuda do.
        
       | Zardoz84 wrote:
       | > By buying a Classic II and hacking the ROM...
       | 
       | I think that to be a perfect article, they should wrote :
       | 
       | By the magic of buying a Classic II and hacking the ROM...
        
       | kazinator wrote:
       | It's not miraculous. If the flaw had prevented the system from
       | booting (in a way that has a high repro rate) they would have
       | fixed it.
       | 
       | The system booted in spite of that undocumented instruction. When
       | things work, you don't go looking for undocumented things that
       | are contributing to the working state.
       | 
       | Millions of C programs work accidentally, in spite of undefined
       | behavior. Nothing gets investigated until a compiler change
       | triggers something.
        
         | dougg3 wrote:
         | Don't you think, as a Mac ROM developer, the chances of your
         | software bug being accidentally fixed by the CPU through an
         | undocumented instruction are pretty low? That's what I was
         | getting at when I wrote that.
         | 
         | Of course they would have fixed it if it had prevented the
         | system from booting, I even said that in the article. I still
         | think the odds of what happened here were pretty small. That's
         | what I meant by miraculous.
        
       | ptek wrote:
       | Damn this instruction won't speed up Amiga chunky to planar
       | conversion.
        
       | knuckleheadsmif wrote:
       | Perhaps it is 'undocumented' and is used as proof of someone
       | copying the source code some portion of the source code.
       | 
       | Another possibility is that is a special institution in the chip
       | specifically for Apple that again was used as a copy write
       | detection or protection scheme.
        
       ___________________________________________________________________
       (page generated 2025-01-26 23:01 UTC)