SPC-700 instruction set
From SNESdev Wiki
Jump to navigationJump to search
The Sony SPC-700 CPU is part of the S-SMP sound processor of the SNES. It runs at 2.048 MHz, and behaves similarly to a 6502 at 1.024 MHz with some extensions.
Architecture
The SPC-700 has a 16-bit address space, and a similar set of registers to the 6502.
Registers
- A - 8-bit accumulator
- X - 8-bit index
- Y - 8-bit index
- YA - 16-bit pair of A (lsb) and Y (msb).
- PC - program counter
- SP - stack pointer
- PSW - program status word: NVPBHIZC
- N - negative flag (high bit of result was set)
- V - overflow flag (signed overflow indication)
- P - direct page flag (moves the direct page to $0100 if set)
- H - half-carry flag (carry between low and high nibble)
- I - interrupt enable (unused: the S-SMP has no attached interrupts)
- Z - zero flag (set if last result was zero)
- C - carry flag
Addressing Modes
- imm - 8-bit immediate value
- dp - 8-bit direct page offset ($0000+dp or $01000+dp)
- !abs - 16-bit absolute address
- rel - relative offset in two's complement
- (i) - direct-page relative index (P * $100 + i)
- (i)+ - direct-page relative index with post-increment (i is incremented after read)
- [addr]+i - indirect indexed (add index after 16-bit lookup)
- [addr+i] - indexed indirect (add index before 16-bit lookup)
Differences from the 6502
- A 16-bit combined YA register is available for some operations.
- The direct page can be moved to $0100. (Rarely used.)
- A half carry flag that is useful for nibble operations, can be cleared by CLRV.
- No decimal mode, instead provides DAA and DAS instructions.
- Iterrupt status flag is enable, not disable. (Not important for SNES.)
- Some operations allow direct page as a register-like destination, e.g. MOV dp, #imm or ADC dp, dp.
- X or Y can be sometimes be used as an index to the direct page, possibly with an automatic post-increment, e.g. MOV (X)+ or ADC (X), (Y).
- Multiply and divide instructions MUL and DIV.
- Loop instructions CBNE and DBNZ.
- Abbreviated call instructions the high page of memory PCALL and TCALL.
- Memory bit operations SET1, NOT1, MOV1, etc.
Instructions
Official instruction names and syntax for SPC-700 instruction were provided by Sony. However, because of its architectural similarity to 6502, some prefer to rename and remap them using a 6502 style syntax. Both are provided here.
Sony instruction convention puts the destination on the left, source on the right (Intel syntax).
Cycles in this table are 1.024 MHz CPU cycles. Each one is equal to 2 clocks of the 2.048 Mhz S-SMP.
Instruction | 6502-Style | Opcode | Bytes | Cycles | Flags | Notes |
---|---|---|---|---|---|---|
. 8-bit move memory to register | ||||||
MOV A, #imm | LDA #imm | E8 | 2 | 2 | N.....Z. | |
MOV A, (X) | ? | E6 | 1 | 3 | N.....Z. | |
MOV A, (X)+ | ? | BF | 1 | 4 | N.....Z. | X++ after read |
MOV A, dp | LDA zp | E4 | 2 | 3 | N.....Z. | |
MOV A, dp+X | LDA zp, X | F4 | 2 | 4 | N.....Z. | |
MOV A, !abs | LDA abs | E5 | 3 | 4 | N.....Z. | |
MOV A, !abs+X | LDA abs, X | F5 | 3 | 5 | N.....Z. | |
MOV A, !abs+Y | LDA abs, Y | F6 | 3 | 5 | N.....Z. | |
MOV A, [dp+X] | LDA (zp, X) | E7 | 2 | 6 | N.....Z. | |
MOV A, [dp]+Y | LDA (dp), Y | F7 | 2 | 6 | N.....Z. | |
MOV X, #imm | LDX #imm | CD | 2 | 2 | N.....Z. | |
MOV X, dp | LDX zp | F8 | 2 | 3 | N.....Z. | |
MOV X, dp+Y | LDX zp, Y | F9 | 2 | 4 | N.....Z. | |
MOV X, !abs | LDX abs | E9 | 3 | 4 | N.....Z. | |
MOV Y, #imm | LDY #imm | 8D | 2 | 2 | N.....Z. | |
MOV Y, dp | LDY zp | EB | 2 | 3 | N.....Z. | |
MOV Y, dp+X | LDY zp, X | FB | 2 | 4 | N.....Z. | |
MOV Y, !abs | LDY abs | EC | 3 | 4 | N.....Z. | |
. 8-bit move register to memory | ||||||
MOV (X), A | ? | C6 | 1 | 4 | ........ | |
MOV (X)+, A | ? | AF | 1 | 4 | ........ | X++ after read |
MOV dp, A | STA zp | C4 | 2 | 4 | ........ | |
MOV dp+X, A | STA zp, X | D4 | 2 | 5 | ........ | |
MOV !abs, A | STA abs | C5 | 3 | 5 | ........ | |
MOV !abs+X, A | STA abs, X | D5 | 3 | 6 | ........ | |
MOV !abs+Y, A | STA abs, Y | D6 | 3 | 6 | ........ | |
MOV [dp+X], A | STA (zp, X) | C7 | 2 | 7 | ........ | |
MOV [dp]+Y, A | STA (zp), Y | D7 | 2 | 7 | ........ | |
MOV dp, X | STX zp | D8 | 2 | 4 | ........ | |
MOV dp+Y, X | STX zp, Y | D9 | 2 | 5 | ........ | |
MOV !abs, X | STX abs | C9 | 3 | 5 | ........ | |
MOV dp, Y | STY zp | CB | 2 | 4 | ........ | |
MOV dp+X, Y | STY zp, X | DB | 2 | 5 | ........ | |
MOV !abs, Y | STY abs | CC | 3 | 5 | ........ | |
. 8-bit move register to register / special direct page moves | ||||||
MOV A, X | TXA | 7D | 1 | 2 | N.....Z. | |
MOV A, Y | TYA | DD | 1 | 2 | N.....Z. | |
MOV X, A | TAX | 5D | 1 | 2 | N.....Z. | |
MOV Y, A | TAY | FD | 1 | 2 | N.....Z. | |
MOV X, SP | TSX | 9D | 1 | 2 | N.....Z. | |
MOV SP, X | TXS | BD | 1 | 2 | ........ | |
MOV dp, dp | ? | FA | 3 | 5 | ........ | |
MOV dp, #imm | ? | 8F | 3 | 5 | ........ | |
. 8-bit arithmetic | ||||||
ADC A, #imm | ADC #imm | 88 | 2 | 2 | NV..H.ZC | |
ADC A, (X) | ? | 86 | 1 | 3 | NV..H.ZC | |
ADC A, dp | ADC zp | 84 | 2 | 3 | NV..H.ZC | |
ADC A, dp+X | ADC zp, X | 94 | 2 | 4 | NV..H.ZC | |
ADC A, !abs | ADC abs | 85 | 3 | 4 | NV..H.ZC | |
ADC A, !abs+X | ADC abs, X | 95 | 3 | 5 | NV..H.ZC | |
ADC A, !abs+Y | ADC abs, Y | 96 | 3 | 5 | NV..H.ZC | |
ADC A, [dp+X] | ADC (zp, X) | 87 | 2 | 6 | NV..H.ZC | |
ADC A, [dp]+Y | ADC (dp), Y | 97 | 2 | 6 | NV..H.ZC | |
ADC (X), (Y) | ? | 99 | 1 | 5 | NV..H.ZC | |
ADC dp, dp | ? | 89 | 3 | 6 | NV..H.ZC | |
ADC dp, #imm | ? | 98 | 3 | 5 | NV..H.ZC | |
SBC A, #imm | SBC #imm | A8 | 2 | 2 | NV..H.ZC | |
SBC A, (X) | ? | A6 | 1 | 3 | NV..H.ZC | |
SBC A, dp | SBC zp | A4 | 2 | 3 | NV..H.ZC | |
SBC A, dp+X | SBC zp, X | B4 | 2 | 4 | NV..H.ZC | |
SBC A, !abs | SBC abs | A5 | 3 | 4 | NV..H.ZC | |
SBC A, !abs+X | SBC abs, X | B5 | 3 | 5 | NV..H.ZC | |
SBC A, !abs+Y | SBC abs, Y | B6 | 3 | 5 | NV..H.ZC | |
SBC A, [dp+X] | SBC (zp, X) | A7 | 2 | 6 | NV..H.ZC | |
SBC A, [dp]+Y | SBC (dp), Y | B7 | 2 | 6 | NV..H.ZC | |
SBC (X), (Y) | ? | B9 | 1 | 5 | NV..H.ZC | |
SBC dp, dp | ? | A9 | 3 | 6 | NV..H.ZC | |
SBC dp, #imm | ? | B8 | 3 | 5 | NV..H.ZC | |
CMP A, #imm | CMP #imm | 68 | 2 | 2 | N.....ZC | |
CMP A, (X) | ? | 66 | 1 | 3 | N.....ZC | |
CMP A, dp | CMP zp | 64 | 2 | 3 | N.....ZC | |
CMP A, dp+X | CMP zp, X | 74 | 2 | 4 | N.....ZC | |
CMP A, !abs | CMP abs | 65 | 3 | 4 | N.....ZC | |
CMP A, !abs+X | CMP abs, X | 75 | 3 | 5 | N.....ZC | |
CMP A, !abs+Y | CMP abs, Y | 76 | 3 | 5 | N.....ZC | |
CMP A, [dp+X] | CMP (zp, X) | 67 | 2 | 6 | N.....ZC | |
CMP A, [dp]+Y | CMP (dp), Y | 77 | 2 | 6 | N.....ZC | |
CMP (X), (Y) | ? | 79 | 1 | 5 | N.....ZC | |
CMP dp, dp | ? | 69 | 3 | 6 | N.....ZC | |
CMP dp, #imm | ? | 78 | 3 | 5 | N.....ZC | |
CMP X, #imm | CPX #imm | C8 | 2 | 2 | N.....ZC | |
CMP X, dp | CPX zp | 3E | 2 | 3 | N.....ZC | |
CMP X, !abs | CPX abs | 1E | 3 | 4 | N.....ZC | |
CMP Y, #imm | CPY #imm | AD | 2 | 2 | N.....ZC | |
CMP Y, dp | CPY zp | 7E | 2 | 3 | N.....ZC | |
CMP Y, !abs | CPY abs | 5E | 3 | 4 | N.....ZC | |
. 8-bit boolean logic | ||||||
AND A, #imm | AND #imm | 28 | 2 | 2 | N.....Z. | |
AND A, (X) | ? | 26 | 1 | 3 | N.....Z. | |
AND A, dp | AND zp | 24 | 2 | 3 | N.....Z. | |
AND A, dp+X | AND zp, X | 34 | 2 | 4 | N.....Z. | |
AND A, !abs | AND abs | 25 | 3 | 4 | N.....Z. | |
AND A, !abs+X | AND abs, X | 35 | 3 | 5 | N.....Z. | |
AND A, !abs+Y | AND abs, Y | 36 | 3 | 5 | N.....Z. | |
AND A, [dp+X] | AND (zp, X) | 27 | 2 | 6 | N.....Z. | |
AND A, [dp]+Y | AND (dp), Y | 37 | 2 | 6 | N.....Z. | |
AND (X), (Y) | ? | 39 | 1 | 5 | N.....Z. | |
AND dp, dp | ? | 29 | 3 | 6 | N.....Z. | |
AND dp, #imm | ? | 38 | 3 | 5 | N.....Z. | |
OR A, #imm | OR #imm | 08 | 2 | 2 | N.....Z. | |
OR A, (X) | ? | 06 | 1 | 3 | N.....Z. | |
OR A, dp | OR zp | 04 | 2 | 3 | N.....Z. | |
OR A, dp+X | OR zp, X | 14 | 2 | 4 | N.....Z. | |
OR A, !abs | OR abs | 05 | 3 | 4 | N.....Z. | |
OR A, !abs+X | OR abs, X | 15 | 3 | 5 | N.....Z. | |
OR A, !abs+Y | OR abs, Y | 16 | 3 | 5 | N.....Z. | |
OR A, [dp+X] | OR (zp, X) | 07 | 2 | 6 | N.....Z. | |
OR A, [dp]+Y | OR (dp), Y | 17 | 2 | 6 | N.....Z. | |
OR (X), (Y) | ? | 19 | 1 | 5 | N.....Z. | |
OR dp, dp | ? | 09 | 3 | 6 | N.....Z. | |
OR dp, #imm | ? | 18 | 3 | 5 | N.....Z. | |
EOR A, #imm | EOR #imm | 48 | 2 | 2 | N.....Z. | |
EOR A, (X) | ? | 46 | 1 | 3 | N.....Z. | |
EOR A, dp | EOR zp | 44 | 2 | 3 | N.....Z. | |
EOR A, dp+X | EOR zp, X | 54 | 2 | 4 | N.....Z. | |
EOR A, !abs | EOR abs | 45 | 3 | 4 | N.....Z. | |
EOR A, !abs+X | EOR abs, X | 55 | 3 | 5 | N.....Z. | |
EOR A, !abs+Y | EOR abs, Y | 56 | 3 | 5 | N.....Z. | |
EOR A, [dp+X] | EOR (zp, X) | 47 | 2 | 6 | N.....Z. | |
EOR A, [dp]+Y | EOR (dp), Y | 57 | 2 | 6 | N.....Z. | |
EOR (X), (Y) | ? | 59 | 1 | 5 | N.....Z. | |
EOR dp, dp | ? | 49 | 3 | 6 | N.....Z. | |
EOR dp, #imm | ? | 58 | 3 | 5 | N.....Z. | |
. 8-bit increment / decrement | ||||||
INC A | INC | BC | 1 | 2 | N.....Z. | |
INC dp | INC zp | AB | 2 | 4 | N.....Z. | |
INC dp+X | INC zp, X | BB | 2 | 5 | N.....Z. | |
INC !abs | INC abs | AC | 3 | 5 | N.....Z. | |
INC X | INX | 3D | 1 | 2 | N.....Z. | |
INC Y | INY | FC | 1 | 2 | N.....Z. | |
DEC A | DEC | 9C | 1 | 2 | N.....Z. | |
DEC dp | DEC zp | 8B | 2 | 4 | N.....Z. | |
DEC dp+X | DEC zp, X | 9B | 2 | 5 | N.....Z. | |
DEC !abs | DEC abs | 8C | 3 | 5 | N.....Z. | |
DEC X | DEX | 1D | 1 | 2 | N.....Z. | |
DEC Y | DEY | DC | 1 | 2 | N.....Z. | |
. 8-bit shift / rotation | ||||||
ASL A | ASL | 1C | 1 | 2 | N.....ZC | |
ASL dp | ASL zp | 0B | 2 | 4 | N.....ZC | |
ASL dp+X | ASL zp, X | 1B | 2 | 5 | N.....ZC | |
ASL !abs | ASL abs | 0C | 3 | 5 | N.....ZC | |
LSR A | LSR | 5C | 1 | 2 | N.....ZC | |
LSR dp | LSR zp | 4B | 2 | 4 | N.....ZC | |
LSR dp+X | LSR zp, X | 5B | 2 | 5 | N.....ZC | |
LSR !abs | LSR abs | 4C | 3 | 5 | N.....ZC | |
ROL A | ROL | 3C | 1 | 2 | N.....ZC | |
ROL dp | ROL zp | 2B | 2 | 4 | N.....ZC | |
ROL dp+X | ROL zp, X | 3B | 2 | 5 | N.....ZC | |
ROL !abs | ROL abs | 2C | 3 | 5 | N.....ZC | |
ROR A | ROR | 7C | 1 | 2 | N.....ZC | |
ROR dp | ROR zp | 6B | 2 | 4 | N.....ZC | |
ROR dp+X | ROR zp, X | 7B | 2 | 5 | N.....ZC | |
ROR !abs | ROR abs | 6C | 3 | 5 | N.....ZC | |
XCN A | ? | 9F | 1 | 5 | N.....Z. | Exchange nibbles of A |
. 16-bit operations | ||||||
MOVW YA, dp | ? | BA | 2 | 5 | N.....Z. | |
MOVW dp, YA | ? | DA | 2 | 4 | ........ | |
INCW dp | ? | 3A | 2 | 6 | N.....Z. | |
DECW dp | ? | 1A | 2 | 6 | N.....Z. | |
ADDW YA, dp | ? | 7A | 2 | 5 | NV..H.ZC | Uses carry flag |
SUBW YA, dp | ? | 9A | 2 | 5 | NV..H.ZC | Uses carry flag |
CMPW YA, dp | ? | 5A | 2 | 4 | N.....ZC | |
MUL YA | ? | CF | 1 | 9 | N.....Z. | YA = Y * A |
DIV YA, X | ? | 9E | 1 | 12 | NV..H.Z. | A = YA / X, Y = YA % X |
. decimal adjust | ||||||
DAA A | ? | DF | 1 | 3 | N.....ZC | TODO |
DAS A | ? | BE | 1 | 3 | N.....ZC | TODO |
. branching | ||||||
BRA rel | ? | 2F | 2 | 4 | ........ | Branch always |
BEQ rel | BEQ rel | F0 | 2 | 2/4 | ........ | Branch if Z=1 |
BNE rel | BNE rel | D0 | 2 | 2/4 | ........ | Branch if Z=0 |
BCS rel | BCS rel | B0 | 2 | 2/4 | ........ | Branch if C=1 |
BCC rel | BCC rel | 90 | 2 | 2/4 | ........ | Branch if C=0 |
BVS rel | BVS rel | 70 | 2 | 2/4 | ........ | Branch if V=1 |
BVC rel | BVC rel | 50 | 2 | 2/4 | ........ | Branch if V=0 |
BMI rel | BMI rel | 30 | 2 | 2/4 | ........ | Branch if N=1 |
BPL rel | BPL rel | 10 | 2 | 2/4 | ........ | Branch if N=0 |
BBS dp, bit, rel | ? | x3 | 3 | 5/7 | ........ | Branch if dp bit=1, x=(bit*2) |
BBC dp, bit, rel | ? | y3 | 3 | 5/7 | ........ | Branch if dp bit=1, y=(bit*2)+1 |
CBNE dp, rel | ? | 2E | 3 | 5/7 | ........ | CMP A, dp then BNE |
CBNE dp+X, rel | ? | DE | 3 | 6/8 | ........ | CMP A, dp+X then BNE |
DBNZ dp, rel | ? | 6E | 3 | 5/7 | ........ | DEC dp then BNE |
DBNZ Y, rel | ? | FE | 2 | 4/6 | ........ | DEC Y then BNE |
JMP !abs | JMP abs | 5F | 3 | 3 | ........ | |
JMP [!abs+X] | ? | 1F | 3 | 6 | ........ | |
. subroutines | ||||||
CALL !abs | JSR abs | 3F | 3 | 8 | ........ | |
PCALL up | ? | 4F | 2 | 6 | ........ | CALL $FF00 + up |
TCALL n | ? | n1 | 1 | 8 | ........ | CALL [$FFDE-(2*n)] |
BRK | BRK | 0F | 1 | 8 | ...1.0.. | |
RET | RET | 6F | 1 | 5 | ........ | |
RETI | RETI | 7F | 1 | 6 | NVPBHIZC | |
. stack | ||||||
PUSH A | PHA | 2D | 1 | 4 | ........ | |
PUSH X | PHX | 4D | 1 | 4 | ........ | |
PUSH Y | PHY | 6D | 1 | 4 | ........ | |
PUSH PSW | PHP | 0D | 1 | 4 | ........ | |
POP A | PLA | AE | 1 | 4 | ........ | |
POP X | PLX | CE | 1 | 4 | ........ | |
POP Y | PLY | EE | 1 | 4 | ........ | |
POP PSW | PLP | 8E | 1 | 4 | NVPBHIZC | |
. bit operations | ||||||
SET1 dp, bit | ? | x2 | 2 | 4 | ........ | Set dp bit, x=(bit*2) |
CLR1 dp, bit | ? | y2 | 2 | 4 | ........ | Set dp bit, y=(bit*2)+1 |
TSET1 !abs | TSB abs | 0E | 3 | 6 | N.....Z. | Test and set bits with A |
TCLR1 !abs | TRB abs | 4E | 3 | 6 | N.....Z. | Test and clear bits with A |
AND1 C, abs, bit | ? | 4A | 3 | 4 | .......C | C &= [abs] bit |
AND1 C, /abs, bit | ? | 6A | 3 | 4 | .......C | C &= !([abs] bit) |
OR1 C, abs, bit | ? | 0A | 3 | 5 | .......C | = [abs] bit |
OR1 C, /abs, bit | ? | 2A | 3 | 5 | .......C | = !([abs] bit) |
EOR1 C, abs, bit | ? | 8A | 3 | 5 | .......C | C ^= [abs] bit |
NOT1 abs, bit | ? | EA | 3 | 5 | ........ | [abs] bit ^= 1 |
MOV1 C, abs, bit | ? | AA | 3 | 4 | .......C | C = [abs] bit |
MOV1 abs, bit, C | ? | CA | 3 | 6 | ........ | [abs] bit = C |
. status flags | ||||||
CLRC | CLC | 60 | 1 | 2 | .......0 | |
SETC | SEC | 80 | 1 | 2 | .......1 | |
NOTC | ? | ED | 1 | 3 | .......C | C ^= 1 |
CLRC | CLV | E0 | 1 | 2 | .0..0... | Clears V and H |
CLRP | ? | 20 | 1 | 2 | ..0..... | |
SETP | ? | 40 | 1 | 2 | ..1..... | |
EI | CLI | A0 | 1 | 3 | ......1. | |
DI | SEI | C0 | 1 | 3 | ......0. | |
TODO |
Links
- SPC700 Reference - CPU Instruction Set at superfamicom.org wiki