From 9b6b7c73929b8be963d0d453f3a41a60eb87bef0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 15 Jan 2022 20:32:50 -0800 Subject: [PATCH] GBA DMA: Fix DMA source direction bits being cleared (fixes #2410) --- CHANGES | 1 + src/gba/dma.c | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 74f434bb2..8a20eda57 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Emulation fixes: - GB Video: Draw SGB border pieces that overlap GB graphics (fixes mgba.io/i/1339) - GBA: Improve timing when not booting from BIOS - GBA BIOS: Work around IRQ handling hiccup in Mario & Luigi (fixes mgba.io/i/1059) + - GBA DMA: Fix DMA source direction bits being cleared (fixes mgba.io/i/2410) - GBA I/O: Redo internal key input, enabling edge-based key IRQs - GBA I/O: Disable open bus behavior on invalid register 06A - GBA Memory: Fix misaligned 32-bit I/O loads (fixes mgba.io/i/2307) diff --git a/src/gba/dma.c b/src/gba/dma.c index d30f0291a..5807e506f 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -83,9 +83,6 @@ uint16_t GBADMAWriteCNT_HI(struct GBA* gba, int dma, uint16_t control) { if (!wasEnabled && GBADMARegisterIsEnable(currentDma->reg)) { currentDma->nextSource = currentDma->source; - if (currentDma->nextSource >= BASE_CART0 && currentDma->nextSource < BASE_CART_SRAM && GBADMARegisterGetSrcControl(currentDma->reg) < 3) { - currentDma->reg = GBADMARegisterClearSrcControl(currentDma->reg); - } currentDma->nextDest = currentDma->dest; uint32_t width = 2 << GBADMARegisterGetWidth(currentDma->reg); @@ -291,7 +288,13 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { } gba->bus = memory->dmaTransferRegister; } - int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width; + + int sourceOffset; + if (info->nextSource >= BASE_CART0 && info->nextSource < BASE_CART_SRAM && GBADMARegisterGetSrcControl(info->reg) < 3) { + sourceOffset = width; + } else { + sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width; + } int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width; if (source) { source += sourceOffset;