all repos — mgba @ d08a0fef0155213731300833105f8c459624b558

mGBA Game Boy Advance Emulator

GBA Memory: Optimize DMA
Jeffrey Pfau jeffrey@endrift.com
Mon, 31 Oct 2016 02:37:00 -0700
commit

d08a0fef0155213731300833105f8c459624b558

parent

fa3d263dd9da2ea4cf0e580c7cb4931b4c8b69d0

1 files changed, 11 insertions(+), 25 deletions(-)

jump to
M src/gba/memory.csrc/gba/memory.c

@@ -1643,9 +1643,7 @@

void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) { struct GBAMemory* memory = &gba->memory; struct ARMCore* cpu = gba->cpu; - uint32_t width = GBADMARegisterGetWidth(info->reg) ? 4 : 2; - int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width; - int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width; + uint32_t width = 2 << GBADMARegisterGetWidth(info->reg); int32_t wordsRemaining = info->nextCount; uint32_t source = info->nextSource; uint32_t dest = info->nextDest;

@@ -1660,8 +1658,6 @@ cycles += 2;

} if (width == 4) { cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion]; - source &= 0xFFFFFFFC; - dest &= 0xFFFFFFFC; } else { cycles += memory->waitstatesNonseq16[sourceRegion] + memory->waitstatesNonseq16[destRegion]; }

@@ -1672,6 +1668,8 @@ GBAMemoryUpdateDMAs(gba, -cycles);

return; } info->hasStarted = 2; + source &= -width; + dest &= -width; } else { if (width == 4) { cycles += memory->waitstatesSeq32[sourceRegion] + memory->waitstatesSeq32[destRegion];

@@ -1679,44 +1677,36 @@ } else {

cycles += memory->waitstatesSeq16[sourceRegion] + memory->waitstatesSeq16[destRegion]; } } + info->nextEvent += cycles; gba->performingDMA = 1 | (number << 1); - int32_t word; + uint32_t word; if (width == 4) { word = cpu->memory.load32(cpu, source, 0); gba->bus = word; cpu->memory.store32(cpu, dest, word, 0); - source += sourceOffset; - dest += destOffset; - --wordsRemaining; } else { if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) { word = GBASavedataReadEEPROM(&memory->savedata); - gba->bus = word | (word << 16); cpu->memory.store16(cpu, dest, word, 0); - source += sourceOffset; - dest += destOffset; - --wordsRemaining; } else if (destRegion == REGION_CART2_EX) { if (memory->savedata.type == SAVEDATA_AUTODETECT) { mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); GBASavedataInitEEPROM(&memory->savedata, gba->realisticTiming); } word = cpu->memory.load16(cpu, source, 0); - gba->bus = word | (word << 16); GBASavedataWriteEEPROM(&memory->savedata, word, wordsRemaining); - source += sourceOffset; - dest += destOffset; - --wordsRemaining; } else { word = cpu->memory.load16(cpu, source, 0); - gba->bus = word | (word << 16); cpu->memory.store16(cpu, dest, word, 0); - source += sourceOffset; - dest += destOffset; - --wordsRemaining; } + gba->bus = word | (word << 16); } + int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width; + int destOffset = DMA_OFFSET[GBADMARegisterGetDestControl(info->reg)] * width; + source += sourceOffset; + dest += destOffset; + --wordsRemaining; gba->performingDMA = 0; if (!wordsRemaining) {

@@ -1741,10 +1731,6 @@ info->nextDest = dest;

info->nextCount = wordsRemaining; } info->nextSource = source; - - if (info->nextEvent != INT_MAX) { - info->nextEvent += cycles; - } GBAMemoryUpdateDMAs(gba, 0); }