I was reading about undocumented opcodes for the 650x family of processors and discovered JAM, an instruction "which simply causes the CPU to freeze, requiring a hardware reset or power cycle to restart."1

Was this instruction ever used in practice/production software? What is a use case for this instruction? Could it be used to lock the hardware on an invalid instruction or if an invalid program was loaded?


It's a bit misleading to call them "undocumented opcodes". "Accidental opcodes" would be more accurate.

Instead of using microcode, the 6502 family used a programmable logic array as a lookup table to break an instruction down into a series of simpler steps. At each step of executing an instruction, the CPU would form a bit pattern from the instruction and instruction clock and feed it into the PLA. The PLA would then activate one of its output lines based on that bit pattern, and the CPU would execute the corresponding micro-operation. This process repeats until the instruction finishes and the instruction clock gets reset.

Many opcodes share micro-operations (for example, every branch instruction shares a "modify the program counter" micro-op), and the CPU designers took full advantage of this to reduce the size of the PLA. Because of this sharing of micro-operations, bit patterns that aren't a documented instruction can still trigger a sequence of micro-operations. The JAM instruction (also documented as KIL or HLT) is one where the sequence of accidentally-triggered micro-operations never resets the instruction clock.

Because the effects of these instructions are an accidental side-effect of the layout of the PLA, they can change from chip to chip as developers try to optimize things. The KIL family are particularly vulnerable to changing because they require that none of the accidentally-triggered micro-operations include a "reset the instruction counter" step.

The vulnerability to changing is why KIL would not be used in production code.

Source: http://www.pagetable.com/?p=39

List of opcodes showing some of the model-to-model variation: http://bbc.nvg.org/doc/6502OpList.txt

  • All of the NMOS 6502 chips that are ever going to be built, most likely have been, and while it would have been possible for companies like Commodore which produced their own 6502 variants to have changed the behavior of undocumented opcodes, most of the useful-but-undocumented opcodes behave consistently among all known manufactured NMOS 6502 variants. The CMOS variants are another story, since CMOS logic requires that every internal signal have a single definite source at all times (rather than using wired-NOR buses where a signal is high if nothing pulls it low). – supercat Aug 12 '16 at 18:10
  • 1
    On all NMOS 6502 variants, for example, two bits of STA/STX/STY identify whether the instruction should store A (one bit set), X (the other bit set), or Y (neither bit set). Setting both bits will cause A and X to be gated to the internal bus simultaneously, but in NMOS the effect of that is to store the bitwise AND of the values in A and X (either A or X can pull down each bit of an internal bus, and any bit not pulled down will be high). Such implicit ANDing is safe in NMOS, but not in CMOS. – supercat Aug 12 '16 at 18:15
  • @supercat so what does sax do in CMOS? Anything useful/reliable? That information is missing from the document 6502OpList.txt. – Wilson Jun 12 at 10:06
  • @Wilson: Some opcodes that were undefined on the NMOS 6502 either have different assigned purposes on the 65C02. Opcodes which don't have any assigned purpose are nominally treated as NOP, though some will fetch and ignore operands. What's significant is that the behavioral assignments are deliberate. Something like "SAX" couldn't work unless deliberately engineered because in properly-designed CMOS every bus must have a definite non-conflicted value at all times, and design tools will squawk if that isn't the case. – supercat Jun 12 at 14:12
  • 1
    @supercat Not everything that runs 6502 machine code is a 6502. Later versions of the architecture often used the undocumented opcodes for different real opcodes. Furthermore, not all emulators "correctly" implement the undocumented opcodes. – JeremyP Jun 14 at 8:42

In some memory constrained situations (like a 4K demo or something like that), it could be useful to stop the CPU. A jam instruction is one obvious way to accomplish that in as few bytes as possible. Only the CPU will stop, so if you left some image or whatever on the screen, that's going to stay there.

But another use I can think of is copy protection. Maybe you deliberately put jam in the instruction stream as loaded from the disk. Then that byte is somehow replaced or modified in some hard-to-figure-out way, such as inside your raster interrupt, so that the whole thing is very delicately dependant on precise timing. Then if your program is pirated, the jam executes, but under the condition that the developer expects, the program proceeds normally. I think I remember a description of a copy-protection scheme which worked in this way. But I can't remember exactly which game or which platform.

  • Like a watchdog circuit in some arcade boards. – DroidW Jun 12 at 11:33
  • @DroidW Exactly that. Do you know of a specimen or example? – Wilson Jun 13 at 7:55
  • There you go in arcades: Reset Watchdog circuit in Rainbow Islands Arcade This is a somewhat late example, but I recall early 80s machines commonly had reset watchdogs to prevent hangs, and this is, IMO, entirely different to hang purposefully the machine (with an undocumented opcode) as a protection mechanism. Of the latter, sorry, I do not know of any specimen. – DroidW Jun 14 at 6:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.