Introduction
The NMOS 6502 decodes every one of the 256 possible opcodes. MOS documented 151 of them. The rest were left out of the data sheet because the decoder’s logic gives them by accident: the opcode is split into bit fields, and where two fields select instructions at once the chip does both. Most are combinations of two documented operations, and many programs for the Commodore 64, the NES and the Atari 8-bit machines use them.
The explorer gives each its status (see the overview):
- Undocumented: 85 opcodes that do the same on every NMOS chip. They are safe to use on the NMOS 6502, the 6510 and the 2A03.
- Unstable: 8 opcodes whose result depends on the chip, its revision or the conditions. Programs should not rely on them.
- Jam: 12 opcodes that stop the processor.
The 65C02 defines all of these opcodes, as NOPs or as its own instructions. A 65C02 decode therefore shows none of them as undocumented. Other names exist for several of these instructions (ASO for SLO, LSE for SRE, ISB for ISC, AXA for SHA, SBX for AXS, ASR for ALR, ANE for XAA, SHS for TAS, LAR for LAS); the explorer shows the names used here.
Undocumented and stable
The read-modify-write combinations (SLO, RLA, SRE, RRA, DCP, ISC) operate on a memory byte and then use the new value against the accumulator. They have the timing of a read-modify-write instruction and, like one, write the unchanged byte back before the changed one.
| Instruction | Forms | What it does | Flags | Status |
|---|---|---|---|---|
slo | zp 07, 2, 5zp,X 17, 2, 6abs 0F, 3, 6abs,X 1F, 3, 7abs,Y 1B, 3, 7(zp,X) 03, 2, 8(zp),Y 13, 2, 8 | ASL on the memory byte, then ORA of the result into A. Also called ASO. | N Z C | Undocumented |
rla | zp 27, 2, 5zp,X 37, 2, 6abs 2F, 3, 6abs,X 3F, 3, 7abs,Y 3B, 3, 7(zp,X) 23, 2, 8(zp),Y 33, 2, 8 | ROL on the memory byte, then AND of the result into A. | N Z C | Undocumented |
sre | zp 47, 2, 5zp,X 57, 2, 6abs 4F, 3, 6abs,X 5F, 3, 7abs,Y 5B, 3, 7(zp,X) 43, 2, 8(zp),Y 53, 2, 8 | LSR on the memory byte, then exclusive OR of the result into A. Also called LSE. | N Z C | Undocumented |
rra | zp 67, 2, 5zp,X 77, 2, 6abs 6F, 3, 6abs,X 7F, 3, 7abs,Y 7B, 3, 7(zp,X) 63, 2, 8(zp),Y 73, 2, 8 | ROR on the memory byte, then ADC of the result into A (using the carry the ROR produced). | N V Z C | Undocumented |
dcp | zp C7, 2, 5zp,X D7, 2, 6abs CF, 3, 6abs,X DF, 3, 7abs,Y DB, 3, 7(zp,X) C3, 2, 8(zp),Y D3, 2, 8 | DEC the memory byte, then CMP it with A. Also called DCM. | N Z C | Undocumented |
isc | zp E7, 2, 5zp,X F7, 2, 6abs EF, 3, 6abs,X FF, 3, 7abs,Y FB, 3, 7(zp,X) E3, 2, 8(zp),Y F3, 2, 8 | INC the memory byte, then SBC it from A. Also called ISB and INS. | N V Z C | Undocumented |
sax | zp 87, 2, 3zp,Y 97, 2, 4abs 8F, 3, 4(zp,X) 83, 2, 6 | Stores A AND X. No flags change. Also called AAX. | – | Undocumented |
lax | zp A7, 2, 3zp,Y B7, 2, 4abs AF, 3, 4abs,Y BF, 3, 4 +1 page(zp,X) A3, 2, 6(zp),Y B3, 2, 5 +1 page | Loads the memory byte into both A and X. (The immediate form, AB, is the unstable LXA.) | N Z | Undocumented |
anc | imm 0B, 2, 2imm 2B, 2, 2 | A = A AND the immediate; then C becomes a copy of N (bit 7 of the result). | N Z C | Undocumented |
alr | imm 4B, 2, 2 | A = A AND the immediate, then LSR A. Also called ASR. | N Z C | Undocumented |
arr | imm 6B, 2, 2 | A = A AND the immediate, then ROR A, with C and V set from bits 6 and 5 of the result (C = bit 6, V = bit 6 exclusive-OR bit 5). In decimal mode it behaves differently again. | N V Z C | Undocumented |
axs | imm CB, 2, 2 | X = (A AND X) minus the immediate, without borrow (the carry is ignored); C is set as in CMP. Also called SBX. | N Z C | Undocumented |
sbc (EB) | imm EB, 2, 2 | The same as SBC immediate (E9). Some assemblers call it USBC. | N V Z C | Undocumented |
nop | implied 1A 3A 5A 7A DA FA, 1, 2imm 80 82 89 C2 E2, 2, 2zp 04 44 64, 2, 3zp,X 14 34 54 74 D4 F4, 2, 4abs 0C, 3, 4abs,X 1C 3C 5C 7C DC FC, 3, 4 +1 page | Do nothing, but the forms with an operand read it (so they can touch a hardware register) and are 2 or 3 bytes long. | – | Undocumented |
Unstable
These eight give results that depend on the individual chip, its temperature, the supply or the electrical state of the bus. Descriptions differ between sources and chips, so what follows is the usual behaviour, not a promise. Do not use them in new code. Emulators handle them with a chosen constant, and different emulators choose differently.
| Instruction | Forms | What it does (usually) | Flags | Status |
|---|---|---|---|---|
xaa | imm 8B, 2, 2 | A = (A OR magic) AND X AND the immediate. The magic constant differs between chips and with conditions; $EE, $EF and $FF have been observed. Also called ANE. | N Z | Unstable |
lxa | imm AB, 2, 2 | A = X = (A OR magic) AND the immediate, with a chip-dependent constant as for XAA. Also called LAX #imm and OAL. | N Z | Unstable |
sha | abs,Y 9F, 3, 5(zp),Y 93, 2, 6 | Stores A AND X AND (the high byte of the base address + 1). When indexing crosses a page, the high byte of the address written is replaced by the stored value on some chips. Also called AHX and AXA. | – | Unstable |
shx | abs,Y 9E, 3, 5 | Stores X AND (the high byte of the base address + 1), with the page-crossing behaviour of SHA. Also called SXA. | – | Unstable |
shy | abs,X 9C, 3, 5 | Stores Y AND (the high byte of the base address + 1), with the page-crossing behaviour of SHA. Also called SYA. | – | Unstable |
tas | abs,Y 9B, 3, 5 | S = A AND X, then stores S AND (the high byte of the base address + 1). Also called SHS and XAS. | – | Unstable |
las | abs,Y BB, 3, 4 +1 page | A = X = S = the memory byte AND S. Also called LAR. The explorer marks it unstable, as several references do; some chips are reported to give the same result every time. | N Z | Unstable |
Jam
| Instruction | Opcodes | What it does | Status |
|---|---|---|---|
kil | 02 12 22 32 42 52 62 72 92 B2 D2 F2, 1 byte | The processor locks up: it stops fetching instructions, and only a reset recovers it (an interrupt does not). Also called JAM and HLT. The opcode B2 and the others are defined on the 65C02, so this applies to the NMOS chips only. | Jam |
How these were checked
The explorer’s decoder was compared opcode by opcode with two published tables (the MOS documentation for the 151 documented opcodes, and the NESdev and “No More Secrets” tables for the undocumented ones), and run against an emulator core on every opcode from random states: lengths, which registers and flags change, whether memory is read or written, and the cycle count. The only difference found is that the emulator does not perform the read of the undocumented NOPs’ operands, which real chips do. The behaviour of the unstable opcodes is not checked against hardware.