Introduction
These instructions change the program counter. A jump or call holds a 16-bit address. A
branch holds a signed 8-bit displacement counted from the end of the instruction, so it
reaches 128 bytes back and 127 forward: D0 FE at $1000 is a branch
to $1000 + 2 − 2, itself. The disassembler shows the target address, and in the
explorer selecting a branch offers to go to its target, which may be in the middle of another
instruction.
Jumps, calls and returns
| Instruction | Forms | What it does | Flags |
|---|---|---|---|
jmp | abs 4C, 3, 3(abs) 6C, 3, 5 (6 on the 65C02)(abs,X) 7C, 3, 6 (65C02) | Jumps. The indirect form reads the target address from the two bytes at the given address.
NMOS bug: a pointer at $xxFF takes its high byte from $xx00, not from the next page, so jmp ($10FF) reads $10FF and $1000. The 65C02 fixed this. | – |
jsr | abs 20, 3, 6 | Calls a subroutine: pushes the address of its last byte (the return address minus one), high byte first, then jumps. | – |
rts | implied 60, 1, 6 | Returns: pulls the address and adds one to it. | – |
rti | implied 40, 1, 6 | Returns from an interrupt: pulls P (bits 4 and 5 ignored), then the return address, which is used as it is (no plus one). | all of N V D I Z C |
brk | implied 00, 1, 7 | A software interrupt. It pushes PC + 2 (so it skips one byte after the BRK, a “signature” byte), then P with the B flag set, sets I and jumps through the vector at $FFFE. The 65C02 also clears D. | I |
Conditional branches
Every branch is 2 bytes and takes 2 cycles when not taken, 3 when taken, and 4 when taken to another page. It changes no flags.
| Instruction | Opcode | Branches when |
|---|---|---|
bpl | 10 | N = 0: the last result was positive or zero |
bmi | 30 | N = 1: negative |
bvc | 50 | V = 0: no overflow |
bvs | 70 | V = 1: overflow |
bcc | 90 | C = 0: carry clear (below, after CMP) |
bcs | B0 | C = 1: carry set (above or equal, after CMP) |
bne | D0 | Z = 0: not equal |
beq | F0 | Z = 1: equal |
The 65C02 adds BRA (branch always) and the BBR and BBS bit-test branches.
Interrupts and the vectors
An interrupt pushes the return address and P (with B clear), sets I and jumps through a vector at the top of memory. It takes 7 cycles.
| Address | Vector | Taken when |
|---|---|---|
$FFFA–$FFFB | NMI | The non-maskable interrupt pin goes low (a falling edge). I does not stop it. |
$FFFC–$FFFD | RESET | The chip is reset: it takes the start address from here (no push). |
$FFFE–$FFFF | IRQ and BRK | The IRQ pin is low and I is clear, or a BRK is executed. The handler tells them apart by the B flag in the pushed P. |