Introduction
The program counter is 16 bits inside the 8-bit program bank register. The ordinary jumps,
calls and branches stay in the bank; the long forms (jml, jsl,
rtl) change the bank too. Branch offsets are relative to the next instruction and
wrap inside the bank. A subroutine entered with jsr must return with
rts and one entered with jsl with rtl: the two push
different numbers of bytes. A target is shown with its 24-bit address in the disassembly.
The instructions
Each form is written mode opcode, bytes, cycles, then the cycle tags.
| Instruction | Forms | What it does | Flags |
|---|---|---|---|
jmp | abs 4C, 3, 3(abs) 6C, 3, 5(abs,X) 7C, 3, 6 | Jump within the program bank. jmp (abs) reads its pointer from bank 0; jmp (abs,X) reads it from the program bank. | – |
jml | long 5C, 4, 4[abs] DC, 3, 6 | Jump to a 24-bit address, changing the program bank. jml [abs] reads a 3-byte pointer from bank 0. Assemblers also write these as jmp with a long or bracketed operand. | – |
jsr | abs 20, 3, 6(abs,X) FC, 3, 8 | Push the address of the last byte of the instruction (2 bytes) and jump within the bank. Return with rts. | – |
jsl | long 22, 4, 8 | Push the program bank and then the address of the last byte (3 bytes) and jump to the 24-bit address. Return with rtl. Also written jsr with a long operand. | – |
rts | imp 60, 1, 6 | Pull 2 bytes, add one and continue there, in the same bank. | – |
rtl | imp 6B, 1, 6 | Pull 3 bytes: the address plus one and the program bank. | – |
rti | imp 40, 1, 7 (6 in emulation mode) | Return from an interrupt: pull P, then PC, then (in native mode only) the program bank. M and X come from the pulled P, and setting X clears the high bytes of X and Y. | N V M X D I Z C |
brk | imm8 00, 2, 8 (7 in emulation mode) | Software interrupt. The second byte is a signature the processor skips, so the return address is two bytes after the opcode. Pushes the program bank (native only), PC and P, clears D, sets I and goes through the BRK vector (the IRQ vector in emulation mode, with the B bit of the pushed P set). Written brk #$00 in the disassembly. | I D |
cop | imm8 02, 2, 8 (7 in emulation mode) | Co-processor enable: like BRK, through the COP vector. A program uses the signature byte to say which service it wants. | I D |
bpl | rel 10, 2, 2 +T +E | Branch if N is clear. | – |
bmi | rel 30, 2, 2 +T +E | Branch if N is set. | – |
bvc | rel 50, 2, 2 +T +E | Branch if V is clear. | – |
bvs | rel 70, 2, 2 +T +E | Branch if V is set. | – |
bcc | rel 90, 2, 2 +T +E | Branch if C is clear (also written blt). | – |
bcs | rel B0, 2, 2 +T +E | Branch if C is set (also written bge). | – |
bne | rel D0, 2, 2 +T +E | Branch if Z is clear. | – |
beq | rel F0, 2, 2 +T +E | Branch if Z is set. | – |
bra | rel 80, 2, 3 +E | Branch always (a signed 8-bit offset). | – |
brl | rel long 82, 3, 4 | Branch always with a signed 16-bit offset: reaches anywhere in the program bank. | – |
Not described
Known, not yet covered
- Reference: the ABORT interrupt (a pin of the W65C816S; the Super Nintendo does not use it) and the interaction of WAI with interrupts, as on the overview.
- Viewer: the disassembly names the target of
jsr (abs,X)andjmp (abs)only by the pointer’s address, not by what is in the table.
Links
Reference
- 65816 reference – the Super Famicom Development Wiki’s instruction table
- CPU vectors – the SNESdev wiki: the vector addresses
- W65C816S data sheet – Western Design Center