APU writes in Dr Mario may suggest new APU inner workings

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
APU writes in Dr Mario may suggest new APU inner workings
by on (#104468)
DFEF 8D STA $4013 A:07 X:03 Y:F4 P:A5 SP:F6 Cy:623422743 NTIC
DFF2 8C STY $4012 A:07 X:03 Y:F4 P:A5 SP:F6 Cy:623422747 NTIC
DFF5 AD LDA $06F7 A:07 X:03 Y:F4 P:A5 SP:F6 Cy:623422751 NTIC
DFF8 D0 BNE $E00E A:00 X:03 Y:F4 P:27 SP:F6 Cy:623422755 TIZC
DFFA A5 LDA $E1 A:00 X:03 Y:F4 P:27 SP:F6 Cy:623422757 TIZC
DFFC 8D STA $4010 A:07 X:03 Y:F4 P:25 SP:F6 Cy:623422760 TIC
DFFF A9 LDA #$0F A:07 X:03 Y:F4 P:25 SP:F6 Cy:623422764 TIC
E001 8D STA $4015 A:0F X:03 Y:F4 P:25 SP:F6 Cy:623422766 TIC
E004 A9 LDA #$00 A:0F X:03 Y:F4 P:25 SP:F6 Cy:623422770 TIC
E006 8D STA $4011 A:00 X:03 Y:F4 P:27 SP:F6 Cy:623422772 TIZC
E009 A9 LDA #$1F A:00 X:03 Y:F4 P:27 SP:F6 Cy:623422776 TIZC
E00B 8D STA $4015 A:1F X:03 Y:F4 P:25 SP:F6 Cy:623422778 TIC


Notice that it disables the DMC channel, sets the DAC value and linear counter, then re-enables the DMC channel. This behavior might suggest that the current DAC value is only set immediately when the channel is enabled, where as the linear counter is the only thing set always on write.
Re: APU writes in Dr Mario may suggest new APU inner working
by on (#104473)
The DMC counter ($4011) can be set at any time, it is not dependent on the bit in $4015. Plenty of games do this, especially any that play PCM sounds. You can also set it while the DPCM playback is ongoing (causing a pop), not sure if any games do this but it's easily verifiable on hardware.

I don't remember offhand, but I believe the sample address and length are only loaded when playback begins (toggling $4015 bit) or when the length counter runs out in looped mode (causing an automatic restart). This has been used by some to loop samples without having to start the loop at the beginning. So, unless looped mode is on, it's perfectly safe to change $4012/4013 before you clear the bit in $4015.
Re: APU writes in Dr Mario may suggest new APU inner working
by on (#104478)
I remember seeing several games do unnecessary writes to the APU that probably revealed the programmers' misunderstanding of how the APU worked, or their cautious use of it. Some of them suggested different behavior than there actually is.
Re: APU writes in Dr Mario may suggest new APU inner working
by on (#104480)
Cool, figured I would consult the experts and they have spoken. Have you tested this specifically or something like it Blargg? Since Dr Mario is an official Nintendo title, I figured they might be more accurate in their hardware use than other games. Sounds like your pretty sure though.

Specifically emulating this incorrectly would only manifest itself as a momentary pop and only when a current dmc sample is playing. So it may have gone unnoticed as that situation isn't common in most games that I know of.
Re: APU writes in Dr Mario may suggest new APU inner working
by on (#104481)
Also, if this wasn't clear, it is safe to write $4012/4013 when the $4015 bit is clear as well. The one thing you should probably do is clear the loop flag if it's being used before setting $4012/4013, so you don't have a chance of reloading the loop to the wrong sample... but since you're probably about to restart it again within a few cycles, even if you forgot to do this the difference would be negligible.
Re: APU writes in Dr Mario may suggest new APU inner working
by on (#104490)
I'm not claiming that there's not something here, just that it's unlikely. I can't remember what happens when a $4011 write occurs at the same time as a DMC sample delta bit trying to increment/decrement $4011.
Re: APU writes in Dr Mario may suggest new APU inner working
by on (#104491)
Ah, yeah you're right there is a potential conflict there. I'd done $4011 writes during DPCM playback, but I'd never checked to see what happens if it conflicts with the DPCM (since the consequences of a missed $4011 are kinda minor). I just tested it. So far it looks like the DPCM unit takes precedence over $4011 if there is a conflict?

Edit: Okay, I've tested interrupting a downward DPCM with $7F writes, and an upward DPCM with $00 writes. Both are missing the $4011 result on occasion. Interestingly, if the DPCM is clamping, I don't see any conflicts, which makes me think the DPCM unit actually suppresses its write if the result would go under 00 / over $7F. It does apparently still happen even when the DPCM would be clamping, though it strangely seems less frequent in this case.

I guess the conflict could be going both ways; from my preliminary tests I guess I couldn't really pick out a missing DPCM write (I'll have to think of a way to test this). I also have no idea if there could be a bus conflict on write sometimes, and what that might do electrically. Maybe someone could determine this from the Visual 2A03. Anyhow, there is at least a conflict that can keep a $4011 write from happening.