GBA Audio: Revert 16-bit audio FIFO write behavior outside of DMAs
Jeffrey Pfau jeffrey@endrift.com
Sat, 17 Jan 2015 09:16:49 -0800
4 files changed,
22 insertions(+),
6 deletions(-)
M
src/gba/gba-io.c
→
src/gba/gba-io.c
@@ -366,11 +366,23 @@ case REG_WAVE_RAM3_HI:
GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16)); break; + // TODO: Confirm this behavior on real hardware case REG_FIFO_A_LO: case REG_FIFO_B_LO: + if (gba->performingDMA) { + GBAAudioWriteFIFO16(&gba->audio, address, value); + } else { + GBAIOWrite32(gba, address, (gba->memory.io[(address >> 1) + 1] << 16) | value); + } + break; + case REG_FIFO_A_HI: case REG_FIFO_B_HI: - GBAAudioWriteFIFO16(&gba->audio, address, value); + if (gba->performingDMA) { + GBAAudioWriteFIFO16(&gba->audio, address, value); + } else { + GBAIOWrite32(gba, address - 2, gba->memory.io[(address >> 1) - 1] | (value << 16)); + } break; // DMA
M
src/gba/gba-memory.c
→
src/gba/gba-memory.c
@@ -172,7 +172,7 @@ }
#define LOAD_BAD \ GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address); \ - if (cpu->cycles >= cpu->nextEvent) { \ + if (gba->performingDMA) { \ value = gba->bus; \ } else { \ value = cpu->prefetch[1]; \@@ -301,7 +301,7 @@ LOAD_16(value, address & 2, &memory->biosPrefetch);
} } else { GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address); - if (cpu->cycles >= cpu->nextEvent) { + if (gba->performingDMA) { LOAD_16(value, address & 2, &gba->bus); } else { LOAD_16(value, address & 2, &cpu->prefetch[1]);@@ -363,7 +363,7 @@ value |= value << 8;
break; default: GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address); - if (cpu->cycles >= cpu->nextEvent) { + if (gba->performingDMA) { LOAD_16(value, address & 2, &gba->bus); } else { LOAD_16(value, address & 2, &cpu->prefetch[1]);@@ -396,7 +396,7 @@ value = ((uint8_t*) &memory->biosPrefetch)[address & 3];
} } else { GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address); - if (cpu->cycles >= cpu->nextEvent) { + if (gba->performingDMA) { value = ((uint8_t*) &gba->bus)[address & 3]; } else { value = ((uint8_t*) &cpu->prefetch[1])[address & 3];@@ -460,7 +460,7 @@ }
break; default: GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address); - if (cpu->cycles >= cpu->nextEvent) { + if (gba->performingDMA) { value = ((uint8_t*) &gba->bus)[address & 3]; } else { value = ((uint8_t*) &cpu->prefetch[1])[address & 3];@@ -1138,6 +1138,7 @@ cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion];
} } + gba->performingDMA = true; int32_t word; if (width == 4) { word = cpu->memory.load32(cpu, source, 0);@@ -1174,6 +1175,7 @@ dest += destOffset;
--wordsRemaining; } } + gba->performingDMA = false; if (!wordsRemaining) { if (!GBADMARegisterIsRepeat(info->reg) || GBADMARegisterGetTiming(info->reg) == DMA_TIMING_NOW) {
M
src/gba/gba.c
→
src/gba/gba.c
@@ -76,6 +76,7 @@
gba->biosChecksum = GBAChecksum(gba->memory.bios, SIZE_BIOS); gba->busyLoop = -1; + gba->performingDMA = false; } void GBADestroy(struct GBA* gba) {
M
src/gba/gba.h
→
src/gba/gba.h
@@ -112,6 +112,7 @@
struct ARMDebugger* debugger; uint32_t bus; + bool performingDMA; int timersEnabled; struct GBATimer timers[4];