DSP Unmute

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

DSP Unmute

Post 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
Last edited by qwertymodo on Mon Oct 17, 2016 10:14 pm, edited 3 times in total.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DSP Unmute

Post 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.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: DSP Unmute

Post 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.)
Last edited by koitsu on Wed Aug 29, 2018 6:55 pm, edited 2 times in total.
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: DSP Unmute

Post by 93143 »

I'm thinking it would be a good idea to make sure echo is off.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: DSP Unmute

Post 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?
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: DSP Unmute

Post 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.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DSP Unmute

Post 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?
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: DSP Unmute

Post 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.)
Last edited by koitsu on Wed Aug 29, 2018 6:55 pm, edited 1 time in total.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: DSP Unmute

Post 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...
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: DSP Unmute

Post 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 -
Revenant
Posts: 455
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: DSP Unmute

Post by Revenant »

For time/convenience, you could also do:

Code: Select all

mov $F2, #$6C
mov $F3, #$20
...
The SPC has a couple of instructions that let you write directly to a zero page address without using a register.
Optiroc
Posts: 129
Joined: Thu Feb 07, 2013 1:15 am
Location: Sweden

Re: DSP Unmute

Post 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.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: DSP Unmute

Post 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 WayTM 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.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: DSP Unmute

Post 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
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: DSP Unmute

Post 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.
Post Reply