Skip to content →

spc700 – the audio processor

The SNES comes with its own processor for audio, the SPC700. It runs completely separate from the 65816. It is clocked at around 1 MHz (we will be more precise on that in a later chapter on synching components).
The SPC700 comes with 64k of memory, which includes some memory-mapped hardware registers, which the CPU and the SPC700 use to communicate with each other. It also comes with 3 timers and the DSP, both will be covered later, when we will actually work on sound. In this chapter we will only cover the basic communication with the SPC700, which is necessary for games to boot almost every time.

(thanks to Anomie for a lot of the resources and docs)

registers

SymbolDescriptionWidth
AAccumulator8 bit
X & YIndex Registers8 bit
SPStack Pointer8 bit
PCProgram Counter16 bit
PSWProgram Status Word8 bit

flags

As usual, the flags make up for the PSW.

SymbolDescription
NNegative
VOverflow
PDirect Page
BBreak
HHalf-Carry
IInterrupt Enabled (unused)
ZZero
CCarry

instruction set

At this point I won’t go far into the instruction set, but rather into the quirks of the SPC700, because it’s very similar to a 6502 and of simple nature. If you have read this far already, you will be very capable of implementing this instruction set in a short amount of time.

Mnemonic            Code Bytes  Cyc  Operation                        NVPBHIZC

  ADC   (X), (Y)     99    1     5   (X) = (X)+(Y)+C                  NV..H.ZC
  ADC   A, #i        88    2     2   A = A+i+C                        NV..H.ZC
  ADC   A, (X)       86    1     3   A = A+(X)+C                      NV..H.ZC
  ADC   A, [d]+Y     97    2     6   A = A+([d]+Y)+C                  NV..H.ZC
  ADC   A, [d+X]     87    2     6   A = A+([d+X])+C                  NV..H.ZC
  ADC   A, d         84    2     3   A = A+(d)+C                      NV..H.ZC
  ADC   A, d+X       94    2     4   A = A+(d+X)+C                    NV..H.ZC
  ADC   A, !a        85    3     4   A = A+(a)+C                      NV..H.ZC
  ADC   A, !a+X      95    3     5   A = A+(a+X)+C                    NV..H.ZC
  ADC   A, !a+Y      96    3     5   A = A+(a+Y)+C                    NV..H.ZC
  ADC   dd, ds       89    3     6   (dd) = (dd)+(d)+C                NV..H.ZC
  ADC   d, #i        98    3     5   (d) = (d)+i+C                    NV..H.ZC
  ADDW  YA, d        7A    2     5   YA  = YA + (d), H on high byte   NV..H.ZC
  AND   (X), (Y)     39    1     5   (X) = (X) & (Y)                  N.....Z.
  AND   A, #i        28    2     2   A = A & i                        N.....Z.
  AND   A, (X)       26    1     3   A = A & (X)                      N.....Z.
  AND   A, [d]+Y     37    2     6   A = A & ([d]+Y)                  N.....Z.
  AND   A, [d+X]     27    2     6   A = A & ([d+X])                  N.....Z.
  AND   A, d         24    2     3   A = A & (d)                      N.....Z.
  AND   A, d+X       34    2     4   A = A & (d+X)                    N.....Z.
  AND   A, !a        25    3     4   A = A & (a)                      N.....Z.
  AND   A, !a+X      35    3     5   A = A & (a+X)                    N.....Z.
  AND   A, !a+Y      36    3     5   A = A & (a+Y)                    N.....Z.
  AND   dd, ds       29    3     6   (dd) = (dd) & (ds)               N.....Z.
  AND   d, #i        38    3     5   (d) = (d) & i                    N.....Z.
  AND1  C, /m.b      6A    3     4   C = C & ~(m.b)                   .......C
  AND1  C, m.b       4A    3     4   C = C & (m.b)                    .......C
  ASL   A            1C    1     2   Left shift A: high->C, 0->low    N.....ZC
  ASL   d            0B    2     4   Left shift (d) as above          N.....ZC
  ASL   d+X          1B    2     5   Left shift (d+X) as above        N.....ZC
  ASL   !a           0C    3     5   Left shift (a) as above          N.....ZC
  BBC   d.0, r       13    3    5/7  PC+=r  if d.0 == 0               ........
  BBC   d.1, r       33    3    5/7  PC+=r  if d.1 == 0               ........
  BBC   d.2, r       53    3    5/7  PC+=r  if d.2 == 0               ........
  BBC   d.3, r       73    3    5/7  PC+=r  if d.3 == 0               ........
  BBC   d.4, r       93    3    5/7  PC+=r  if d.4 == 0               ........
  BBC   d.5, r       B3    3    5/7  PC+=r  if d.5 == 0               ........
  BBC   d.6, r       D3    3    5/7  PC+=r  if d.6 == 0               ........
  BBC   d.7, r       F3    3    5/7  PC+=r  if d.7 == 0               ........
  BBS   d.0, r       03    3    5/7  PC+=r  if d.0 == 1               ........
  BBS   d.1, r       23    3    5/7  PC+=r  if d.1 == 1               ........
  BBS   d.2, r       43    3    5/7  PC+=r  if d.2 == 1               ........
  BBS   d.3, r       63    3    5/7  PC+=r  if d.3 == 1               ........
  BBS   d.4, r       83    3    5/7  PC+=r  if d.4 == 1               ........
  BBS   d.5, r       A3    3    5/7  PC+=r  if d.5 == 1               ........
  BBS   d.6, r       C3    3    5/7  PC+=r  if d.6 == 1               ........
  BBS   d.7, r       E3    3    5/7  PC+=r  if d.7 == 1               ........
  BCC   r            90    2    2/4  PC+=r  if C == 0                 ........
  BCS   r            B0    2    2/4  PC+=r  if C == 1                 ........
  BEQ   r            F0    2    2/4  PC+=r  if Z == 1                 ........
  BMI   r            30    2    2/4  PC+=r  if N == 1                 ........
  BNE   r            D0    2    2/4  PC+=r  if Z == 0                 ........
  BPL   r            10    2    2/4  PC+=r  if N == 0                 ........
  BVC   r            50    2    2/4  PC+=r  if V == 0                 ........
  BVS   r            70    2    2/4  PC+=r  if V == 1                 ........
  BRA   r            2F    2     4   PC+=r                            ........
  BRK                0F    1     8   Push PC and Flags, PC = [$FFDE]  ...1.0..
  CALL  !a           3F    3     8   (SP--)=PCh, (SP--)=PCl, PC=a     ........
  CBNE  d+X, r       DE    3    6/8  CMP A, (d+X) then BNE            ........
  CBNE  d, r         2E    3    5/7  CMP A, (d) then BNE              ........
  CLR1  d.0          12    2     4   d.0 = 0                          ........
  CLR1  d.1          32    2     4   d.1 = 0                          ........
  CLR1  d.2          52    2     4   d.2 = 0                          ........
  CLR1  d.3          72    2     4   d.3 = 0                          ........
  CLR1  d.4          92    2     4   d.4 = 0                          ........
  CLR1  d.5          B2    2     4   d.5 = 0                          ........
  CLR1  d.6          D2    2     4   d.6 = 0                          ........
  CLR1  d.7          F2    2     4   d.7 = 0                          ........
  CLRC               60    1     2   C = 0                            .......0
  CLRP               20    1     2   P = 0                            ..0.....
  CLRV               E0    1     2   V = 0, H = 0                     .0..0...
  CMP   (X), (Y)     79    1     5   (X) - (Y)                        N.....ZC
  CMP   A, #i        68    2     2   A - i                            N.....ZC
  CMP   A, (X)       66    1     3   A - (X)                          N.....ZC
  CMP   A, [d]+Y     77    2     6   A - ([d]+Y)                      N.....ZC
  CMP   A, [d+X]     67    2     6   A - ([d+X])                      N.....ZC
  CMP   A, d         64    2     3   A - (d)                          N.....ZC
  CMP   A, d+X       74    2     4   A - (d+X)                        N.....ZC
  CMP   A, !a        65    3     4   A - (a)                          N.....ZC
  CMP   A, !a+X      75    3     5   A - (a+X)                        N.....ZC
  CMP   A, !a+Y      76    3     5   A - (a+Y)                        N.....ZC
  CMP   X, #i        C8    2     2   X - i                            N.....ZC
  CMP   X, d         3E    2     3   X - (d)                          N.....ZC
  CMP   X, !a        1E    3     4   X - (a)                          N.....ZC
  CMP   Y, #i        AD    2     2   Y - i                            N.....ZC
  CMP   Y, d         7E    2     3   Y - (d)                          N.....ZC
  CMP   Y, !a        5E    3     4   Y - (a)                          N.....ZC
  CMP   dd, ds       69    3     6   (dd) - (ds)                      N.....ZC
  CMP   d, #i        78    3     5   (d) - i                          N.....ZC
  CMPW  YA, d        5A    2     4   YA - (d)                         N.....ZC
  DAA   A            DF    1     3   decimal adjust for addition      N.....ZC
  DAS   A            BE    1     3   decimal adjust for subtraction   N.....ZC
  DBNZ  Y, r         FE    2    4/6  Y-- then JNZ                     ........
  DBNZ  d, r         6E    3    5/7  (d)-- then JNZ                   ........
  DEC   A            9C    1     2   A--                              N.....Z.
  DEC   X            1D    1     2   X--                              N.....Z.
  DEC   Y            DC    1     2   Y--                              N.....Z.
  DEC   d            8B    2     4   (d)--                            N.....Z.
  DEC   d+X          9B    2     5   (d+X)--                          N.....Z.
  DEC   !a           8C    3     5   (a)--                            N.....Z.
  DECW  d            1A    2     6   Word (d)--                       N.....Z.
  DI                 C0    1     3   I = 0                            .....0..
  DIV   YA, X        9E    1    12   A=YA/X, Y=mod(YA,X)              NV..H.Z.
  EI                 A0    1     3   I = 1                            .....1..
  EOR   (X), (Y)     59    1     5   (X) = (X) EOR (Y)                N.....Z.
  EOR   A, #i        48    2     2   A = A EOR i                      N.....Z.
  EOR   A, (X)       46    1     3   A = A EOR (X)                    N.....Z.
  EOR   A, [d]+Y     57    2     6   A = A EOR ([d]+Y)                N.....Z.
  EOR   A, [d+X]     47    2     6   A = A EOR ([d+X])                N.....Z.
  EOR   A, d         44    2     3   A = A EOR (d)                    N.....Z.
  EOR   A, d+X       54    2     4   A = A EOR (d+X)                  N.....Z.
  EOR   A, !a        45    3     4   A = A EOR (a)                    N.....Z.
  EOR   A, !a+X      55    3     5   A = A EOR (a+X)                  N.....Z.
  EOR   A, !a+Y      56    3     5   A = A EOR (a+Y)                  N.....Z.
  EOR   dd, ds       49    3     6   (dd) = (dd) EOR (ds)             N.....Z.
  EOR   d, #i        58    3     5   (d) = (d) EOR i                  N.....Z.
  EOR1  C, m.b       8A    3     5   C = C EOR (m.b)                  .......C
  INC   A            BC    1     2   A++                              N.....Z.
  INC   X            3D    1     2   X++                              N.....Z.
  INC   Y            FC    1     2   Y++                              N.....Z.
  INC   d            AB    2     4   (d)++                            N.....Z.
  INC   d+X          BB    2     5   (d+X)++                          N.....Z.
  INC   !a           AC    3     5   (a)++                            N.....Z.
  INCW  d            3A    2     6   Word (d)++                       N.....Z.
  JMP   [!a+X]       1F    3     6   PC = [a+X]                       ........
  JMP   !a           5F    3     3   PC = a                           ........
  LSR   A            5C    1     2   Right shift A: 0->high, low->C   N.....ZC
  LSR   d            4B    2     4   Right shift (d) as above         N.....ZC
  LSR   d+X          5B    2     5   Right shift (d+X) as above       N.....ZC
  LSR   !a           4C    3     5   Right shift (a) as above         N.....ZC
  MOV   (X)+, A      AF    1     4   (X++) = A      (no read)         ........
  MOV   (X), A       C6    1     4   (X) = A        (read)            ........
  MOV   [d]+Y, A     D7    2     7   ([d]+Y) = A    (read)            ........
  MOV   [d+X], A     C7    2     7   ([d+X]) = A    (read)            ........
  MOV   A, #i        E8    2     2   A = i                            N.....Z.
  MOV   A, (X)       E6    1     3   A = (X)                          N.....Z.
  MOV   A, (X)+      BF    1     4   A = (X++)                        N.....Z.
  MOV   A, [d]+Y     F7    2     6   A = ([d]+Y)                      N.....Z.
  MOV   A, [d+X]     E7    2     6   A = ([d+X])                      N.....Z.
  MOV   A, X         7D    1     2   A = X                            N.....Z.
  MOV   A, Y         DD    1     2   A = Y                            N.....Z.
  MOV   A, d         E4    2     3   A = (d)                          N.....Z.
  MOV   A, d+X       F4    2     4   A = (d+X)                        N.....Z.
  MOV   A, !a        E5    3     4   A = (a)                          N.....Z.
  MOV   A, !a+X      F5    3     5   A = (a+X)                        N.....Z.
  MOV   A, !a+Y      F6    3     5   A = (a+Y)                        N.....Z.
  MOV   SP, X        BD    1     2   SP = X                           ........
  MOV   X, #i        CD    2     2   X = i                            N.....Z.
  MOV   X, A         5D    1     2   X = A                            N.....Z.
  MOV   X, SP        9D    1     2   X = SP                           N.....Z.
  MOV   X, d         F8    2     3   X = (d)                          N.....Z.
  MOV   X, d+Y       F9    2     4   X = (d+Y)                        N.....Z.
  MOV   X, !a        E9    3     4   X = (a)                          N.....Z.
  MOV   Y, #i        8D    2     2   Y = i                            N.....Z.
  MOV   Y, A         FD    1     2   Y = A                            N.....Z.
  MOV   Y, d         EB    2     3   Y = (d)                          N.....Z.
  MOV   Y, d+X       FB    2     4   Y = (d+X)                        N.....Z.
  MOV   Y, !a        EC    3     4   Y = (a)                          N.....Z.
  MOV   dd, ds       FA    3     5   (dd) = (ds)    (no read)         ........
  MOV   d+X, A       D4    2     5   (d+X) = A      (read)            ........
  MOV   d+X, Y       DB    2     5   (d+X) = Y      (read)            ........
  MOV   d+Y, X       D9    2     5   (d+Y) = X      (read)            ........
  MOV   d, #i        8F    3     5   (d) = i        (read)            ........
  MOV   d, A         C4    2     4   (d) = A        (read)            ........
  MOV   d, X         D8    2     4   (d) = X        (read)            ........
  MOV   d, Y         CB    2     4   (d) = Y        (read)            ........
  MOV   !a+X, A      D5    3     6   (a+X) = A      (read)            ........
  MOV   !a+Y, A      D6    3     6   (a+Y) = A      (read)            ........
  MOV   !a, A        C5    3     5   (a) = A        (read)            ........
  MOV   !a, X        C9    3     5   (a) = X        (read)            ........
  MOV   !a, Y        CC    3     5   (a) = Y        (read)            ........
  MOV1  C, m.b       AA    3     4   C = (m.b)                        .......C
  MOV1  m.b, C       CA    3     6   (m.b) = C                        ........
  MOVW  YA, d        BA    2     5   YA = word (d)                    N.....Z.
  MOVW  d, YA        DA    2     5   word (d) = YA  (read low only)   ........
  MUL   YA           CF    1     9   YA = Y * A, NZ on Y only         N.....Z.
  NOP                00    1     2   do nothing                       ........
  NOT1  m.b          EA    3     5   m.b = ~m.b                       ........
  NOTC               ED    1     3   C = !C                           .......C
  OR    (X), (Y)     19    1     5   (X) = (X) | (Y)                  N.....Z.
  OR    A, #i        08    2     2   A = A | i                        N.....Z.
  OR    A, (X)       06    1     3   A = A | (X)                      N.....Z.
  OR    A, [d]+Y     17    2     6   A = A | ([d]+Y)                  N.....Z.
  OR    A, [d+X]     07    2     6   A = A | ([d+X])                  N.....Z.
  OR    A, d         04    2     3   A = A | (d)                      N.....Z.
  OR    A, d+X       14    2     4   A = A | (d+X)                    N.....Z.
  OR    A, !a        05    3     4   A = A | (a)                      N.....Z.
  OR    A, !a+X      15    3     5   A = A | (a+X)                    N.....Z.
  OR    A, !a+Y      16    3     5   A = A | (a+Y)                    N.....Z.
  OR    dd, ds       09    3     6   (dd) = (dd) | (ds)               N.....Z.
  OR    d, #i        18    3     5   (d) = (d) | i                    N.....Z.
  OR1   C, /m.b      2A    3     5   C = C | ~(m.b)                   .......C
  OR1   C, m.b       0A    3     5   C = C | (m.b)                    .......C
  PCALL u            4F    2     6   CALL $FF00+u                     ........
  POP   A            AE    1     4   A = (++SP)                       ........
  POP   PSW          8E    1     4   Flags = (++SP)                   NVPBHIZC
  POP   X            CE    1     4   X = (++SP)                       ........
  POP   Y            EE    1     4   Y = (++SP)                       ........
  PUSH  A            2D    1     4   (SP--) = A                       ........
  PUSH  PSW          0D    1     4   (SP--) = Flags                   ........
  PUSH  X            4D    1     4   (SP--) = X                       ........
  PUSH  Y            6D    1     4   (SP--) = Y                       ........
  RET                6F    1     5   Pop PC                           ........
  RET1               7F    1     6   Pop Flags, PC                    NVPBHIZC
  ROL   A            3C    1     2   Left shift A: low=C, C=high      N.....ZC
  ROL   d            2B    2     4   Left shift (d) as above          N.....ZC
  ROL   d+X          3B    2     5   Left shift (d+X) as above        N.....ZC
  ROL   !a           2C    3     5   Left shift (a) as above          N.....ZC
  ROR   A            7C    1     2   Right shift A: high=C, C=low     N.....ZC
  ROR   d            6B    2     4   Right shift (d) as above         N.....ZC
  ROR   d+X          7B    2     5   Right shift (d+X) as above       N.....ZC
  ROR   !a           6C    3     5   Right shift (a) as above         N.....ZC
  SBC   (X), (Y)     B9    1     5   (X) = (X)-(Y)-!C                 NV..H.ZC
  SBC   A, #i        A8    2     2   A = A-i-!C                       NV..H.ZC
  SBC   A, (X)       A6    1     3   A = A-(X)-!C                     NV..H.ZC
  SBC   A, [d]+Y     B7    2     6   A = A-([d]+Y)-!C                 NV..H.ZC
  SBC   A, [d+X]     A7    2     6   A = A-([d+X])-!C                 NV..H.ZC
  SBC   A, d         A4    2     3   A = A-(d)-!C                     NV..H.ZC
  SBC   A, d+X       B4    2     4   A = A-(d+X)-!C                   NV..H.ZC
  SBC   A, !a        A5    3     4   A = A-(a)-!C                     NV..H.ZC
  SBC   A, !a+X      B5    3     5   A = A-(a+X)-!C                   NV..H.ZC
  SBC   A, !a+Y      B6    3     5   A = A-(a+Y)-!C                   NV..H.ZC
  SBC   dd, ds       A9    3     6   (dd) = (dd)-(ds)-!C              NV..H.ZC
  SBC   d, #i        B8    3     5   (d) = (d)-i-!C                   NV..H.ZC
  SET1  d.0          02    2     4   d.0 = 1                          ........
  SET1  d.1          22    2     4   d.1 = 1                          ........
  SET1  d.2          42    2     4   d.2 = 1                          ........
  SET1  d.3          62    2     4   d.3 = 1                          ........
  SET1  d.4          82    2     4   d.4 = 1                          ........
  SET1  d.5          A2    2     4   d.5 = 1                          ........
  SET1  d.6          C2    2     4   d.6 = 1                          ........
  SET1  d.7          E2    2     4   d.7 = 1                          ........
  SETC               80    1     2   C = 1                            .......1
  SETP               40    1     2   P = 1                            ..1.....
  SLEEP              EF    1     ?   Halts the processor              ........
  STOP               FF    1     ?   Halts the processor              ........
  SUBW  YA, d        9A    2     5   YA  = YA - (d), H on high byte   NV..H.ZC
  TCALL 0            01    1     8   CALL [$FFDE]                     ........
  TCALL 1            11    1     8   CALL [$FFDC]                     ........
  TCALL 2            21    1     8   CALL [$FFDA]                     ........
  TCALL 3            31    1     8   CALL [$FFD8]                     ........
  TCALL 4            41    1     8   CALL [$FFD6]                     ........
  TCALL 5            51    1     8   CALL [$FFD4]                     ........
  TCALL 6            61    1     8   CALL [$FFD2]                     ........
  TCALL 7            71    1     8   CALL [$FFD0]                     ........
  TCALL 8            81    1     8   CALL [$FFCE]                     ........
  TCALL 9            91    1     8   CALL [$FFCC]                     ........
  TCALL 10           A1    1     8   CALL [$FFCA]                     ........
  TCALL 11           B1    1     8   CALL [$FFC8]                     ........
  TCALL 12           C1    1     8   CALL [$FFC6]                     ........
  TCALL 13           D1    1     8   CALL [$FFC4]                     ........
  TCALL 14           E1    1     8   CALL [$FFC2]                     ........
  TCALL 15           F1    1     8   CALL [$FFC0]                     ........
  TCLR1 !a           4E    3     6   (a) = (a)&~A, ZN as for A-(a)    N.....Z.
  TSET1 !a           0E    3     6   (a) = (a)|A, ZN as for A-(a)     N.....Z.
  XCN   A            9F    1     5   A = (A>>4) | (A<<4)              N.....Z.

memory-mapped hardware registers

The SPC700 has 16 I/O registers, to communicate with the CPU, the DSP (will be covered later), and to work with its timers.

AddressRead/WriteDescription
0xF0WTEST – Undocumented
0xF1WCONTROL – IO and timer control
0xF2RWDSPADDR – DSP Address
0xF3RWDSPDATA – DSP Data
0xF4RWCPUI/O0 – CPU I/O register 0
0xF5RWCPUI/O1 – CPU I/O register 1
0xF6RWCPUI/O2 – CPU I/O register 2
0xF7RWCPUI/O3 – CPU I/O register 3
0xF8RWnormal RAM
0xF9RWnormal RAM
0xFAWT0TARGET – Timer 0 scaling
0xFBWT1TARGET – Timer 1 scaling
0xFCWT2TARGET – Timer 2 scaling
0xFDRT0OUT – Timer 0 Output
0xFERT1OUT – Timer 1 Output
0xFFRT2OUT – Timer 2 Output
0xF1 – CONTROL

r-ba-210

r – If set, the IPL Bootrom can be read at 0xFFC0 – 0xFFFF
a – If 1 is written, input ports 0xF4 and 0xF5 are cleared
b – If 1 is written, input ports 0xF6 and 0xF7 are cleared
210 – Enables timers 0, 1, 2

0xF2 – DSPADDR

aaaaaaaa

Stores/reads the DSP address we can interact with on DSPDATA

0xF3 – DSPDATA

dddddddd

Stores to/reads from DSP at the address specified at DSPADDR

0xF4 – CPUI/O0
0xF5 – CPUI/O1
0xF6 – CPUI/O2
0xF7 – CPUI/O3

xxxxxxxx

IMPORTANT!
With these (seemingly) 4 registers the CPU and the SPC700 communicate with each other. Each register can hold two values though. The input value, and the output value. The input value is what the CPU wrote to it, the output value is what the SPC700 wrote to it. The CPU can only read the SPC700’s output values, and vice versa. This is used so both processors can sync up to each other.

0xF8 – normal RAM
0xF9 – normal RAM

These two bytes behave just like regular RAM.

0xFA – T0TARGET
0xFB – T1TARGET
0xFC – T2TARGET

tttttttt

0xFD – T0OUT
0xFE – T1OUT
0xFF – T2OUT

0000xxxx


These are the Timer Scaling Targets and the according Timer Outputs

Timers

The SPC700 has 3 Timers, Timer 0 and Timer 1 run at a base rate of 128 clock cycles (~8000 Hz), and Timer 2 runs on a base rate of 16 clock cycles (~64000 Hz).

The timers work in basicall 3 stages, separately for each timer:

  • Stage 1

Clock cycles of the timer have passed, Stage 1 gets ticked (this is always running and can not be stopped), so after 128 cycles for Timer 0 and Timer 1, and after 16 cycles

  • Stage 2

This stage has a 1-256 counter (with wraparound), that gets ticked whenever Stage 1 gets ticked and the Timer is enabled. Post-increment, the counters value gets compare to TnTARGET. If the values are equal, Stage 3 gets ticked, and the Stage 2 counter gets reset to zero.

Note: A value of 0x00 corresponds to 256 ticks.

  • Stage 3

4-Bit Counter, which can be read from TnOUT and is reset to zero on read

IPL Boot ROM

The SPC700 comes with an IPL Boot ROM, which gets copied to 0xFFC0 on reset. The boot ROM handles the handshaking between the SPC700 and the CPU, so they can be in sync.

const u8 IPL_BOOTROM[0x40] = {
	0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0, 0xFC, 0x8F, 0xAA, 0xF4, 0x8F, 0xBB, 0xF5, 0x78,
	0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4, 0xD0, 0xFC, 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5,
	0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, 0xAB, 0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA,
	0xF6, 0xDA, 0x00, 0xBA, 0xF4, 0xC4, 0xF4, 0xDD, 0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF
};

If someone is interested in the disassembly of the IPL Boot ROM, anemie did a great one with full comments:

.ORG $FFC0
       MOV X, #$EF     ; *** INIT ***
       MOV SP, X       ; setup stack
       MOV A, #$00     ; clear page 0 RAM
       MOV (X),A
       DEC X
       BNE -
       MOV $F4,#$AA    ; Signal "ready" to 5A22: $2140-1 will return #$BBAA
       MOV $F5,#$BB
       CMP $F4,#$CC    ; wait for 5A22 to write #$CC to $2140
       BNE -
       BRA Start
Trans: MOV Y,$F4       ; *** TRANSFER ROUTINE ***
       BNE Trans       ; First, wait for 5A22 to indicate Byte 0 ready on $2140
       CMP Y,$F4       ; start loop: wait for "next byte/end" signal on $2140
       BNE +
       MOV A,$F5       ; Got "next byte" ($2140 matches expected byte index)
       MOV $F4,Y       ; Read byte-to-write from $2141, echo $2140 to signal
       MOV [$00]+Y,A   ; ready, and write the byte and update the counter.
       INC Y
       BNE -
       INC $01         ; (handle $xxFF->$xx00 overflow case on increment)
       BPL -
       CMP Y,$F4       ; If "next byte/end" is not equal to expected next byte
       BPL -           ; index, it's "end": drop back into the main loop.
Start: MOVW YA,$F6     ; *** MAIN LOOP ***
       MOVW $00,YA     ; Get address from 5A22's $2142-3,
       MOVW YA,$F4     ; mode from $2141, and echo $2140 back
       MOV $F4,A
       MOV A,Y
       MOV X,A
       BNE Trans       ; Mode non-0: begin transfer
       JMP [$0000+X]   ; Mode 0: jump to address
       .DW $FFC0       ; RESET vector

Comments

  1. Jeff Linahan Jeff Linahan

    Is JNZ an SPC700 instruction? I notice its mentioned as the operation of DBNZ but doesn’t actually appear in as a separate entry in the mnemonic table.

    • LilaQ LilaQ

      Hey, sorry it took so long, someone just hinted me your message – I was in the middle of moving.
      Afair JNZ is not a separate SPC700 instruction, but is only used to make clear how the different DBNZ instructions perform, without having to write everything out again. Because JNZ at this point usually is pretty clear to everyone familiar with some assembly.

Leave a Reply