Skip to content
Michiel van Oosterhout edited this page Feb 4, 2015 · 3 revisions

The Super Nintendo CPU (S-CPU) is a Ricoh 5A22 processor, which is based on a WDC 65816 core. A 65816 processor can operate in 2 modes: native mode and emulation mode. In emulation mode a 65816 processor emulates a 6502 processor. A 65816 starts in emulation mode, and can be switched to native mode by executing the clc instruction to set the carry flag to 0, followed by the xce instruction to exchange the carry flag with the emulation flag.

This document assumes native mode operation of the S-CPU.

General

The S-CPU has 24 address lines and with a 24-bit address space it can address 16MiB. A 24-bit address consists of an 8-bit bank selector and a 16-bit address, giving 256 banks of 64KiB each. Each bank has 256 pages of 256 bytes. The first page of the first bank is the zero page.

Registers

The S-CPU has the following built-in registers:

  • 1 status register: Processor Status
  • 3 general purpose registers: Accumulator, X Index and Y Index
  • 2 registers to assist addressing: Direct and Data Bank
  • 3 registers for program control: Program Counter, Program Bank and Stack Pointer

Processor Status (P)

Contains status flags for ALU operations and mode select bits. The status flags c, z, v, and n, are tested by conditional branch instructions. P(e) is a hidden bit, its value can be swapped with the P(c) bit using the xce instruction.

_: e Emulation mode select
0: c Carry status flag
1: z Zero status flag
2: i IRQ disabled mode select
3: d Decimal mode select
4: x Index 8-bit mode select
5: m Memory/Accumulator 8-bit mode select
6: v Overflow status flag (for signed arithmetic)
7: n Negative status flag (for unsiged arithmetic)

Status flags initialization:

  • P(i)=1 after reset
  • P(d)=0 after reset (binary mode)
  • P(x)=1 after reset and after switching to native mode
  • P(m)=1 after reset and after switching to native mode

In 16-bit mode certain instructions can take a 16-bit operands, e.g. lda $1234 or sta $1234. These instructions will map the low order byte of the register to the effective address, and the register's high order byte to the effective address + 1.

In 16-bit mode, when executing push or pull instructions, the high order byte is pushed first, followed by the low order byte, and the low order byte is pulled first, followed by the high order byte. (This seems like the reverse compared to e.g. lda, but the stack grows downwards, so values are consistently stored in memory.)

Accumulator (A,B) (C)

General purpose register, stores one of the operands or the result of the arithmetic and logic unit (ALU).

In 8-bit mode the low order byte is designated A, and the high order byte is designated B, but not directly accessible. The low order A and high order B bytes can be exchanged using the xba instruction, or A and B can be tranferred to a 16-bit index register (B becomes the high order byte). In 16-bit mode the 16-bit register is designated C.

When switching between 8-bit and 16-bit mode the high order byte is retained.

sep #%00010000 ;  8-bit mode, sets P(m) to 1
rep #%00010000 ; 16-bit mode, resets P(m)

X/Y Index (X) (Y)

General purpose register, also used in indexed addressing modes to calculate an effective address by adding the index value to the address prior to performing the operation.

When switching to 8-bit mode the high order byte is lost, switching back to 16-bit mode sets it to zero.

sep #%00001000 ;  8-bit mode, sets P(x) to 1
rep #%00001000 ; 16-bit mode, resets P(x)

Stack Pointer (S) [16-bit]

Location of the next available location on the stack. The stack is always in bank 0, but is relocatable and not restricted to 256 bytes.

Initialized to $0100 during reset.

Direct (D) [16-bit]

Start of 'page zero' in bank 0. Used as an offset for direct addressing mode instructions. Can be any value, but it is preferred to keep the low order byte at zero, to align with 256 byte page boundaries, e.g. $3F00 or $4000. D can be set using the tcd instruction, to tranfer the value from C to D, or using the pld instruction, to pull the value off the stack.

A direct page address combined with an index that crosses the page boundary will roll into the next page (no wrap-around).

Initialized to zero during reset.

Data Bank (DB) [8-bit]

The default bank address or 'bank byte' for memory transfers. Combined as the highest order byte with the 16-bit effective instruction address to form a 24-bit address used for storing and retrieving data. DB is incremented automatically for indexed addressing that crosses a bank boundary, en automatically decremented afterwards.

Initialized to zero during reset.

Program Counter (PC) [16-bit]

Pointer to next instruction in memory (combined with the PB). PC is incremented after each instruction or operand fetch. Program segments cannot cross the boundary of a bank, because at $FFFF the program counter will reset to $0000.

Program Bank (PB) [8-bit]

The bank address for fetching instructions ('bank byte' for the PC). The highest order byte of 24-bit addresses used in jump instructions. Relative branch instructions do not use the PB and when crossing the $FFFF boundary will loop around to $0000.

Initialized to zero after reset.

Interrupts

When a hardware interrupt (reset, NMI, IRQ, or abort) or software interrupt (break or co-processor instruction) occurs, the S-CPU must first perform a sequence of operations to allow for rti. This sequence causes some interrupt latency. The S-CPU can be set to wait for an IRQ using the wai instruction. In this state it will continue with the next instruction when an IRQ occurs.

Interrupt vector table

To handle an interrupt a pointer to the address of the interrupt handler (in bank 0) must be set in the interrupt vector table, according to the table below:

Address Interrupt
$FFE4 COP
$FFE6 BRK
$FFE8 Abort
$FFEA NMI
$FFEE IRQ
$FFFC Reset

After a reset or powerup P is set to %00110100 (emulation mode, binary mode, 8-bit mode for A and X/Y), and S is initialized to %00010000 (stack at $0100).

Addressing modes

The S-CPU supports 25 addressing modes, consisting of (combinations of) general modes which determine how the effective address for the instruction is established.

Indexed ,x/,y: the value of X or Y is added to the operand (operand,x), or, when combined with indirect mode, it is added to the operand before fetching an address from memory (pre-indexing (operand,x)), or after an address was fetched from memory (postindexing (operand),x).

Indirect ()/[]: the base or effective address is fetched from memory using a pointer (based on the operand, optionally combined with D and/or X/Y, shown as <...> in the table below).

Direct: in direct mode D is used as an offset for the 8-bit operand and bank zero is default, unless direct mode is combined with indirect mode, in which case DB is used (unless combined with long mode).

Absolute: DB is used as an offset for a 16-bit operand, or the instruction uses a 24-bit operand.

24-bit Code Addressing mode Example Effective address (or constant value)
A Accumulator dec a (accumulator)
i Implied clc (implied)
# Immediate sep #$12 operand
Immediate, accumulator inc #$12 operand
Immediate, accumulator (16-bit) lda #$1234 operand
Immediate, index ldx #$12 operand
Immediate, index (16-bit) ldy #$1234 operand
* a Absolute and $1234 DB:operand
* al Absolute long and $123456 operand
* al,x Absolute long indexed and $123456,x operand + X
* a,x Absolute indexed with X and $1234,x DB:(operand + X)
* a,y Absolute indexed with Y and $1234,y DB:(operand + Y)
(a,x) Absolute indexed indirect jmp ($1234,x) PC = <00:(operand + X)>
(a) Absolute indirect jmp ($1234) PC = <00:operand>
(al) Absolute indirect long jml [$1234] PC,PB = <00:operand>,<00:(operand + 2)>
d Direct and $12 00:(D + operand)
d,x Direct indexed with X stz $12,x 00:(D + operand + X)
d,y Direct indexed with Y stx $12,y 00:(D + operand + X)
* (d,x) Direct indexed indirect and ($12,x) DB:<(D + operand + X>
* (d) Direct indirect and ($12) DB:<00:operand>
* [d] Direct indirect long and [$12] <00:operand>
* (d),y Direct indirect indexed and ($12),y (DB:<00:(D + operand)>) + Y
* [d],y Direct indirect long indexed and [$12],y <00:(D + operand)> + Y
r Program Counter relative beq $12 PC + operand (signed 8-bit value)
rl Program Counter relative long brl $1234 PC + operand (signed 16-bit value)
s Stack rts
d,s Stack relative and $12,s 00:(S + operand)
* (d,s),y Stack relative indirect indexed and ($12,s),y (DB:<00:(S + operand)>) + Y
xya Block move mvp $12,$34

*) 24-bit effective address mode

--