all repos — mgba @ 1e1c8fd2ddc42a2cb55b1e34c0660cf7d0168d18

mGBA Game Boy Advance Emulator

Ensure that DMAs read back from I/O memory properly
Jeffrey Pfau jeffrey@endrift.com
Thu, 18 Apr 2013 00:58:22 -0700
commit

1e1c8fd2ddc42a2cb55b1e34c0660cf7d0168d18

parent

4f8c288f20a66c9a2606ca071adcaacb2c079f64

3 files changed, 18 insertions(+), 6 deletions(-)

jump to
M src/gba/gba-io.csrc/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.csrc/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.hsrc/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);