SNES DevelopmentTransferring Data from ROM to the SNES APU The method of transferring data to the sound module of the SNES is a bit screwy, but it works. I’ve read many docs, looked at a lot of code, and nothing I’ve seen seems to explain the method to this madness in a straightforward way. I’m hoping I can shed some light on the matter.
During the transfer process, the following ports apply:
$2140 = Status
$2141 = Command / Data
$2142-3 = Address
$2140 to be $AA and port $2141 to be $BB. (This means the ROM program is through initializing, and is ready to begin a transfer.)$2141. (A value of 0 has a different meaning which will be explained later.)$2142 and $2143, with the low byte written to $2142.$CC to port $2140.$2140 to be $CC.$2141.$00 to port $2140.$2140 to be $00.$2141.$2140 by 1, and write it back.$2140 to be the same as the value written.$2141.$2142 and $2143, with the low byte written to $2142.$2140 by 2. If it’s 0, increase it again. Write it back.$2140 to be the same as the value written, then go to the section “Transferring Data”.$2141.$2142 and $2143, with the low byte written to $2142.$2140 by 2, and write it back.Between transfers, a non-zero value sent to $2141 means to begin a transfer, and a zero value means to end a transfer and begin execution.
16-bit addresses are written to $2142-3.
During transfers, in $2140 a value less than means the APU is busy, a value equal means it’s ready for the next byte. Writing a value one greater means the next byte ($2141) is ready to be stored. Writing a value two or more greater means to end the transfer and apply the command in $2141. (Because of the internal workings of the ROM program, the value in $2140 must be non-zero if the command is to start another transfer.)
; Wait for SPC700 to initialize
REP #$30 ; (16-bit A and X Y)
LDA #$BBAA
Init: CMP $2140
BNE Init
; Initialize transfer ---------
LDA #SPCExec ; Send starting address
STA $2142
LDA #$1CC
STA $2140 ; Write $CC to 2140 and !0 to 2141
SEP #$20 ; (8-bit A)
Start: CMP $2140 ; Wait for SPC700 to give the go
BNE Start
; Send data -------------------
LDX #0 ; X indexes the current byte being sent
LDY #SPCSize ; Y = Number of bytes that need to be sent
Next: LDA SPCData,X ; Send byte
STA $2141
TXA
STA $2140
Wait: CMP $2140 ; Wait for transfer
BNE Wait
INX
DEY
BNE Next
; Begin execution -------------
REP #$20 ; (16-bit A)
LDA #SPCExec ; Starting address of execution
STA $2142
SEP #$20 ; (8-bit A)
LDA #0 ; JMP to execution address
STA $2141
LDA $2140 ; Break transfer cycle
ADC #2
STA $2140
Copyright ©2000 Alpha-II Productions