SPC-700 instruction set: Difference between revisions
From SNESdev Wiki
Jump to navigationJump to search
Rainwarrior (talk | contribs) m (→Differences from the 6502: explain memory bit more) |
Rainwarrior (talk | contribs) (vague description of DAA/DAS, these will need their own section to properly describe) |
||
Line 37: | Line 37: | ||
* A 16-bit combined YA register is available for some operations. | * A 16-bit combined YA register is available for some operations. | ||
* The direct page can be moved to $0100. (Rarely used.) | * The direct page can be moved to $0100. (Rarely used.) | ||
* No decimal mode, instead provides <tt>DAA</tt> and <tt>DAS</tt> instructions which use the added half-carry flag. | |||
* No decimal mode, instead provides <tt>DAA</tt> and <tt>DAS</tt> instructions. | |||
* Iterrupt status flag is enable, not disable. (Not important for SNES.) | * Iterrupt status flag is enable, not disable. (Not important for SNES.) | ||
* Some operations allow direct page as a register-like destination, e.g. <tt>MOV dp, #imm</tt> or <tt>ADC dp, dp</tt>. | * Some operations allow direct page as a register-like destination, e.g. <tt>MOV dp, #imm</tt> or <tt>ADC dp, dp</tt>. | ||
Line 1,347: | Line 1,346: | ||
| 3 | | 3 | ||
| <tt>N.....ZC</tt> | | <tt>N.....ZC</tt> | ||
| | | Apply carry/half-carry after BCD addition | ||
|- | |- | ||
| <tt>DAS A</tt> | | <tt>DAS A</tt> | ||
Line 1,355: | Line 1,354: | ||
| 3 | | 3 | ||
| <tt>N.....ZC</tt> | | <tt>N.....ZC</tt> | ||
| | | Apply carry/half-carry after BCD subtraction | ||
|- | |- | ||
| colspan=7 | . '''branching''' | | colspan=7 | . '''branching''' |
Revision as of 07:17, 7 October 2022
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.)
- No decimal mode, instead provides DAA and DAS instructions which use the added half-carry flag.
- 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, that can target individual bits of memory.
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 | Apply carry/half-carry after BCD addition |
DAS A | ? | BE | 1 | 3 | N.....ZC | Apply carry/half-carry after BCD subtraction |
. 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 | |
. memory 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 | C |= [abs] bit |
OR1 C, /abs, bit | ? | 2A | 3 | 5 | .......C | 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. | |
. no-operation and halt | ||||||
NOP | NOP | 00 | 1 | 2 | ........ | |
SLEEP | ? | EF | 1 | 3 | ........ | |
STOP | ? | FF | 1 | 2 | ........ |
Links
- SPC700 Reference - CPU Instruction Set at superfamicom.org wiki