Introduction
An instruction is one opcode byte followed by none, one or two operand bytes, so it is 1, 2 or 3 bytes long. The opcode fixes both the operation and the addressing mode: how the operand bytes are turned into the address of the byte to work on. The same mnemonic has a different opcode for each mode it supports.
Page zero, $0000–$00FF, is special: its addresses take one byte
instead of two, so an instruction on it is shorter and a cycle faster, and it is where the
indirect modes keep their pointers.
The modes
| Mode | Written | Bytes | The operand is |
|---|---|---|---|
| Implied | inx | 1 | Nothing: the instruction names its registers. |
| Accumulator | asl a | 1 | The accumulator. |
| Immediate | lda #$01 | 2 | The byte after the opcode. |
| Zero page | lda $fb | 2 | The byte at the page-zero address given. |
| Zero page,X | lda $fb,x | 2 | The byte at the given address plus X, wrapping within page zero: $FF + 2 is $01, not $101. |
| Zero page,Y | ldx $fb,y | 2 | As zero page,X with Y. Only LDX, STX and the undocumented LAX and SAX use it. |
| Absolute | lda $d020 | 3 | The byte at the 16-bit address (low byte first). |
| Absolute,X | lda $0400,x | 3 | The byte at the address plus X. A read takes one more cycle when the addition carries into the high byte (crosses a page). |
| Absolute,Y | lda $0400,y | 3 | As absolute,X with Y. |
| Indirect | jmp ($0314) | 3 | The 16-bit address stored at the given address. Only JMP uses it. On the NMOS chip a pointer at $xxFF takes its high byte from $xx00. |
| (Zero page,X): indexed indirect | lda ($fb,x) | 2 | X is added to the zero-page address (wrapping), and the 16-bit pointer there is the address of the byte. |
| (Zero page),Y: indirect indexed | lda ($fb),y | 2 | The 16-bit pointer at the zero-page address (its second byte wraps at $FF) plus Y is the address of the byte. A read takes one more cycle across a page. This is the usual way to walk through a table or a buffer. |
| Relative | bne $0810 | 2 | A signed displacement added to the address of the next instruction. Only the branches use it. The disassembler writes the target address. |
Added by the 65C02
| Mode | Written | Bytes | The operand is |
|---|---|---|---|
| (Zero page): zero page indirect | lda ($fb) | 2 | The byte at the 16-bit pointer stored at the zero-page address: indirect indexed without the index. Used by ORA, AND, EOR, ADC, STA, LDA, CMP and SBC. |
| (Absolute,X) | jmp ($1000,x) | 3 | The 16-bit address stored at the address plus X: a jump table. Only JMP uses it. |
| Zero page and relative | bbr0 $fb,$0810 | 3 | A zero-page byte to test, then a displacement as in a branch. Only BBR0–7 and BBS0–7 use it. |
The 65C02 also gives BIT immediate, zero page,X and absolute,X, and INC and DEC on the accumulator. They are on the 65C02 additions page.
Cycles
The instruction pages give each form’s base cycle count. A read through absolute,X, absolute,Y or (zero page),Y takes one more cycle when the index carries into the high byte; a store or a read-modify-write always takes the longer time, so it has no extra. A branch takes one more cycle when taken and another when its target is on a different page from the next instruction. In the explorer, the instruction detail gives these.