Registers
| Register | Size | What it holds |
|---|---|---|
A (or C) | 8 or 16 bits | The accumulator. It is always 16 bits in the register; M decides whether instructions use all of it or only the low byte (the high byte, called B, is kept and XBA swaps it with the low byte). TCD, TCS and TDC, TSC use all 16 bits whatever M says. |
X, Y | 8 or 16 bits | Index registers. X decides their width; when X is set the high bytes are zero. |
S | 16 bits | The stack pointer, anywhere in bank 0 in native mode; in emulation mode its high byte is fixed at 1 (page one, as on the 6502). |
D | 16 bits | The direct page register: where the “zero page” is. Direct page operands are added to it, so the direct page can be any 256 bytes (or more: its address wraps in bank 0) in bank 0. |
DB (or DBR) | 8 bits | The data bank register: the bank that 16-bit absolute operands (and indirect pointers) address. |
PB (or PBR, K) | 8 bits | The program bank register: the bank the program counter runs in. Only long jumps and calls, returns that pull it, and interrupts change it. |
PC | 16 bits | The program counter inside the program bank; it wraps at the end of the bank. |
P | 8 bits | The status register, below. |
E | 1 bit | The emulation flag, a hidden bit exchanged with carry by XCE. |
The status register
The status register P, from bit 7 to bit 0. The mask of REP and SEP uses these bit numbers.
| Bit | Flag | Name | Meaning |
|---|---|---|---|
| 7 | N | Negative | A copy of the top bit of the last result (bit 7, or bit 15 for a 16-bit result). |
| 6 | V | Overflow | Signed overflow of ADC and SBC; BIT copies the top bits of the memory operand into N and V (not with an immediate operand). |
| 5 | M | Accumulator and memory width | Set: 8-bit accumulator and memory operands. Clear: 16-bit. In emulation mode this bit is unused and the width is always 8 bits; the M and X flags says what depends on it. |
| 4 | X | Index register width | Set: 8-bit X and Y. Clear: 16-bit. In emulation mode this bit is the B (break) flag in the copy of P that is pushed on the stack, and the width is always 8 bits. |
| 3 | D | Decimal | When set, ADC and SBC work in binary-coded decimal. |
| 2 | I | Interrupt disable | When set, the IRQ is ignored; the NMI is not. |
| 1 | Z | Zero | Set when the last result was zero. |
| 0 | C | Carry | The carry out of the last addition or shift; the inverse of the borrow in subtraction and comparison. XCE exchanges it with E. |
Emulation mode and native mode
The processor has two modes, set by the hidden E flag. A reset puts it in emulation
mode, where it behaves like a 65C02: M and X are forced to 1, the stack is in page
one, and the interrupt vectors are the 6502’s. A program that wants the 65816 enters
native mode with clc then xce. It goes back with
sec then xce.
| Thing | Emulation mode (E = 1) | Native mode (E = 0) |
|---|---|---|
| M and X | Both 1 and cannot be changed; 8-bit registers | Set or cleared by REP, SEP and PLP; after XCE into native mode both are 1 |
| X and Y high bytes | Always zero | Zero while X is set; setting X (SEP, PLP, RTI) clears them |
| Stack pointer | High byte forced to 1: the stack is page one | Any 16-bit address in bank 0 |
| Interrupt pushes | PC (2 bytes) and P (1 byte); the pushed P has bit 4 set for BRK | PB, PC and P (4 bytes) |
| RTI | Pulls P and PC (3 bytes) | Pulls P, PC and PB (4 bytes) |
| Vectors | $FFF4–$FFFF; BRK shares the IRQ vector | $FFE4–$FFEF; BRK has its own |
| Branch timing | A taken branch that crosses a page takes one more cycle | No such penalty |
| BRK and COP timing | 7 cycles | 8 cycles |
| RTI timing | 6 cycles | 7 cycles |
| Direct page | When the low byte of D is zero, direct page modes wrap within the page as on the 65C02 | The direct page address plus the operand is a 16-bit address in bank 0 |
The rest of the instruction set works in both modes and the bank registers keep working in emulation mode: DB and PB are not cleared by XCE, and long addresses still reach 16 MB.
Switching modes
clcxce: enter native mode. M and X are 1 (8 bits) until arepclears them; the usual next instruction isrep #$30for 16-bit registers.secxce: enter emulation mode. M and X become 1, the high bytes of X and Y are cleared and the stack pointer’s high byte becomes 1.- A reset enters emulation mode with the interrupt flag set and the decimal flag clear. The SNES’s reset code therefore starts with 8-bit M and X.
The explorer’s disassembler starts in emulation mode, as the reset does, and follows
clc xce and rep as it goes: the M and X flags.
Not described
Known, not yet covered
- Reference: the exact order of the pushes and the bus cycles of an interrupt, and the pins (VPB, MLB, VDA, VPA, RDY, ABORT) of the W65C816S.
Unknown
- Reference: how the direct page wraps for the indexed and indirect modes in emulation mode when the low byte of D is not zero, on real hardware; the explorer’s checks do not execute instructions with an address that wraps the page.
Links
Reference
- 65816 reference – the Super Famicom Development Wiki’s registers, flags and instructions
- W65C816S data sheet – Western Design Center’s data sheet, the programming model and the emulation-mode differences