Page 1 of 2
DSP Unmute
Posted: Mon Oct 17, 2016 9:09 pm
by qwertymodo
I need to unmute the DSP in order to allow expansion audio to play. I understand that this requires uploading code to the SPC. Looking at
this document, the process looks pretty straightforward. However, this is only my second time even touching SPC code, and the first time was so far into a caffeine-fueled all-nighter, I am basically starting from scratch here. Now, all I want to do is unmute the DSP and then leave the SPC idle, so I feel like the SPC code should be as simple as:
Code: Select all
arch snes.smp
define REG_FLAG($6C)
define FLAG_ECHO(#$20)
define FLAG_MUTE(#$40)
lda {REG_FLAG} // E4 6C
ora {FLAG_ECHO} // 08 20
and ~{FLAG_MUTE} // 28 BF
sta {REG_FLAG} // C4 6C
-; bra - // 2F FE
The main thing missing from that link is the actual value of #SPCExec (the start-of-execution address). With that, it seems like all I need to do is transfer the 6-byte code block above and execute it, using the code example from that link verbatim, right? Or is there more to it than that?
Edit: derp, got my bitmask backwards
Re: DSP Unmute
Posted: Mon Oct 17, 2016 9:49 pm
by lidnariq
You probably can mimic Nocash's Magic Floor code and just instruct the SPC bootloader to write the "unmute" control to the relevant DSP register.
Re: DSP Unmute
Posted: Mon Oct 17, 2016 9:57 pm
by koitsu
Code provided by Nintendo back in the 90s is attached; the ! designator you see on the equates is to force 16-bit absolute addressing, the rest should be pretty obvious, barring the 1da/1dy instructions (likely an OCR mistake; should be lda/ldy). I'm attaching this just as a comparison example to what's on the wiki you linked. The actual SNES/SPC communication protocol is in fact officially documented if you'd prefer that.
(2018/08/29 Edit: attachments removed.)
Re: DSP Unmute
Posted: Mon Oct 17, 2016 10:01 pm
by 93143
I'm thinking it would be a good idea to make sure echo is off.
Re: DSP Unmute
Posted: Mon Oct 17, 2016 10:17 pm
by qwertymodo
I made a few stupid mistakes, like getting my bitmask backwards, and never storing the value back to the register. Updated those, and added in disabling echo, but still no luck. Watching the memory viewer in bsnes-plus, I at least see that the data is successfully transferred to the location I specified, it's just still not playing any sound. Maybe do I need to set the volume registers too? Do those affect the volume of audio coming from the cart pins?
Re: DSP Unmute
Posted: Mon Oct 17, 2016 10:36 pm
by koitsu
The SPC700 is on the main PCB of the SNES/SFC itself, not the cartridge. Audio provided by the cartridge itself (i.e. some sort of on-cart audio IC) is provided on cartridge pins 31 and 62, and is mixed into the literal audio output circuitry of the SNES -- it does not go through the SPC700. I.e. the on-cart audio IC needs to have a volume control itself, managed through some means of its own (maybe MMIO registers, etc.); the SNES/SFC cannot control this.
Re: DSP Unmute
Posted: Mon Oct 17, 2016 10:37 pm
by lidnariq
No, the MUTE signal is actually a trace that comes from the S-DSP to a BJT clamp that dramatically reduces the gain on the output amplifier. So for audio fed in through the expansion port, disabling that signal should be all that's necessary.
Do you know whether the S-SMP is executing the code you've uploaded?
Re: DSP Unmute
Posted: Mon Oct 17, 2016 10:59 pm
by koitsu
While I'm here: here are a couple official "cautions" -- the 2nd should be good reason not to use the code on that wiki (it does 16-bit writes to $2140/2141).
There has been a past discussion about the /MUTE line:
https://forums.nesdev.com/viewtopic.php?f=12&t=10585
Sorry for the attachment order (if they're out of order): I have no software that can easily let me make a long "strip" image from multiple images (please do not let this become a subject of discussion / derail thread subject).
(2018/08/29 Edit: attachments removed.)
Re: DSP Unmute
Posted: Tue Oct 18, 2016 12:23 am
by qwertymodo
lidnariq wrote:Do you know whether the S-SMP is executing the code you've uploaded?
If the bsnes-plus trace logger is to be believed, yes. Does the code itself look correct?
Code: Select all
..0100 mov a,$06c A:00 X:00 Y:00 SP:01ef YA:0000 nvpbhiZc
..0102 or a,#$20 A:00 X:00 Y:00 SP:01ef YA:0000 nvpbhiZc
..0104 and a,#$bf A:20 X:00 Y:00 SP:01ef YA:0020 nvpbhizc
..0106 mov $06c,a A:20 X:00 Y:00 SP:01ef YA:0020 nvpbhizc
..0108 bra $0108 A:20 X:00 Y:00 SP:01ef YA:0020 nvpbhizc
..0108 bra $0108 A:20 X:00 Y:00 SP:01ef YA:0020 nvpbhizc
..0108 bra $0108 A:20 X:00 Y:00 SP:01ef YA:0020 nvpbhizc
..0108 bra $0108 A:20 X:00 Y:00 SP:01ef YA:0020 nvpbhizc
Oh, wait. That's just writing to SPC RAM address $6C, I need to write to DSP register $6C. So much indirection...
Re: DSP Unmute
Posted: Tue Oct 18, 2016 12:40 am
by qwertymodo
Got it!
Code: Select all
arch snes.smp
lda #$6C // DSP Flag Register
sta $F2 // DSP Access Address
lda #$20 // RESET: Off, MUTE: Off, ECHO: Off, NCLK: 0Hz
sta $F3 // DSP Access Data
-; bra -
Re: DSP Unmute
Posted: Tue Oct 18, 2016 9:59 am
by Revenant
For time/convenience, you could also do:
The SPC has a couple of instructions that let you write directly to a zero page address without using a register.
Re: DSP Unmute
Posted: Tue Oct 18, 2016 12:38 pm
by Optiroc
Just as a side note it's good practice to jump back to the IPL (jmp !$ffc0 (yes, I seem to be one of the few here that prefers the "native" mnemonics

)) after executing a snippet like this, otherwise it's impossible to communicate with the SPC again until the SNES is reset.
Re: DSP Unmute
Posted: Tue Oct 18, 2016 12:49 pm
by qwertymodo
Optiroc wrote:Just as a side note it's good practice to jump back to the IPL (jmp !$ffc0 (yes, I seem to be one of the few here that prefers the "native" mnemonics

)) after executing a snippet like this, otherwise it's impossible to communicate with the SPC again until the SNES is reset.
I'll keep that in mind. For my current purposes though, unmuting the DSP is literally the only thing I ever want to do (this is for an MSU-1 video player), but it's always good to know The Right Way
TM to do things.
Edit: and apparently that fixed an issue I was having where higan v101 refused to lock to 60FPS and started freerunning, even with Synchronize Audio enabled.
Re: DSP Unmute
Posted: Tue Oct 18, 2016 3:50 pm
by qwertymodo
On real hardware, this is generating a very rapid popping sound, somewhere around ~8Hz. Looks like you need to set the echo volume to 0, even with the echo flag disabled. Here's the final (I hope), minimal code:
Code: Select all
arch snes.smp
str $F2=#$2C // DSP Echo Volume (Left)
str $F3=#$00 // Volume 0
str $F2=#$3C // DSP Echo Volume (Right)
str $F3=#$00 // Volume 0
str $F2=#$6C // DSP Flag Register
str $F3=#$20 // RESET: Off, MUTE: Off, ECHO: Off, NCLK: 0Hz
jmp $FFC0 // Return to IPLROM
Re: DSP Unmute
Posted: Tue Oct 18, 2016 6:52 pm
by AWJ
qwertymodo wrote:On real hardware, this is generating a very rapid popping sound, somewhere around ~8Hz. Looks like you need to set the echo volume to 0, even with the echo flag disabled. Here's the final (I hope), minimal code:
Code: Select all
arch snes.smp
str $F2=#$2C // DSP Echo Volume (Left)
str $F3=#$00 // Volume 0
str $F2=#$3C // DSP Echo Volume (Right)
str $F3=#$00 // Volume 0
str $F2=#$6C // DSP Flag Register
str $F3=#$20 // RESET: Off, MUTE: Off, ECHO: Off, NCLK: 0Hz
jmp $FFC0 // Return to IPLROM
Sounds like the DSP is reading and outputting uninitialized APU RAM as echo data. DSP register $63.d5 only disables writing into the echo buffer, not reading and mixing it into the final output.