Ensure that DMAs read back from I/O memory properly
Jeffrey Pfau jeffrey@endrift.com
Thu, 18 Apr 2013 00:58:22 -0700
3 files changed,
18 insertions(+),
6 deletions(-)
M
src/gba/gba-io.c
→
src/gba/gba-io.c
@@ -11,25 +11,25 @@ case REG_DMA0CNT_LO:
GBAMemoryWriteDMACNT_LO(&gba->memory, 0, value); break; case REG_DMA0CNT_HI: - GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value); + value = GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value); break; case REG_DMA1CNT_LO: GBAMemoryWriteDMACNT_LO(&gba->memory, 1, value); break; case REG_DMA1CNT_HI: - GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value); + value = GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value); break; case REG_DMA2CNT_LO: GBAMemoryWriteDMACNT_LO(&gba->memory, 2, value); break; case REG_DMA2CNT_HI: - GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value); + value = GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value); break; case REG_DMA3CNT_LO: GBAMemoryWriteDMACNT_LO(&gba->memory, 3, value); break; case REG_DMA3CNT_HI: - GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value); + value = GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value); break; case REG_WAITCNT:@@ -94,6 +94,16 @@ switch (address) {
case REG_DISPSTAT: return GBAVideoReadDISPSTAT(&gba->video); break; + case REG_DMA0CNT_LO: + case REG_DMA1CNT_LO: + case REG_DMA2CNT_LO: + case REG_DMA3CNT_LO: + // Write-only register + return 0; + case REG_DMA0CNT_HI: + case REG_DMA1CNT_HI: + case REG_DMA2CNT_HI: + case REG_DMA3CNT_HI: case REG_IE: case REG_WAITCNT: case REG_IME:
M
src/gba/gba-memory.c
→
src/gba/gba-memory.c
@@ -461,7 +461,7 @@ void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count) {
memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000); } -void GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control) { +uint16_t GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control) { struct GBADMA* currentDma = &memory->dma[dma]; int wasEnabled = currentDma->enable; currentDma->packed = control;@@ -477,6 +477,8 @@ currentDma->nextDest = currentDma->dest;
currentDma->nextCount = currentDma->count; GBAMemoryScheduleDMA(memory, dma, currentDma); } + // If the DMA has already occurred, this value might have changed since the function started + return currentDma->packed; }; void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info) {
M
src/gba/gba-memory.h
→
src/gba/gba-memory.h
@@ -134,7 +134,7 @@
void GBAMemoryWriteDMASAD(struct GBAMemory* memory, int dma, uint32_t address); void GBAMemoryWriteDMADAD(struct GBAMemory* memory, int dma, uint32_t address); void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count); -void GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control); +uint16_t GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control); void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info); void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* info);