# Opcode

**Opcodes** (short for Operation Codes) are processor instructions used in machine language.
The 6510 CPU offers 151 ^{[1]} official opcodes, plus 105 illegal (unofficial) opcodes, totaling 256 opcodes.

## Legal Opcodes[edit | edit source]

Examples:

- $C8 (11001000) is the opcode for the mnemonic INY.
- $EA (11101010) is the opcode for the mnemonic NOP.

## Illegal Opcodes[edit | edit source]

Illegal opcodes are undocumented commands that exist as a side-effect of the hardwired circuit design and were called "illegal" because they are not guaranteed to work reliably.

## Opcode matrix for MOS 6510[edit | edit source]

Illegal Opcodes are coloured red.

x0 |
x1 |
x2 |
x3 |
x4 |
x5 |
x6 |
x7 |
x8 |
x9 |
xA |
xB |
xC |
xD |
xE |
xF
| |

0x |
BRK imp |
ORA inx |
JAM | SLO inx |
NOP zp |
ORA zp |
ASL zp |
SLO zp |
PHP imp |
ORA imm |
ASL akk |
ANC imm |
NOP abs |
ORA abs |
ASL abs |
SLO abs |

1x |
BPL rel |
ORA iny |
JAM | SLO iny |
NOP zpx |
ORA zpx |
ASL zpx |
SLO zpy |
CLC imp |
ORA aby |
NOP imp |
SLO aby |
NOP abx |
ORA abx |
ASL abx |
SLO abx |

2x |
JSR abs |
AND inx |
JAM | RLA inx |
BIT zp |
AND zp |
ROL zp |
RLA zp |
PLP imp |
AND imm |
ROL akk |
ANC imm |
BIT abs |
AND abs |
ROL abs |
RLA abs |

3x |
BMI rel |
AND iny |
JAM | RLA iny |
NOP zpx |
AND zpx |
ROL zpx |
RLA zpy |
SEC imp |
AND aby |
NOP imp |
RLA aby |
NOP abx |
AND abx |
ROL abx |
RLA abx |

4x |
RTI imp |
EOR inx |
JAM | SRE inx |
NOP zp |
EOR zp |
LSR zp |
SRE zp |
PHA imp |
EOR imm |
LSR akk |
ALR imm |
JMP abs |
EOR abs |
LSR abs |
SRE abs |

5x |
BVC rel |
EOR iny |
JAM | SRE iny |
NOP zpx |
EOR zpx |
LSR zpx |
SRE zpx |
CLI imp |
EOR aby |
NOP imp |
SRE aby |
NOP abx |
EOR abx |
LSR abx |
SRE abx |

6x |
RTS imp |
ADC inx |
JAM | RRA inx |
NOP zp |
ADC zp |
ROR zp |
RRA zp |
PLA imp |
ADC imm |
ROR akk |
ARR imm |
JMP ind |
ADC abs |
ROR abs |
RRA abs |

7x |
BVS rel |
ADC iny |
JAM | RRA iny |
NOP zpx |
ADC zpx |
ROR zpx |
RRA zpx |
SEI imp |
ADC aby |
NOP imp |
RRA aby |
NOP abx |
ADC abx |
ROR abx |
RRA abx |

8x |
NOP imm |
STA inx |
NOP imm |
SAX inx |
STY zp |
STA zp |
STX zp |
SAX zp |
DEY imp |
NOP imm |
TXA imp |
ANE imm |
STY abs |
STA abs |
STX abs |
SAX abs |

9x |
BCC rel |
STA iny |
JAM | SHA iny |
STY zpx |
STA zpx |
STX zpy |
SAX zpy |
TYA imp |
STA aby |
TXS imp |
TAS aby |
SHY abx |
STA abx |
SHX aby |
SHA aby |

Ax |
LDY imm |
LDA inx |
LDX imm |
LAX inx |
LDY zp |
LDA zp |
LDX zp |
LAX zp |
TAY imp |
LDA imm |
TAX imp |
LAX imm |
LDY abs |
LDA abs |
LDX abs |
LAX abs |

Bx |
BCS rel |
LDA iny |
JAM | LAX iny |
LDY zpx |
LDA zpx |
LDX zpy |
LAX zpy |
CLV imp |
LDA aby |
TSX imp |
LAS aby |
LDY abx |
LDA abx |
LDX aby |
LAX aby |

Cx |
CPY imm |
CMP inx |
NOP imm |
DCP inx |
CPY zp |
CMP zp |
DEC zp |
DCP zp |
INY imp |
CMP imm |
DEX imp |
SBX imm |
CPY abs |
CMP abs |
DEC abs |
DCP abs |

Dx |
BNE rel |
CMP iny |
JAM | DCP iny |
NOP zpx |
CMP zpx |
DEC zpx |
DCP zpx |
CLD imp |
CMP aby |
NOP imp |
DCP aby |
NOP abx |
CMP abx |
DEC abx |
DCP abx |

Ex |
CPX imm |
SBC inx |
NOP imm |
ISC inx |
CPX zp |
SBC zp |
INC zp |
ISC zp |
INX imp |
SBC imm |
NOP | SBC imm |
CPX abs |
SBC abs |
INC abs |
ISC abs |

Fx |
BEQ rel |
SBC iny |
JAM | ISC iny |
NOP zpx |
SBC zpx |
INC zpx |
ISC zpx |
SED imp |
SBC aby |
NOP imp |
ISC aby |
NOP abx |
SBC abx |
INC abx |
ISC abx |

## Arrangement[edit | edit source]

The microcode of the 6502 is compressed into a 130-entry decode ROM. Instead of 256 entries telling how to process each separate opcode, it's encoded as combinational logic post-processing the output of a "sparse" ROM that acts in some ways like a programmable logic array (PLA). Each entry in the ROM means "if these bits are on, and these bits are off, do things on these six cycles.

Many instructions activate multiple lines of the decode ROM at once. Often this is on purpose, such as one line for the addressing mode and one for the opcode part. But many of the unofficial opcodes simultaneously trigger parts of the ROM that were intended for completely unrelated instructions.

Perhaps the pattern is easier to see by shuffling the 6502's opcode matrix. This table lists all 6502 opcodes, 32 columns per row. The columns are colored by bits 1 and 0: 00 red, 01 green, 10 blue, and 11 gray.

Key: a is a 16-bit absolute address, and d is an 8-bit zero page address. Entries in bold represent unofficial opcodes.

+00 | +04 | +08 | +0C | +10 | +14 | +18 | +1C | +01 | +05 | +09 | +0D | +11 | +15 | +19 | +1D | +02 | +06 | +0A | +0E | +12 | +16 | +1A | +1E | +03 | +07 | +0B | +0F | +13 | +17 | +1B | +1F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|

00 | BRK |
NOPd |
PHP |
NOPa |
BPL *+d |
NOPd,x |
CLC |
NOPa,x |
ORA (d,x) |
ORA d |
ORA #i |
ORA a |
ORA (d),y |
ORA d,x |
ORA a,y |
ORA a,x |
JAM |
ASL d |
ASL |
ASL a |
JAM |
ASL d,x |
NOP |
ASL a,x |
SLO(d,x) |
SLOd |
ANC#i |
SLOa |
SLO(d),y |
SLOd,x |
SLOa,y |
SLOa,x |

20 | JSR a |
BIT d |
PLP |
BIT a |
BMI *+d |
NOPd,x |
SEC |
NOPa,x |
AND (d,x) |
AND d |
AND #i |
AND a |
AND (d),y |
AND d,x |
AND a,y |
AND a,x |
JAM |
ROL d |
ROL |
ROL a |
JAM |
ROL d,x |
NOP |
ROL a,x |
RLA(d,x) |
RLAd |
ANC#i |
RLAa |
RLA(d),y |
RLAd,x |
RLAa,y |
RLAa,x |

40 | RTI |
NOPd |
PHA |
JMP a |
BVC *+d |
NOPd,x |
CLI |
NOPa,x |
EOR (d,x) |
EOR d |
EOR #i |
EOR a |
EOR (d),y |
EOR d,x |
EOR a,y |
EOR a,x |
JAM |
LSR d |
LSR |
LSR a |
JAM |
LSR d,x |
NOP |
LSR a,x |
SRE(d,x) |
SREd |
ALR#i |
SREa |
SRE(d),y |
SREd,x |
SREa,y |
SREa,x |

60 | RTS |
NOPd |
PLA |
JMP (a) |
BVS *+d |
NOPd,x |
SEI |
NOPa,x |
ADC (d,x) |
ADC d |
ADC #i |
ADC a |
ADC (d),y |
ADC d,x |
ADC a,y |
ADC a,x |
JAM |
ROR d |
ROR |
ROR a |
JAM |
ROR d,x |
NOP |
ROR a,x |
RRA(d,x) |
RRAd |
ARR#i |
RRAa |
RRA(d),y |
RRAd,x |
RRAa,y |
RRAa,x |

80 | NOP#i |
STY d |
DEY |
STY a |
BCC *+d |
STY d,x |
TYA |
SHYa,x |
STA (d,x) |
STA d |
NOP#i |
STA a |
STA (d),y |
STA d,x |
STA a,y |
STA a,x |
NOP#i |
STX d |
TXA |
STX a |
JAM |
STX d,y |
TXS |
SHXa,y |
SAX(d,x) |
SAXd |
ANE#i |
SAXa |
SHA(d),y |
SAXd,y |
TASa,y |
SHAa,y |

A0 | LDY #i |
LDY d |
TAY |
LDY a |
BCS *+d |
LDY d,x |
CLV |
LDY a,x |
LDA (d,x) |
LDA d |
LDA #i |
LDA a |
LDA (d),y |
LDA d,x |
LDA a,y |
LDA a,x |
LDX #i |
LDX d |
TAX |
LDX a |
JAM |
LDX d,y |
TSX |
LDX a,y |
LAX(d,x) |
LAXd |
LAX#i |
LAXa |
LAX(d),y |
LAXd,y |
LASa,y |
LAXa,y |

C0 | CPY #i |
CPY d |
INY |
CPY a |
BNE *+d |
NOPd,x |
CLD |
NOPa,x |
CMP (d,x) |
CMP d |
CMP #i |
CMP a |
CMP (d),y |
CMP d,x |
CMP a,y |
CMP a,x |
NOP#i |
DEC d |
DEX |
DEC a |
JAM |
DEC d,x |
NOP |
DEC a,x |
DCP(d,x) |
DCPd |
SBX#i |
DCPa |
DCP(d),y |
DCPd,x |
DCPa,y |
DCPa,x |

E0 | CPX #i |
CPX d |
INX |
CPX a |
BEQ *+d |
NOPd,x |
SED |
NOPa,x |
SBC (d,x) |
SBC d |
SBC #i |
SBC a |
SBC (d),y |
SBC d,x |
SBC a,y |
SBC a,x |
NOP#i |
INC d |
NOP |
INC a |
JAM |
INC d,x |
NOP |
INC a,x |
ISC(d,x) |
ISCd |
SBC#i |
ISCa |
ISC(d),y |
ISCd,x |
ISCa,y |
ISCa,x |

Thus the 00 (red) block is mostly control instructions,
01 (green) is ALU operations,
and 10 (blue) is read-modify-write (RMW) operations and data movement instructions involving X.
The RMW instructions (all but row 80 and A0) in columns +06, +0E, +16, and +1E
have the same addressing modes as the corresponding ALU operations.

The 11 (gray) block is unofficial opcodes combining the operations of instructions from the ALU and RMW blocks. all of them having the same addressing mode as the corresponding ALU opcode. The RMW+ALU instructions that affect memory are easiest to understand because their RMW part completes during the opcode and the ALU part completes during the next opcode's fetch. Column +0B, on the other hand, has no extra cycles; everything completes during the next opcode's fetch. This causes instructions to have strange mixing properties. Some even differ based on analog effects.

## Links[edit | edit source]

- 6502/6510/8500/8502 opcodes (including illegal) at oxyron.de
- NMOS 6510 Unintended Opcodes (No More Secrets)

## References[edit | edit source]

- ↑ Codebase64.org - [Extra Instructions Of The 65XX Series CPU]