6502 / 65C12 Instruction Set Reference
Complete cycle/opcode/byte table per mnemonic. Cycle counts are CPU cycles — multiply by 0.5 µs for 2 MHz BBC (1 cycle), 0.33 µs for 6502 2P (3 MHz), 0.25 µs for Master Turbo (4 MHz).
Marks:
*65C12 only (Master, Master Compact). Not present on Model B / B+ / Electron.**R65C02 only (Master Turbo, 6502 2P). Not recognised by BBC BASIC assembler.
Cycle notation: +1p = +1 if indexed address crosses a page boundary (loads only — stores are at the higher count unconditionally). +1b = +1 if branch is taken. +2np = +2 if branch destination is on a new page (combined with +1b: a same-page-taken branch is 3c; a new-page-taken branch is 4c).
Summary
NAUG §5.2 p38.
| Mnemonic | Function | Effect |
|---|---|---|
| ADC | Add with carry | A,C = A + M + C |
| AND | Logical AND | A = A AND M |
| ASL | Arithmetic shift left | M = M*2, C = M7 (A or M) |
| BBR** 0-7 | Branch on bit reset | Branch if zp bit = 0 |
| BBS** 0-7 | Branch on bit set | Branch if zp bit = 1 |
| BCC | Branch if carry clear | Branch if C = 0 |
| BCS | Branch if carry set | Branch if C = 1 |
| BEQ | Branch on zero | Branch if Z = 1 |
| BIT | Test memory bits | A AND M; N=M7, V=M6 |
| BMI | Branch if minus | Branch if N = 1 |
| BNE | Branch if not zero | Branch if Z = 0 |
| BPL | Branch if positive | Branch if N = 0 |
| BRA* | Branch always | — |
| BRK | Force interrupt | PC,P→stack; PC=(&FFFE) |
| BVC | Branch if V clear | Branch if V = 0 |
| BVS | Branch if V set | Branch if V = 1 |
| CLC/CLD/CLI/CLV | Clear flag | C/D/I/V = 0 |
| CLR* | Clear memory | M = 0 (synonym for STZ) |
| CMP | Compare A with M | A - M (flags) |
| CPX/CPY | Compare X/Y with M | X-M / Y-M (flags) |
| DEC/DEA* | Decrement | M=M-1 (DEA=A-1) |
| DEX/DEY | Decrement X/Y | X-1 / Y-1 |
| EOR | Exclusive OR | A = A EOR M |
| INC/INA* | Increment | M=M+1 (INA=A+1) |
| INX/INY | Increment X/Y | X+1 / Y+1 |
| JMP | Jump | PC = addr |
| JSR | Jump to subroutine | push PC; PC = addr |
| LDA/LDX/LDY | Load reg from M | A/X/Y = M |
| LSR | Logical shift right | M = M/2; C = M0 |
| NOP | No operation | — |
| ORA | OR with A | A = A OR M |
| PHA/PHP | Push A / P | — |
| PHX*/PHY* | Push X / Y | — |
| PLA/PLP | Pull A / P | — |
| PLX*/PLY* | Pull X / Y | — |
| RMB** 0-7 | Reset memory bit | zp bit = 0 |
| ROL/ROR | Rotate left/right | through C |
| RTI | Return from interrupt | pull P, pull PC |
| RTS | Return from subroutine | pull PC |
| SBC | Subtract with borrow | A,C = A - M - (1-C) |
| SEC/SED/SEI | Set flag | C/D/I = 1 |
| SMB** 0-7 | Set memory bit | zp bit = 1 |
| STA/STX/STY | Store reg to M | M = A/X/Y |
| STZ* | Store zero | M = 0 |
| TAX/TAY/TSX/TXA/TXS/TYA | Transfer registers | — |
| TRB* | Test and reset bits | M = M AND NOT A |
| TSB* | Test and set bits | M = M OR A |
Per-mnemonic addressing modes, bytes, cycles, opcodes
Format: mode | bytes | cycles | opcode. (zp ind)* = 65C12 (zero page indirect) — opcode pattern ends &x2. RMW absolute,X timings differ on NMOS — annotated [6502A: 7] where applicable.
ADC — Add with carry (p39)
imm 2 2 &69
zp 2 3 &65
zp,X 2 4 &75
(zp ind)* 2 5 &72
abs 3 4 &6D
abs,X 3 4 +1p &7D
abs,Y 3 4 +1p &79
(ind,X) 2 6 &61
(ind),Y 2 5 +1p &71
+1c on 65C12 if decimal-mode (D=1).
AND — Logical AND (p40)
imm 2 2 &29
zp 2 3 &25
zp,X 2 4 &35
(zp ind)* 2 5 &32
abs 3 4 &2D
abs,X 3 4 +1p &3D
abs,Y 3 4 +1p &39
(ind,X) 2 6 &21
(ind),Y 2 5 +1p &31
ASL — Arithmetic shift left (p41)
A 1 2 &0A
zp 2 5 &06
zp,X 2 6 &16
abs 3 6 &0E
abs,X 3 6 +1p [6502A: 7] &1E
BBR**0..7 — Branch on bit reset (p42)
zp 3 5 +1b +2np
opcodes: bit0=&0F bit1=&1F bit2=&2F bit3=&3F bit4=&4F bit5=&5F bit6=&6F bit7=&7F
Encoded as 3 bytes: EQUB <opcode>, EQUB <zp addr>, EQUB <signed rel offset>. Branch offset of -3 returns to BBR (instruction is 3 bytes).
BBS**0..7 — Branch on bit set (p43)
zp 3 5 +1b +2np
opcodes: bit0=&8F bit1=&9F bit2=&AF bit3=&BF bit4=&CF bit5=&DF bit6=&EF bit7=&FF
BCC / BCS / BEQ / BMI / BNE / BPL / BVC / BVS — Conditional branches (p44-54)
rel 2 2 +1b +2np
opcodes: BCC=&90 BCS=&B0 BEQ=&F0 BMI=&30 BNE=&D0 BPL=&10 BVC=&50 BVS=&70
Same-page taken = 3c. New-page taken = 4c. Not-taken = 2c.
BIT — Test bits (p47)
imm* 2 2 &89 (V,N unchanged in imm mode)
zp 2 3 &24
abs 3 4 &2C
abs,X* 3 4 +1p &3C
zp,X* 2 4 &34
BRA* — Branch always (p51)
rel 2 3 +1np &80
3c base, 4c if to new page. One byte shorter and 1c cheaper than JMP abs.
BRK — Forced interrupt (p52)
implied 1 7 &00
Pushes PC then P (with B=1). Jumps via (&FFFE). On 65C12, D is cleared. On NMOS, D is not cleared — handlers must clear it manually if BCD code is around.
CLC / CLD / CLI / CLV — Clear flag (p55-59)
implied 1 2
opcodes: CLC=&18 CLD=&D8 CLI=&58 CLV=&B8
CLR* — Clear memory (p58, synonym for STZ)
zp 2 3 &64
zp,X 2 4 &74
abs 3 4 &9C
abs,X 3 5 &9E
CMP — Compare A (p60)
imm 2 2 &C9
zp 2 3 &C5
zp,X 2 4 &D5
(zp ind)* 2 5 &D2
abs 3 4 &CD
abs,X 3 4 +1p &DD
abs,Y 3 4 +1p &D9
(ind,X) 2 6 &C1
(ind),Y 2 5 +1p &D1
After CMP: BEQ = A==M; BCS = A>=M; BCC = A<M; for “A>M” use BCS then BNE.
CPX — Compare X (p62)
imm 2 2 &E0
zp 2 3 &E4
abs 3 4 &EC
CPY — Compare Y (p63)
imm 2 2 &C0
zp 2 3 &C4
abs 3 4 &CC
DEC / DEA* — Decrement memory or A (p64)
A* 1 2 &3A (alias DEA)
zp 2 5 &C6
zp,X 2 6 &D6
abs 3 6 &CE
abs,X 3 7 &DE
DEX / DEY — Decrement X / Y (p65, p66)
implied 1 2
opcodes: DEX=&CA DEY=&88
EOR — Exclusive OR (p67)
imm 2 2 &49
zp 2 3 &45
zp,X 2 4 &55
(zp ind)* 2 5 &52
abs 3 4 &4D
abs,X 3 4 +1p &5D
abs,Y 3 4 +1p &59
(ind,X) 2 6 &41
(ind),Y 2 5 +1p &51
INC / INA* — Increment memory or A (p68)
A* 1 2 &1A (alias INA)
zp 2 5 &E6
zp,X 2 6 &F6
abs 3 6 &EE
abs,X 3 7 &FE
INX / INY — Increment X / Y (p69, p70)
implied 1 2
opcodes: INX=&E8 INY=&C8
JMP — Jump (p71)
abs 3 3 &4C
(ind) 3 6 [6502A: 5] &6C
(abs,X)* 3 6 &7C
JMP (ind) is 6c on 65C12 (bug-fixed) vs 5c on NMOS 6502A.
JSR — Jump to subroutine (p72)
abs 3 6 &20
LDA — Load A (p73)
imm 2 2 &A9
zp 2 3 &A5
zp,X 2 4 &B5
(zp ind)* 2 5 &B2
abs 3 4 &AD
abs,X 3 4 +1p &BD
abs,Y 3 4 +1p &B9
(ind,X) 2 6 &A1
(ind),Y 2 5 +1p &B1
LDX — Load X (p74)
imm 2 2 &A2
zp 2 3 &A6
zp,Y 2 4 &B6
abs 3 4 &AE
abs,Y 3 4 +1p &BE
LDY — Load Y (p75)
imm 2 2 &A0
zp 2 3 &A4
zp,X 2 4 &B4
abs 3 4 &AC
abs,X 3 4 +1p &BC
LSR — Logical shift right (p76)
A 1 2 &4A
zp 2 5 &46
zp,X 2 6 &56
abs 3 6 &4E
abs,X 3 6 +1p [6502A: 7] &5E
NOP (p77)
implied 1 2 &EA
ORA — OR with A (p78)
imm 2 2 &09
zp 2 3 &05
zp,X 2 4 &15
(zp ind)* 2 5 &12
abs 3 4 &0D
abs,X 3 4 +1p &1D
abs,Y 3 4 +1p &19
(ind,X) 2 6 &01
(ind),Y 2 5 +1p &11
PHA / PHP / PHX* / PHY* — Push (p79-82)
implied 1 3
opcodes: PHA=&48 PHP=&08 PHX*=&DA PHY*=&5A
PLA / PLP / PLX* / PLY* — Pull (p83-86)
implied 1 4
opcodes: PLA=&68 PLP=&28 PLX*=&FA PLY*=&7A
ROL — Rotate left (p87)
A 1 2 &2A
zp 2 5 &26
zp,X 2 6 &36
abs 3 6 &2E
abs,X 3 6 +1p [6502A: 7] &3E
ROR — Rotate right (p88)
A 1 2 &6A
zp 2 5 &66
zp,X 2 6 &76
abs 3 6 &6E
abs,X 3 6 +1p [6502A: 7] &7E
RTI — Return from interrupt (p89)
implied 1 6 &40
RTS — Return from subroutine (p90)
implied 1 6 &60
SBC — Subtract with borrow (p91)
imm 2 2 &E9
zp 2 3 &E5
zp,X 2 4 &F5
(zp ind)* 2 5 &F2
abs 3 4 &ED
abs,X 3 4 +1p &FD
abs,Y 3 4 +1p &F9
(ind,X) 2 6 &E1
(ind),Y 2 5 +1p &F1
+1c on 65C12 if decimal-mode.
SEC / SED / SEI — Set flag (p92-94)
implied 1 2
opcodes: SEC=&38 SED=&F8 SEI=&78
STA — Store A (p95)
zp 2 3 &85
zp,X 2 4 &95
(zp ind)* 2 5 &92
abs 3 4 &8D
abs,X 3 5 &9D
abs,Y 3 5 &99
(ind,X) 2 6 &81
(ind),Y 2 6 &91
STX — Store X (p96)
zp 2 3 &86
zp,Y 2 4 &96
abs 3 4 &8E
STY — Store Y (p97)
zp 2 3 &84
zp,X 2 4 &94
abs 3 4 &8C
STZ* — Store zero (p98, synonym CLR)
zp 2 3 &64
zp,X 2 4 &74
abs 3 4 &9C
abs,X 3 5 &9E
TAX / TAY / TSX / TXA / TXS / TYA — Transfer (p99-105)
implied 1 2
opcodes: TAX=&AA TAY=&A8 TSX=&BA TXA=&8A TXS=&9A TYA=&98
TRB* — Test and reset bits (p101)
zp 2 5 &14
abs 3 6 &1C
M = M AND NOT A; Z set if A AND M == 0.
TSB* — Test and set bits (p102)
zp 2 5 &04
abs 3 6 &0C
M = M OR A; Z set if A AND M == 0.
R65C02-only
BBR0..7/BBS0..7 opcodes: see BBR/BBS sections above.
| Mnemonic | Bytes | Cycles | Opcode pattern |
|---|---|---|---|
| RMB0..7 zp | 2 | 5 | &07 + bit*&10 (e.g. RMB0=&07, RMB1=&17, … RMB7=&77) |
| SMB0..7 zp | 2 | 5 | &87 + bit*&10 (e.g. SMB0=&87, … SMB7=&F7) |
(NAUG §5.2 only details BBR/BBS explicitly with examples; the RMB/SMB/WAI/STP encodings are summarised here from the chapter’s R65C02 caveats — verify against the R65C02 datasheet before relying on them.)
Performance reference
- Cheapest read:
LDA imm/LDA zp— 2c / 3c. - Cheapest indexed read (without page penalty):
LDA zp,X— 4c. - Cheapest 16-bit pointer deref:
LDA (zp),Y— 5c (+1 if page crossed). - Cheapest 16-bit pointer deref on 65C12 without an index:
LDA (zp)— 5c flat, no page penalty. - Branches: 3c when taken within page, 4c across. Prefer to layout hot loops so the common path is fall-through.
- JSR + RTS total overhead: 6 + 6 = 12 cycles. Often worth inlining at the hot edges.
- Decimal mode on 65C12 costs +1c per ADC/SBC — avoid in inner loops on Master.
See 6502 for register/flag model and CPU variants. See 6502-addressing-modes for the mechanics of each mode (why (zp),Y is 5c, why abs,X pays +1 on page-cross, etc). See naug-ch05-6502-isa for the chapter’s notational conventions.
This wiki is curated by Claude following the LLM-Wiki methodology — a human curates source documents, the LLM compiles structured cross-linked markdown. Content may contain errors, omissions, or stale claims. For authoritative information refer to the original source documents in the bbc-documents GitHub archive.