Programming the MEGA65 — Chapter 10: Vocabulary of the 45GS02

Oct 4, 2026 · Updated Oct 11, 2026 · @Craig Taylor

Introduction

This chapter is a reference to every instruction the 45GS02 executes, in alphabetical order. Each entry gives the operation, the flags it changes, every addressing mode with its opcode, and which processor introduced it. The opcodes follow the cc65 project's CPU reference (ca65/da65 CPU overview), which documents the 6502, 65C02, 65CE02, 4510 and 45GS02 instruction sets side by side.

The 65CE02 defines all 256 opcodes, and the 45GS02 builds its extensions from prefixes rather than new opcodes, so every byte value is a valid instruction or prefix. In its native mode there are no undocumented opcodes of the kind C64 programmers know; a separate 6502 compatibility mode, which the Book describes as incomplete and untested, emulates some of them (MEGA65 Book, 45GS02 and 6502 instruction sets appendix).

Cycle counts are not given here. The 45GS02's native timings differ from the 6502's, and at 40.5 MHz they also depend on memory type and wait states; Chapter 7 discusses timing, and the MEGA65 Book's CPU chapter is the authority.

Addressing mode abbreviations

Abbreviation Mode Example
impl Implied INX
A Accumulator ASL A
imm Immediate byte LDA #$41
imm16 Immediate word PHW #$1234
bp Base page LDA $10
bp,X / bp,Y Base page indexed LDA $10,X
abs Absolute LDA $D020
abs,X / abs,Y Absolute indexed LDA $0400,X
(bp,X) Indexed indirect LDA ($10,X)
(bp),Y Indirect indexed by Y LDA ($10),Y
(bp),Z Indirect indexed by Z LDA ($10),Z
[bp],Z Flat indirect, 32-bit pointer LDA [$10],Z
(d,SP),Y Stack relative indirect LDA ($02,SP),Y
(abs) Absolute indirect JMP ($0318)
(abs,X) Absolute indexed indirect JMP ($1000,X)
rel 8-bit relative BNE loop
rel16 16-bit relative LBNE far

In the opcode columns, two-byte sequences such as $EA $72 are prefixed instructions: the prefix byte comes first, then the opcode and its operand.

Flags

The flags column lists the flags an instruction can change, using N, V, E, B, D, I, Z and C as in Chapter 7. A dash means no flags are affected. The flags column refers to the Z flag, never the Z register.

Origin

Code Processor
6502 Original NMOS 6502
C02 65C02 family (65SC02)
R Rockwell 65C02 bit instructions
CE CSG 65CE02
4510 CSG 4510 (C65)
GS 45GS02 (MEGA65)

Assemblers do not all use the same mnemonics for the newer instructions. Long branches may be written LBNE or chosen automatically from BNE; quad instructions may be written ADCQ (cc65 and the MEGA65 Book) or ADQ (64tass); and bit instructions may be written RMB3 $10 or RMB 3,$10. This chapter uses the forms most common in MEGA65 documentation.

ADC to BVS

Mnemonic Operation Flags Modes and opcodes Origin
ADC A = A + M + C N V Z C imm $69 · bp $65 · bp,X $75 · abs $6D · abs,X $7D · abs,Y $79 · (bp,X) $61 · (bp),Y $71 · (bp),Z $72 · [bp],Z $EA $72 6502; (bp),Z CE; [bp],Z GS
AND A = A AND M N Z imm $29 · bp $25 · bp,X $35 · abs $2D · abs,X $3D · abs,Y $39 · (bp,X) $21 · (bp),Y $31 · (bp),Z $32 · [bp],Z $EA $32 6502; (bp),Z CE; [bp],Z GS
ASL Shift left; bit 7 to C N Z C A $0A · bp $06 · bp,X $16 · abs $0E · abs,X $1E 6502
ASR Arithmetic shift right; bit 7 kept, bit 0 to C N Z C A $43 · bp $44 · bp,X $54 CE
ASW Shift 16-bit word left; bit 15 to C N Z C abs $CB CE
BBR0-7 Branch if bit n of a base page byte is clear - BBR0 $0F · BBR1 $1F · BBR2 $2F · BBR3 $3F · BBR4 $4F · BBR5 $5F · BBR6 $6F · BBR7 $7F R
BBS0-7 Branch if bit n of a base page byte is set - BBS0 $8F · BBS1 $9F · BBS2 $AF · BBS3 $BF · BBS4 $CF · BBS5 $DF · BBS6 $EF · BBS7 $FF R
BCC Branch if C = 0 - rel $90 · rel16 $93 6502; rel16 CE
BCS Branch if C = 1 - rel $B0 · rel16 $B3 6502; rel16 CE
BEQ Branch if Z = 1 - rel $F0 · rel16 $F3 6502; rel16 CE
BIT Test A AND M; N and V from M N V Z imm $89 · bp $24 · bp,X $34 · abs $2C · abs,X $3C 6502; imm, indexed C02
BMI Branch if N = 1 - rel $30 · rel16 $33 6502; rel16 CE
BNE Branch if Z = 0 - rel $D0 · rel16 $D3 6502; rel16 CE
BPL Branch if N = 0 - rel $10 · rel16 $13 6502; rel16 CE
BRA Branch always - rel $80 · rel16 $83 C02; rel16 CE
BRK Software interrupt through $FFFE I impl $00 6502
BSR Call subroutine at a 16-bit relative offset - rel16 $63 CE
BVC Branch if V = 0 - rel $50 · rel16 $53 6502; rel16 CE
BVS Branch if V = 1 - rel $70 · rel16 $73 6502; rel16 CE

Notes

ADC and SBC honour the D flag, working in binary-coded decimal when it is set. Clear D with CLD at the start of any program that does not set it deliberately.

BBR and BBS take two operands: the base page address to test and an 8-bit relative branch target, as in BBS3 $10,done. They are three-byte instructions.

BIT immediate sets Z from A AND the operand, and, unlike the 65C02, also copies bits 7 and 6 of the operand into N and V, just as the memory modes do (MEGA65 Book, BIT instruction entry; mega65-core, gs4510.vhdl, September 2026).

BSR is written LBSR in cc65 (cc65 CPU reference); the MEGA65 Book writes BSR.

BRK sets I. The CPU has no stored B flag: bit 4 is set only in the copy of P that BRK pushes, so a handler tells BRK from IRQ by testing that copy on the stack (mega65-core, gs4510.vhdl, September 2026).

BRK is followed by a padding byte that the CPU skips on return, as on the 6502. The return address pushed is that of BRK plus two.

BSR pushes the return address like JSR, so a subroutine called with BSR returns with RTS or RTN. Because the target is relative, code built with BSR can run at any address without relocation.

CLC to EOR

Mnemonic Operation Flags Modes and opcodes Origin
CLC C = 0 C impl $18 6502
CLD D = 0: binary arithmetic D impl $D8 6502
CLE E = 0: enable 16-bit stack pointer E impl $02 CE
CLI I = 0: allow IRQ I impl $58 6502
CLV V = 0 V impl $B8 6502
CMP Compare A with M N Z C imm $C9 · bp $C5 · bp,X $D5 · abs $CD · abs,X $DD · abs,Y $D9 · (bp,X) $C1 · (bp),Y $D1 · (bp),Z $D2 · [bp],Z $EA $D2 6502; (bp),Z CE; [bp],Z GS
CPX Compare X with M N Z C imm $E0 · bp $E4 · abs $EC 6502
CPY Compare Y with M N Z C imm $C0 · bp $C4 · abs $CC 6502
CPZ Compare Z with M N Z C imm $C2 · bp $D4 · abs $DC CE
DEC M = M - 1, or A = A - 1 N Z A $3A · bp $C6 · bp,X $D6 · abs $CE · abs,X $DE 6502; A C02
DEW 16-bit base page word = word - 1 N Z bp $C3 CE
DEX X = X - 1 N Z impl $CA 6502
DEY Y = Y - 1 N Z impl $88 6502
DEZ Z = Z - 1 N Z impl $3B CE
EOM End of mapping sequence; otherwise no operation - impl $EA 4510
EOR A = A XOR M N Z imm $49 · bp $45 · bp,X $55 · abs $4D · abs,X $5D · abs,Y $59 · (bp,X) $41 · (bp),Y $51 · (bp),Z $52 · [bp],Z $EA $52 6502; (bp),Z CE; [bp],Z GS

Notes

CLE should be used only where the program's stack can safely grow beyond page 1. The KERNAL and BASIC expect the 8-bit stack, so cooperative routines should leave E set.

Compare instructions set C when the register is greater than or equal to the operand, treating both as unsigned, and set Z when they are equal. N reflects bit 7 of the difference.

DEW works on a 16-bit value at a base page address, low byte first. Its flags reflect the 16-bit result.

EOM is the 6502's NOP, $EA. After MAP it ends the interrupt-blocked mapping sequence. Placed before an instruction that uses (bp),Z, it acts as the flat-addressing prefix described in the last section of this chapter, so a stray NOP before such an instruction changes its meaning.

INC to PLZ

Mnemonic Operation Flags Modes and opcodes Origin
INC M = M + 1, or A = A + 1 N Z A $1A · bp $E6 · bp,X $F6 · abs $EE · abs,X $FE 6502; A C02
INW 16-bit base page word = word + 1 N Z bp $E3 CE
INX X = X + 1 N Z impl $E8 6502
INY Y = Y + 1 N Z impl $C8 6502
INZ Z = Z + 1 N Z impl $1B CE
JMP Jump - abs $4C · (abs) $6C · (abs,X) $7C 6502; (abs,X) C02
JSR Push return address and jump - abs $20 · (abs) $22 · (abs,X) $23 6502; indirect CE
LDA A = M N Z imm $A9 · bp $A5 · bp,X $B5 · abs $AD · abs,X $BD · abs,Y $B9 · (bp,X) $A1 · (bp),Y $B1 · (bp),Z $B2 · [bp],Z $EA $B2 · (d,SP),Y $E2 6502; (bp),Z and (d,SP),Y CE; [bp],Z GS
LDX X = M N Z imm $A2 · bp $A6 · bp,Y $B6 · abs $AE · abs,Y $BE 6502
LDY Y = M N Z imm $A0 · bp $A4 · bp,X $B4 · abs $AC · abs,X $BC 6502
LDZ Z = M N Z imm $A3 · abs $AB · abs,X $BB CE
LSR Shift right; 0 into bit 7, bit 0 to C N Z C A $4A · bp $46 · bp,X $56 · abs $4E · abs,X $5E 6502
MAP Set memory map from A, X, Y, Z; block interrupts until EOM - impl $5C 4510
NEG A = 0 - A N Z impl $42 CE
NOP See EOM - impl $EA 6502
ORA A = A OR M N Z imm $09 · bp $05 · bp,X $15 · abs $0D · abs,X $1D · abs,Y $19 · (bp,X) $01 · (bp),Y $11 · (bp),Z $12 · [bp],Z $EA $12 6502; (bp),Z CE; [bp],Z GS
PHA Push A - impl $48 6502
PHP Push P - impl $08 6502
PHW Push a 16-bit value, low byte first - imm16 $F4 · abs $FC CE
PHX Push X - impl $DA C02
PHY Push Y - impl $5A C02
PHZ Push Z - impl $DB CE
PLA Pull A N Z impl $68 6502
PLP Pull P N V D I Z C impl $28 6502
PLX Pull X N Z impl $FA C02
PLY Pull Y N Z impl $7A C02
PLZ Pull Z N Z impl $FB CE

Notes

PLP and RTI restore N, V, D, I, Z and C from the stack, but never E: only CLE and SEE change the stack mode (MEGA65 Book, PLP and RTI instruction entries; mega65-core, gs4510.vhdl, September 2026).

INW increments a 16-bit value at a base page address, low byte first. It is the 45GS02's most common way to advance a pointer.

JMP (abs) with a vector at an address ending in $FF behaves differently on the NMOS 6502, which fetches the high byte from the start of the same page. Avoid placing vectors at $xxFF, and code will behave the same on every member of the family.

JSR (abs,X) calls through a table of 16-bit addresses. With X holding twice a command number, it dispatches commands in one instruction.

LDZ has no base page modes. To load Z from base page, use LDA and TAZ.

MAP reads its arguments from all four registers; see Chapters 5 and 8. It also gives the megabyte selector when X or Z holds $0F.

PHW pushes the low byte first, so the high byte ends up at the lower stack address. That is the reverse of how JSR leaves a return address, and it means a word pushed with PHW is not a ready-made little-endian pointer for stack-relative addressing (mega65-core, gs4510.vhdl, September 2026; Xemu, cpu65.c). PHW abs pushes the 16-bit contents of the address, not the address itself.

RMB to STZ

Mnemonic Operation Flags Modes and opcodes Origin
RMB0-7 Clear bit n of a base page byte - RMB0 $07 · RMB1 $17 · RMB2 $27 · RMB3 $37 · RMB4 $47 · RMB5 $57 · RMB6 $67 · RMB7 $77 R
ROL Rotate left through C N Z C A $2A · bp $26 · bp,X $36 · abs $2E · abs,X $3E 6502
ROR Rotate right through C N Z C A $6A · bp $66 · bp,X $76 · abs $6E · abs,X $7E 6502
ROW Rotate 16-bit word left through C N Z C abs $EB CE
RTI Pull P and PC; return from interrupt N V D I Z C impl $40 6502
RTN Return from subroutine, then drop n bytes from the stack - imm $62 CE
RTS Pull PC; return from subroutine - impl $60 6502
SBC A = A - M - (1 - C) N V Z C imm $E9 · bp $E5 · bp,X $F5 · abs $ED · abs,X $FD · abs,Y $F9 · (bp,X) $E1 · (bp),Y $F1 · (bp),Z $F2 · [bp],Z $EA $F2 6502; (bp),Z CE; [bp],Z GS
SEC C = 1 C impl $38 6502
SED D = 1: decimal arithmetic D impl $F8 6502
SEE E = 1: 8-bit stack pointer E impl $03 CE
SEI I = 1: block IRQ I impl $78 6502
SMB0-7 Set bit n of a base page byte - SMB0 $87 · SMB1 $97 · SMB2 $A7 · SMB3 $B7 · SMB4 $C7 · SMB5 $D7 · SMB6 $E7 · SMB7 $F7 R
STA M = A - bp $85 · bp,X $95 · abs $8D · abs,X $9D · abs,Y $99 · (bp,X) $81 · (bp),Y $91 · (bp),Z $92 · [bp],Z $EA $92 · (d,SP),Y $82 6502; (bp),Z and (d,SP),Y CE; [bp],Z GS
STX M = X - bp $86 · bp,Y $96 · abs $8E · abs,Y $9B 6502; abs,Y CE
STY M = Y - bp $84 · bp,X $94 · abs $8C · abs,X $8B 6502; abs,X CE
STZ M = Z register - bp $64 · bp,X $74 · abs $9C · abs,X $9E CE (65C02 opcodes, new meaning)

Notes

RMB and SMB are two-byte instructions that change one bit without affecting the others or the flags. They are ideal for flag bytes shared between a main program and an interrupt handler, since each is a single uninterruptible instruction.

RTN #n pops the return address as RTS does, then discards n further bytes, cleaning up parameters the caller pushed before the call. It works only on core 0.97 and later; on earlier cores it fails, usually crashing the program (mega65-core PR #791).

SBC needs C set before a subtraction without borrow, as on the 6502.

STX abs,Y and STY abs,X fill gaps in the 6502's instruction set, which had only base page forms of indexed STX and STY.

STZ uses the same opcodes as the 65C02's "store zero" but stores the Z register. While Z is zero the result is identical; once a program uses Z for anything else, 65C02 code that relies on STZ to clear memory breaks. See Chapter 7.

TAB to TZA

Mnemonic Operation Flags Modes and opcodes Origin
TAB B = A: move the base page - impl $5B CE
TAX X = A N Z impl $AA 6502
TAY Y = A N Z impl $A8 6502
TAZ Z = A N Z impl $4B CE
TBA A = B N Z impl $7B CE
TRB M = M AND NOT A; Z from A AND M Z bp $14 · abs $1C C02
TSB M = M OR A; Z from A AND M Z bp $04 · abs $0C C02
TSX X = low byte of SP N Z impl $BA 6502
TSY Y = high byte of SP N Z impl $0B CE
TXA A = X N Z impl $8A 6502
TXS Low byte of SP = X - impl $9A 6502
TYA A = Y N Z impl $98 6502
TYS High byte of SP = Y - impl $2B CE
TZA A = Z N Z impl $6B CE

Notes

TAB takes effect immediately: the very next base page instruction uses the new page. Set B back to zero before calling the KERNAL or returning to BASIC.

TRB and TSB set or clear, in memory, the bits that are set in A, and set the Z flag from the bits that were already common to both. They are the natural way to change single bits of hardware registers, such as LDA #$40 : TSB $D031, and they leave A unchanged.

TSY and TYS reach the high byte of the stack pointer. With E set, the stack is 8 bits wide and wraps within a single 256-byte page, the page given by the high byte; it is page 1 after reset, and TYS can move it elsewhere. With E clear, the stack pointer is a full 16-bit value.

TXS sets only the low byte of SP. With the 16-bit stack enabled, set the high byte with TYS as well.

The Quad Instructions

The quad instructions operate on the 32-bit Q register, formed from A (bits 7-0), X (15-8), Y (23-16) and Z (31-24). Each is an ordinary 8-bit instruction preceded by the prefix $42 $42; the opcodes below give the full sequence. Flat indirect forms add the $EA prefix after it.

Mnemonic Operation Flags Modes and opcodes
ADCQ Q = Q + M + C N V Z C bp $42 $42 $65 · abs $42 $42 $6D · (bp) $42 $42 $72 · [bp] $42 $42 $EA $72
ANDQ Q = Q AND M N Z bp $42 $42 $25 · abs $42 $42 $2D · (bp) $42 $42 $32 · [bp] $42 $42 $EA $32
ASLQ Shift Q or M left N Z C Q $42 $42 $0A · bp $42 $42 $06 · bp,X $42 $42 $16 · abs $42 $42 $0E · abs,X $42 $42 $1E
ASRQ Arithmetic shift right N Z C Q $42 $42 $43 · bp $42 $42 $44 · bp,X $42 $42 $54
BITQ Test Q AND M N V Z bp $42 $42 $24 · abs $42 $42 $2C
CMPQ Compare Q with M N Z C bp $42 $42 $C5 · abs $42 $42 $CD · (bp) $42 $42 $D2 · [bp] $42 $42 $EA $D2
DEQ Q or M = value - 1 N Z Q $42 $42 $3A · bp $42 $42 $C6 · bp,X $42 $42 $D6 · abs $42 $42 $CE · abs,X $42 $42 $DE
EORQ Q = Q XOR M N Z bp $42 $42 $45 · abs $42 $42 $4D · (bp) $42 $42 $52 · [bp] $42 $42 $EA $52
INQ Q or M = value + 1 N Z Q $42 $42 $1A · bp $42 $42 $E6 · bp,X $42 $42 $F6 · abs $42 $42 $EE · abs,X $42 $42 $FE
LDQ Q = M N Z bp $42 $42 $A5 · abs $42 $42 $AD · (bp),Z $42 $42 $B2 · [bp],Z $42 $42 $EA $B2
LSRQ Shift Q or M right N Z C Q $42 $42 $4A · bp $42 $42 $46 · bp,X $42 $42 $56 · abs $42 $42 $4E · abs,X $42 $42 $5E
ORQ Q = Q OR M N Z bp $42 $42 $05 · abs $42 $42 $0D · (bp) $42 $42 $12 · [bp] $42 $42 $EA $12
ROLQ Rotate Q or M left through C N Z C Q $42 $42 $2A · bp $42 $42 $26 · bp,X $42 $42 $36 · abs $42 $42 $2E · abs,X $42 $42 $3E
RORQ Rotate Q or M right through C N Z C Q $42 $42 $6A · bp $42 $42 $66 · bp,X $42 $42 $76 · abs $42 $42 $6E · abs,X $42 $42 $7E
SBCQ Q = Q - M - (1 - C) N V Z C bp $42 $42 $E5 · abs $42 $42 $ED · (bp) $42 $42 $F2 · [bp] $42 $42 $EA $F2
STQ M = Q N Z (from A) bp $42 $42 $85 · abs $42 $42 $8D · (bp) $42 $42 $92 · [bp] $42 $42 $EA $92

The mode list follows the cc65 assembler's 45GS02 table. Other assemblers name some of these differently: 64tass, for example, writes ADQ and LDQ as forms of its own mnemonics, and treats INQ and DEQ as implied-only, using other names for the memory forms. Check your assembler's documentation for the spelling it expects.

Notes

STQ changes flags. Unlike STA, STQ is not flag-neutral. The CPU executes the $42 $42 prefix as two NEG instructions before the store: A ends up unchanged, but N and Z are set from it (MEGA65 Book, STQ instruction entry). Don't rely on flags from an earlier instruction surviving an STQ. The other quad instructions set N and Z from their own results, so the prefix makes no difference to them.

Indirect quad modes are written (bp) and [bp] for every instruction except LDQ, which cc65 writes (bp),Z and [bp],Z. Because Z is part of Q, the other indirect quad instructions do not add Z to the pointer at all; only LDQ does, which is why cc65 writes its modes with ,Z. Set Z to zero before an indirect LDQ (mega65-core, gs4510.vhdl, September 2026).

Flags reflect the whole 32-bit result: N is bit 31, and Z is set only if all 32 bits are zero.

Every quad instruction that changes Q changes A, X, Y and Z. Save any of them that hold values you still need.

Prefixes and Encoding Notes

The 45GS02 adds its extensions without new opcodes. Instead it gives special meaning to sequences of existing one-byte instructions placed in front of an ordinary instruction.

Prefix Bytes Effect on the following instruction
NOP (EOM) $EA A (bp),Z instruction uses a 32-bit pointer: flat [bp],Z addressing
NEG NEG $42 $42 The instruction operates on Q instead of A
NEG NEG NOP $42 $42 $EA Both: a quad instruction with flat addressing

NEG and NOP were chosen because they are single-cycle instructions on the C65's CPU, and the 65CE02 does not take an interrupt immediately after a one-cycle instruction. An interrupt therefore cannot arrive between a prefix and the instruction it modifies (Xemu issue #202).

Consequences for programmers

Disassembly. A disassembler that does not know the 45GS02 shows prefixes as separate NEG and NOP instructions. Reading NEG, NEG, LDA $10 as three instructions gives the wrong meaning: it is a single LDQ $10.

Self-modifying code. Code that patches an instruction must patch the whole prefixed sequence, and branch targets must point at the first prefix byte, not into the middle of the sequence.

Unintended prefixes. A NOP placed for timing or padding immediately before a (bp),Z instruction turns it into a flat access, and a NEG of A immediately followed by another NEG creates a quad prefix. Place padding NOPs elsewhere, and do not negate A twice in a row.

Differences from the 65C02

Code written for the 65C02 mostly runs unchanged, but five differences can catch it out:

Opcode 65C02 45GS02
$64 $74 $9C $9E STZ: store zero STZ: store the Z register
$12 $32 $52 $72 $92 $B2 $D2 $F2 (zp) indirect (bp),Z: the same while Z is zero
$89 BIT immediate: sets only Z BIT immediate: also sets N and V from the operand
$CB WAI on WDC parts ASW abs
$DB STP on WDC parts PHZ

With Z held at zero, the first two differences disappear. The third matters to 65C02 code that tests N or V after a BIT immediate. The last two matter only for code written for WDC's 65C02 variant, which the MEGA65 has never needed to run.