GBA Audio: Fix reads from CH3 Wave RAM

The previous code always read the state of bank 0. The correct behaviour
is to read from the bank that isn't selected. Most likely, no game has
ever tried to read from this RAM and verify the values because the
values are destroyed as soon as the channel starts to play the desired
sound.

Writes were done correctly: The values are saved to the bank that isn't
selected.

Also, when the sound hardware is off, it acts like bank 0 has been
selected in register SOUND3CNT_L.
This commit is contained in:
Antonio Niño Díaz 2021-03-21 18:30:58 +00:00 committed by Vicki Pfau
parent 853c64b326
commit c0cfa602af
3 changed files with 46 additions and 9 deletions

View File

@ -304,6 +304,7 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value);
void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value);
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
uint32_t GBAAudioReadWaveRAM(struct GBAAudio* audio, int address);
uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles);

View File

@ -221,7 +221,27 @@ void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) {
}
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
audio->psg.ch3.wavedata32[address | (!audio->psg.ch3.bank * 4)] = value;
int bank = !audio->psg.ch3.bank;
// When the audio hardware is turned off, it acts like bank 0 has been
// selected in SOUND3CNT_L, so any read comes from bank 1.
if (!audio->enable) {
bank = 1;
}
audio->psg.ch3.wavedata32[address | (bank * 4)] = value;
}
uint32_t GBAAudioReadWaveRAM(struct GBAAudio* audio, int address) {
int bank = !audio->psg.ch3.bank;
// When the audio hardware is turned off, it acts like bank 0 has been
// selected in SOUND3CNT_L, so any read comes from bank 1.
if (!audio->enable) {
bank = 1;
}
return audio->psg.ch3.wavedata32[address | (bank * 4)];
}
uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {

View File

@ -616,6 +616,9 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
switch (address) {
// Wave RAM can be written and read even if the audio hardware is disabled.
// However, it is not possible to switch between the two banks because it
// isn't possible to write to register SOUND3CNT_LO.
case REG_WAVE_RAM0_LO:
GBAAudioWriteWaveRAM(&gba->audio, 0, value);
break;
@ -833,6 +836,27 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case REG_POSTFLG:
mLOG(GBA_IO, STUB, "Stub I/O register read: %03x", address);
break;
// Wave RAM can be written and read even if the audio hardware is disabled.
// However, it is not possible to switch between the two banks because it
// isn't possible to write to register SOUND3CNT_LO.
case REG_WAVE_RAM0_LO:
return GBAAudioReadWaveRAM(&gba->audio, 0) & 0xFFFF;
case REG_WAVE_RAM0_HI:
return GBAAudioReadWaveRAM(&gba->audio, 0) >> 16;
case REG_WAVE_RAM1_LO:
return GBAAudioReadWaveRAM(&gba->audio, 1) & 0xFFFF;
case REG_WAVE_RAM1_HI:
return GBAAudioReadWaveRAM(&gba->audio, 1) >> 16;
case REG_WAVE_RAM2_LO:
return GBAAudioReadWaveRAM(&gba->audio, 2) & 0xFFFF;
case REG_WAVE_RAM2_HI:
return GBAAudioReadWaveRAM(&gba->audio, 2) >> 16;
case REG_WAVE_RAM3_LO:
return GBAAudioReadWaveRAM(&gba->audio, 3) & 0xFFFF;
case REG_WAVE_RAM3_HI:
return GBAAudioReadWaveRAM(&gba->audio, 3) >> 16;
case REG_SOUND1CNT_LO:
case REG_SOUND1CNT_HI:
case REG_SOUND1CNT_X:
@ -863,14 +887,6 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case REG_BLDALPHA:
case REG_SOUNDCNT_HI:
case REG_SOUNDCNT_X:
case REG_WAVE_RAM0_LO:
case REG_WAVE_RAM0_HI:
case REG_WAVE_RAM1_LO:
case REG_WAVE_RAM1_HI:
case REG_WAVE_RAM2_LO:
case REG_WAVE_RAM2_HI:
case REG_WAVE_RAM3_LO:
case REG_WAVE_RAM3_HI:
case REG_DMA0CNT_HI:
case REG_DMA1CNT_HI:
case REG_DMA2CNT_HI: