Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSP: Fix write masks on AUDIO_*/AR_* MMIO registers #9392

Merged
merged 1 commit into from Jan 5, 2021

Conversation

smurf3tte
Copy link
Contributor

https://bugs.dolphin-emu.org/issues/6749

This change fixes the scratchy audio in Teenage Mutant Ninja Turtles (SX7E52/SX7P52). The game starts an audio interface DMA with an unaligned address, and because Dolphin was not masking off the low 5 bits of AUDIO_DMA_START_LO, all future AI DMAs were misaligned. To understand why, it is instructive to refer to AUDIO_InitDMA() in libogc, which behaves the same as the official SDK:

_dspReg[25] = (_dspReg[25]&~0xffe0)|(startaddr&0xffff);

The implementation does not mask off the low bits of the passed in value before it ORs them with low bits of the current register value. Therefore, if they are not masked off by the hardware itself, they become permanently stuck once set.

Adding a write mask for AUDIO_DMA_START_LO is enough to fix the bug in TMNT, but I decided to run some tests on GC and Wii to find the correct write masks for the surrounding registers, as only a couple were already being masked. Dolphin has gotten away with not masking the rest because many are already A) masked on read (or never read) by the SDK and/or B) masked on use (or never used) in Dolphin.

This leaves just three registers where the difference may be observable: AR_DMA_CNT_H and AUDIO_DMA_START_HI/LO.

Source/Core/Core/HW/DSP.cpp Outdated Show resolved Hide resolved
Source/Core/Core/HW/DSP.cpp Outdated Show resolved Hide resolved
@JMC47
Copy link
Contributor

JMC47 commented Dec 29, 2020

Fixes The Bachelor for Wii as well.

https://bugs.dolphin-emu.org/issues/6749

This change fixes the scratchy audio in Teenage Mutant Ninja Turtles (SX7E52/SX7P52). The game starts an audio interface DMA with an unaligned address, and because Dolphin was not masking off the low 5 bits of AUDIO_DMA_START_LO, all future AI DMAs were misaligned. To understand why, it is instructive to refer to AUDIO_InitDMA() in libogc, which behaves the same as the official SDK:

_dspReg[25] = (_dspReg[25]&~0xffe0)|(startaddr&0xffff);

The implementation does not mask off the low bits of the passed in value before it ORs them with low bits of the current register value. Therefore, if they are not masked off by the hardware itself, they become permanently stuck once set.

Adding a write mask for AUDIO_DMA_START_LO is enough to fix the bug in TMNT, but I decided to run some tests on GC and Wii to find the correct write masks for the surrounding registers, as only a couple were already being masked. Dolphin has gotten away with not masking the rest because many are already A) masked on read (or never read) by the SDK and/or B) masked on use (or never used) in Dolphin.

This leaves just three registers where the difference may be observable: AR_DMA_CNT_H and AUDIO_DMA_START_HI/LO.
Copy link
Member

@BhaaLseN BhaaLseN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good, untested

@Silanda
Copy link

Silanda commented Dec 31, 2020

It looks like this fixes Dragon's Lair Trilogy too: https://bugs.dolphin-emu.org/issues/12349

@delroth
Copy link
Member

delroth commented Jan 5, 2021

LGTM, configmed with @smurf3tte that this was hardware tested and that the register masking does happen when writing and not in the DMA engine itself.

@delroth delroth merged commit bd89523 into dolphin-emu:master Jan 5, 2021
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
6 participants