mirror of https://github.com/mgba-emu/mgba.git
GBA I/O: Fix audio register 8-bit write behavior (fixes #3086)
This commit is contained in:
parent
9271198f64
commit
f778cf4749
1
CHANGES
1
CHANGES
|
@ -4,6 +4,7 @@ Emulation fixes:
|
|||
- GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501)
|
||||
- GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141)
|
||||
- GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309)
|
||||
- GBA I/O: Fix audio register 8-bit write behavior (fixes mgba.io/i/3086)
|
||||
- GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110)
|
||||
Other fixes:
|
||||
- GB: Fix uninitialized save data when loading undersized temporary saves
|
||||
|
|
106
src/gba/io.c
106
src/gba/io.c
|
@ -378,17 +378,19 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
break;
|
||||
case REG_SOUND1CNT_HI:
|
||||
GBAAudioWriteSOUND1CNT_HI(&gba->audio, value);
|
||||
value &= 0xFFC0;
|
||||
break;
|
||||
case REG_SOUND1CNT_X:
|
||||
GBAAudioWriteSOUND1CNT_X(&gba->audio, value);
|
||||
value &= 0x47FF;
|
||||
value &= 0x4000;
|
||||
break;
|
||||
case REG_SOUND2CNT_LO:
|
||||
GBAAudioWriteSOUND2CNT_LO(&gba->audio, value);
|
||||
value &= 0xFFC0;
|
||||
break;
|
||||
case REG_SOUND2CNT_HI:
|
||||
GBAAudioWriteSOUND2CNT_HI(&gba->audio, value);
|
||||
value &= 0x47FF;
|
||||
value &= 0x4000;
|
||||
break;
|
||||
case REG_SOUND3CNT_LO:
|
||||
GBAAudioWriteSOUND3CNT_LO(&gba->audio, value);
|
||||
|
@ -396,16 +398,15 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
|||
break;
|
||||
case REG_SOUND3CNT_HI:
|
||||
GBAAudioWriteSOUND3CNT_HI(&gba->audio, value);
|
||||
value &= 0xE03F;
|
||||
value &= 0xE000;
|
||||
break;
|
||||
case REG_SOUND3CNT_X:
|
||||
GBAAudioWriteSOUND3CNT_X(&gba->audio, value);
|
||||
// TODO: The low bits need to not be readable, but still 8-bit writable
|
||||
value &= 0x47FF;
|
||||
value &= 0x4000;
|
||||
break;
|
||||
case REG_SOUND4CNT_LO:
|
||||
GBAAudioWriteSOUND4CNT_LO(&gba->audio, value);
|
||||
value &= 0xFF3F;
|
||||
value &= 0xFF00;
|
||||
break;
|
||||
case REG_SOUND4CNT_HI:
|
||||
GBAAudioWriteSOUND4CNT_HI(&gba->audio, value);
|
||||
|
@ -637,9 +638,96 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
|
|||
if (address > SIZE_IO) {
|
||||
return;
|
||||
}
|
||||
uint16_t value16 = value << (8 * (address & 1));
|
||||
value16 |= (gba->memory.io[(address & (SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1)));
|
||||
GBAIOWrite(gba, address & 0xFFFFFFFE, value16);
|
||||
uint16_t value16;
|
||||
|
||||
switch (address) {
|
||||
case REG_SOUND1CNT_HI:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR11(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND1CNT_HI >> 1] &= 0xFF00;
|
||||
gba->memory.io[REG_SOUND1CNT_HI >> 1] |= value & 0xC0;
|
||||
break;
|
||||
case REG_SOUND1CNT_HI + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR12(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND1CNT_HI >> 1] &= 0x00C0;
|
||||
gba->memory.io[REG_SOUND1CNT_HI >> 1] |= value << 8;
|
||||
break;
|
||||
case REG_SOUND1CNT_X:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR13(&gba->audio.psg, value);
|
||||
break;
|
||||
case REG_SOUND1CNT_X + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR14(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND1CNT_X >> 1] = (value & 0x40) << 8;
|
||||
break;
|
||||
case REG_SOUND2CNT_LO:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR21(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND2CNT_LO >> 1] &= 0xFF00;
|
||||
gba->memory.io[REG_SOUND2CNT_LO >> 1] |= value & 0xC0;
|
||||
break;
|
||||
case REG_SOUND2CNT_LO + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR22(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND2CNT_LO >> 1] &= 0x00C0;
|
||||
gba->memory.io[REG_SOUND2CNT_LO >> 1] |= value << 8;
|
||||
break;
|
||||
case REG_SOUND2CNT_HI:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR23(&gba->audio.psg, value);
|
||||
break;
|
||||
case REG_SOUND2CNT_HI + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR24(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND2CNT_HI >> 1] = (value & 0x40) << 8;
|
||||
break;
|
||||
case REG_SOUND3CNT_HI:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR31(&gba->audio.psg, value);
|
||||
break;
|
||||
case REG_SOUND3CNT_HI + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
gba->audio.psg.ch3.volume = GBAudioRegisterBankVolumeGetVolumeGBA(value);
|
||||
gba->memory.io[REG_SOUND3CNT_HI >> 1] = (value & 0xE0) << 8;
|
||||
break;
|
||||
case REG_SOUND3CNT_X:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR33(&gba->audio.psg, value);
|
||||
break;
|
||||
case REG_SOUND3CNT_X + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR34(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND3CNT_X >> 1] = (value & 0x40) << 8;
|
||||
break;
|
||||
case REG_SOUND4CNT_LO:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR41(&gba->audio.psg, value);
|
||||
break;
|
||||
case REG_SOUND4CNT_LO + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR42(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND4CNT_LO >> 1] = value << 8;
|
||||
break;
|
||||
case REG_SOUND4CNT_HI:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR43(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND4CNT_HI >> 1] &= 0x4000;
|
||||
gba->memory.io[REG_SOUND4CNT_HI >> 1] |= value;
|
||||
break;
|
||||
case REG_SOUND4CNT_HI + 1:
|
||||
GBAAudioSample(&gba->audio, mTimingCurrentTime(&gba->timing));
|
||||
GBAudioWriteNR44(&gba->audio.psg, value);
|
||||
gba->memory.io[REG_SOUND4CNT_HI >> 1] &= 0x00FF;
|
||||
gba->memory.io[REG_SOUND4CNT_HI >> 1] |= (value & 0x40) << 8;
|
||||
break;
|
||||
default:
|
||||
value16 = value << (8 * (address & 1));
|
||||
value16 |= (gba->memory.io[(address & (SIZE_IO - 1)) >> 1]) & ~(0xFF << (8 * (address & 1)));
|
||||
GBAIOWrite(gba, address & 0xFFFFFFFE, value16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
|
||||
|
|
Loading…
Reference in New Issue