I have a rom where there is a default sound driver. If certain songs are selected a flag is set to unload the default sound driver. Once the dault sound driver is unloaded than a flag is set to indicate the non-default driver is currently loaded. If the next song that is called does not request the non-default sound driver than that driver is unloaded and the default driver is restored.
I had this working 100% at one point, and I'm not sure how or why it has stopped working. To simplify I'm no longer switching drivers at any point. All my cuurent tests are loading either driver A or B.
Currently, this is what happens:
load sound driver A: sound driver doesn't work (sound doesn't work but the menu screen is operational, so not stuck in any loops waiting on the spc)
load sound driver B: sound driver works
I have one file has the spc code for both sound drivers in such a fashion:
the code to load a driver is just
There is a copy of the code that is the same except for local labels and uses SOUND_DRIVER_B and is called spcBootDriverB. While assembeld (ca65) the output is the same for both routines except for the driver address and number of bytes to transfer. Everything here is correct.
Right now there is no way I can get SOUND_DRIVER_A to work.
If I go back to the version which only has the ability to load one sound driver and I only include one sound driver (no matter which sound driver I include) then it will always work. I'm not sure why including the code for a second driver, and including the data for a second sound driver would cause any weirdness.
If I use SOUND_DRIVER_B data for both SOUND_DRIVER_B and SOUND_DRIVER_A than "A" works.
It looks like when I use SOUND_DRIVER_A the last thing written to $f2 is $17 which is gain, and the last value written to $f3 is $9e (%10011110, custom gain and gain rate). This shows me it's not processing pattern data because it's not cycling through the channels. The only thing being updated are the spc timers. I know what code would produce this value and it's the exact same code in SOUND_DRIVER_B. Most of the code between the sound drivers is the same, everything that handles the it pattern data is the same, as is everything which handles volume and such.
If I use the original snesmod code and only include 1 driver than it works no matter which driver I use. I do not understand why SOUND_DRIVER_A would "magically" (that word rather implies some sort of bug some where doesn't it?) work.
The only changes to snesmod.asm was having two different spcBoot routines (which are the same except for the data they read and the number of bytes they transfer), and sm_spc where I'm including two sound drivers instead of one.
Anyway I posted this because I thought if I wrote it out something might jump out at me and possibly somebody might have some ideas of things to check.
I had this working 100% at one point, and I'm not sure how or why it has stopped working. To simplify I'm no longer switching drivers at any point. All my cuurent tests are loading either driver A or B.
Currently, this is what happens:
load sound driver A: sound driver doesn't work (sound doesn't work but the menu screen is operational, so not stuck in any loops waiting on the spc)
load sound driver B: sound driver works
I have one file has the spc code for both sound drivers in such a fashion:
Code:
.export SOUND_DRIVER_A, SOUND_DRIVER_A_END, SOUND_DRIVER_B, SOUND_DRIVER_B_END
.segment "DRIVER"
SOUND_DRIVER_A:
(sound driver A data)
SOUND_DRIVER_A_END:
SOUND_DRIVER_B:
(sound driver B data)
SOUND_DRIVER_B_END:
.segment "DRIVER"
SOUND_DRIVER_A:
(sound driver A data)
SOUND_DRIVER_A_END:
SOUND_DRIVER_B:
(sound driver B data)
SOUND_DRIVER_B_END:
the code to load a driver is just
Code:
SPC_BOOT = 0380h ; all sound drivers being tested are using this address
;**********************************************************************
;* upload driver
;*
;* disable time consuming interrupts during this function
;**********************************************************************
spcBootDriverA:
;----------------------------------------------------------------------
: ldx REG_APUIO0 ; wait for 'ready signal from SPC
cpx #0BBAAh ;
bne :- ;--------------------------------------
stx REG_APUIO1 ; start transfer:
ldx #SPC_BOOT ; port1 = !0
stx REG_APUIO2 ; port2,3 = transfer address
lda #0CCh ; port0 = 0CCh
sta REG_APUIO0 ;--------------------------------------
: cmp REG_APUIO0 ; wait for SPC
bne :- ;
;----------------------------------------------------------------------
; ready to transfer
;----------------------------------------------------------------------
lda f:SOUND_DRIVER_A ; read first byte
xba ;
lda #0 ;
ldx #1 ;
bra sb_start ;
;----------------------------------------------------------------------
; transfer data
;----------------------------------------------------------------------
sb_send:
;----------------------------------------------------------------------
xba ; swap DATA into A
lda f:SOUND_DRIVER_A, x; read next byte
inx ; swap DATA into B
xba ;--------------------------------------
: cmp REG_APUIO0 ; wait for SPC
bne :- ;--------------------------------------
ina ; increment counter (port0 data)
;----------------------------------------------------------------------
sb_start:
;----------------------------------------------------------------------
rep #20h ; write port0+port1 data
sta REG_APUIO0 ;
sep #20h ;--------------------------------------
cpx #SOUND_DRIVER_A-SOUND_DRIVER_A ; loop until all bytes transferred
bcc sb_send ;
;----------------------------------------------------------------------
; all bytes transferred
;----------------------------------------------------------------------
: cmp REG_APUIO0 ; wait for SPC
bne :- ;--------------------------------------
ina ; add 2 or so...
ina ;--------------------------------------
; mask data so invalid 80h message wont get sent
stz REG_APUIO1 ; port1=0
ldx #SPC_BOOT ; port2,3 = entry point
stx REG_APUIO2 ;
sta REG_APUIO0 ; write P0 data
;--------------------------------------
: cmp REG_APUIO0 ; final sync
bne :- ;--------------------------------------
stz REG_APUIO0
stz spc_v ; reset V
stz spc_q ; reset Q
stz spc_fwrite ; reset command fifo
stz spc_fread ;
stz spc_sfx_next ;
stz spc_pr+0
stz spc_pr+1
stz spc_pr+2
stz spc_pr+3
;----------------------------------------------------------------------
; driver installation successful
;----------------------------------------------------------------------
rts ; return
;----------------------------------------------------------------------
;**********************************************************************
;* upload driver
;*
;* disable time consuming interrupts during this function
;**********************************************************************
spcBootDriverA:
;----------------------------------------------------------------------
: ldx REG_APUIO0 ; wait for 'ready signal from SPC
cpx #0BBAAh ;
bne :- ;--------------------------------------
stx REG_APUIO1 ; start transfer:
ldx #SPC_BOOT ; port1 = !0
stx REG_APUIO2 ; port2,3 = transfer address
lda #0CCh ; port0 = 0CCh
sta REG_APUIO0 ;--------------------------------------
: cmp REG_APUIO0 ; wait for SPC
bne :- ;
;----------------------------------------------------------------------
; ready to transfer
;----------------------------------------------------------------------
lda f:SOUND_DRIVER_A ; read first byte
xba ;
lda #0 ;
ldx #1 ;
bra sb_start ;
;----------------------------------------------------------------------
; transfer data
;----------------------------------------------------------------------
sb_send:
;----------------------------------------------------------------------
xba ; swap DATA into A
lda f:SOUND_DRIVER_A, x; read next byte
inx ; swap DATA into B
xba ;--------------------------------------
: cmp REG_APUIO0 ; wait for SPC
bne :- ;--------------------------------------
ina ; increment counter (port0 data)
;----------------------------------------------------------------------
sb_start:
;----------------------------------------------------------------------
rep #20h ; write port0+port1 data
sta REG_APUIO0 ;
sep #20h ;--------------------------------------
cpx #SOUND_DRIVER_A-SOUND_DRIVER_A ; loop until all bytes transferred
bcc sb_send ;
;----------------------------------------------------------------------
; all bytes transferred
;----------------------------------------------------------------------
: cmp REG_APUIO0 ; wait for SPC
bne :- ;--------------------------------------
ina ; add 2 or so...
ina ;--------------------------------------
; mask data so invalid 80h message wont get sent
stz REG_APUIO1 ; port1=0
ldx #SPC_BOOT ; port2,3 = entry point
stx REG_APUIO2 ;
sta REG_APUIO0 ; write P0 data
;--------------------------------------
: cmp REG_APUIO0 ; final sync
bne :- ;--------------------------------------
stz REG_APUIO0
stz spc_v ; reset V
stz spc_q ; reset Q
stz spc_fwrite ; reset command fifo
stz spc_fread ;
stz spc_sfx_next ;
stz spc_pr+0
stz spc_pr+1
stz spc_pr+2
stz spc_pr+3
;----------------------------------------------------------------------
; driver installation successful
;----------------------------------------------------------------------
rts ; return
;----------------------------------------------------------------------
There is a copy of the code that is the same except for local labels and uses SOUND_DRIVER_B and is called spcBootDriverB. While assembeld (ca65) the output is the same for both routines except for the driver address and number of bytes to transfer. Everything here is correct.
Right now there is no way I can get SOUND_DRIVER_A to work.
If I go back to the version which only has the ability to load one sound driver and I only include one sound driver (no matter which sound driver I include) then it will always work. I'm not sure why including the code for a second driver, and including the data for a second sound driver would cause any weirdness.
If I use SOUND_DRIVER_B data for both SOUND_DRIVER_B and SOUND_DRIVER_A than "A" works.
It looks like when I use SOUND_DRIVER_A the last thing written to $f2 is $17 which is gain, and the last value written to $f3 is $9e (%10011110, custom gain and gain rate). This shows me it's not processing pattern data because it's not cycling through the channels. The only thing being updated are the spc timers. I know what code would produce this value and it's the exact same code in SOUND_DRIVER_B. Most of the code between the sound drivers is the same, everything that handles the it pattern data is the same, as is everything which handles volume and such.
If I use the original snesmod code and only include 1 driver than it works no matter which driver I use. I do not understand why SOUND_DRIVER_A would "magically" (that word rather implies some sort of bug some where doesn't it?) work.
The only changes to snesmod.asm was having two different spcBoot routines (which are the same except for the data they read and the number of bytes they transfer), and sm_spc where I'm including two sound drivers instead of one.
Anyway I posted this because I thought if I wrote it out something might jump out at me and possibly somebody might have some ideas of things to check.