mirror of https://github.com/mgba-emu/mgba.git
GBA DMA: Linger last DMA on bus (fixes mgba.io/i/301, fixes mgba.io/i/1320)
This commit is contained in:
parent
38613e1c78
commit
93633ea605
1
CHANGES
1
CHANGES
|
@ -2,6 +2,7 @@
|
||||||
Emulation fixes:
|
Emulation fixes:
|
||||||
- ARM: Fix ALU reading PC after shifting
|
- ARM: Fix ALU reading PC after shifting
|
||||||
- ARM: Fix STR storing PC after address calculation
|
- ARM: Fix STR storing PC after address calculation
|
||||||
|
- GBA DMA: Linger last DMA on bus (fixes mgba.io/i/301 and mgba.io/i/1320)
|
||||||
- GBA Memory: Misaligned SRAM writes are ignored
|
- GBA Memory: Misaligned SRAM writes are ignored
|
||||||
- GBA Serialize: Fix serializing DMA transfer register
|
- GBA Serialize: Fix serializing DMA transfer register
|
||||||
Other fixes:
|
Other fixes:
|
||||||
|
|
|
@ -109,6 +109,7 @@ struct GBA {
|
||||||
bool haltPending;
|
bool haltPending;
|
||||||
bool cpuBlocked;
|
bool cpuBlocked;
|
||||||
bool earlyExit;
|
bool earlyExit;
|
||||||
|
uint32_t dmaPC;
|
||||||
int idleDetectionStep;
|
int idleDetectionStep;
|
||||||
int idleDetectionFailures;
|
int idleDetectionFailures;
|
||||||
int32_t cachedRegisters[16];
|
int32_t cachedRegisters[16];
|
||||||
|
|
|
@ -300,8 +300,9 @@ struct GBASerializedState {
|
||||||
} hw;
|
} hw;
|
||||||
|
|
||||||
uint32_t dmaTransferRegister;
|
uint32_t dmaTransferRegister;
|
||||||
|
uint32_t dmaBlockPC;
|
||||||
|
|
||||||
uint32_t reservedHardware[5];
|
uint32_t reservedHardware[4];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
|
@ -219,6 +219,7 @@ void GBADMAUpdate(struct GBA* gba) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memory->activeDMA >= 0) {
|
if (memory->activeDMA >= 0) {
|
||||||
|
gba->dmaPC = gba->cpu->gprs[ARM_PC];
|
||||||
mTimingDeschedule(&gba->timing, &memory->dmaEvent);
|
mTimingDeschedule(&gba->timing, &memory->dmaEvent);
|
||||||
mTimingSchedule(&gba->timing, &memory->dmaEvent, memory->dma[memory->activeDMA].when - currentTime);
|
mTimingSchedule(&gba->timing, &memory->dmaEvent, memory->dma[memory->activeDMA].when - currentTime);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -203,6 +203,7 @@ void GBAReset(struct ARMCore* cpu) {
|
||||||
|
|
||||||
gba->cpuBlocked = false;
|
gba->cpuBlocked = false;
|
||||||
gba->earlyExit = false;
|
gba->earlyExit = false;
|
||||||
|
gba->dmaPC = 0;
|
||||||
if (gba->yankedRomSize) {
|
if (gba->yankedRomSize) {
|
||||||
gba->memory.romSize = gba->yankedRomSize;
|
gba->memory.romSize = gba->yankedRomSize;
|
||||||
gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
|
gba->memory.romMask = toPow2(gba->memory.romSize) - 1;
|
||||||
|
|
|
@ -951,6 +951,7 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
|
STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
|
||||||
|
STORE_32(gba->dmaPC, 0, &state->dmaBlockPC);
|
||||||
|
|
||||||
GBAHardwareSerialize(&gba->memory.hw, state);
|
GBAHardwareSerialize(&gba->memory.hw, state);
|
||||||
}
|
}
|
||||||
|
@ -995,6 +996,7 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
||||||
GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
|
GBAAudioWriteSOUNDCNT_X(&gba->audio, gba->memory.io[REG_SOUNDCNT_X >> 1]);
|
||||||
|
|
||||||
LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
|
LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister);
|
||||||
|
LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC);
|
||||||
|
|
||||||
GBADMAUpdate(gba);
|
GBADMAUpdate(gba);
|
||||||
GBAHardwareDeserialize(&gba->memory.hw, state);
|
GBAHardwareDeserialize(&gba->memory.hw, state);
|
||||||
|
|
|
@ -337,7 +337,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOAD_BAD \
|
#define LOAD_BAD \
|
||||||
if (gba->performingDMA) { \
|
if (gba->performingDMA || cpu->gprs[ARM_PC] - gba->dmaPC == (gba->cpu->executionMode == MODE_THUMB ? WORD_SIZE_THUMB : WORD_SIZE_ARM)) { \
|
||||||
value = gba->bus; \
|
value = gba->bus; \
|
||||||
} else { \
|
} else { \
|
||||||
value = cpu->prefetch[1]; \
|
value = cpu->prefetch[1]; \
|
||||||
|
|
Loading…
Reference in New Issue