SPC-700 instruction set: Difference between revisions

From SNESdev Wiki
Jump to navigationJump to search
(→‎Instructions: 6502 ORA rather than OR)
m (→‎Instructions: 6502 returns)
Line 1,529: Line 1,529:
|-
|-
| <tt>RET</tt>
| <tt>RET</tt>
| <tt>RET</tt>
| <tt>RTS</tt>
| <tt>6F</tt>
| <tt>6F</tt>
| 1
| 1
Line 1,537: Line 1,537:
|-
|-
| <tt>RETI</tt>
| <tt>RETI</tt>
| <tt>RETI</tt>
| <tt>RTI</tt>
| <tt>7F</tt>
| <tt>7F</tt>
| 1
| 1

Revision as of 07:31, 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.
  • Interrupt 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.

SPC-700 Instruction Set
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 ORA #imm 08 2 2 N.....Z.
OR A, (X) ? 06 1 3 N.....Z.
OR A, dp ORA zp 04 2 3 N.....Z.
OR A, dp+X ORA zp, X 14 2 4 N.....Z.
OR A, !abs ORA abs 05 3 4 N.....Z.
OR A, !abs+X ORA abs, X 15 3 5 N.....Z.
OR A, !abs+Y ORA abs, Y 16 3 5 N.....Z.
OR A, [dp+X] ORA (zp, X) 07 2 6 N.....Z.
OR A, [dp]+Y ORA (zp), 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 RTS 6F 1 5 ........
RETI RTI 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