GBA: Ensure idle loops are not removed on the first iteration
Jeffrey Pfau jeffrey@endrift.com
Mon, 23 Mar 2015 01:15:56 -0700
4 files changed,
9 insertions(+),
2 deletions(-)
M
src/gba/gba.c
→
src/gba/gba.c
@@ -87,6 +87,7 @@
gba->idleOptimization = IDLE_LOOP_REMOVE; gba->idleLoop = IDLE_LOOP_NONE; gba->lastJump = 0; + gba->haltPending = false; gba->idleDetectionStep = 0; gba->idleDetectionFailures = 0; gba->performingDMA = false;
M
src/gba/gba.h
→
src/gba/gba.h
@@ -157,6 +157,7 @@
enum GBAIdleLoopOptimization idleOptimization; uint32_t idleLoop; uint32_t lastJump; + bool haltPending; int idleDetectionStep; int idleDetectionFailures; int32_t cachedRegisters[16];
M
src/gba/io.c
→
src/gba/io.c
@@ -567,7 +567,7 @@ gba->memory.io[(address >> 1) + 1] = value >> 16;
} uint16_t GBAIORead(struct GBA* gba, uint32_t address) { - gba->lastJump = -1; // IO reads need to invalidate detected idle loops + gba->haltPending = false; // IO reads need to invalidate detected idle loops switch (address) { case REG_TM0CNT_LO: GBATimerUpdateRegister(gba, 0);
M
src/gba/memory.c
→
src/gba/memory.c
@@ -198,7 +198,12 @@
int newRegion = address >> BASE_OFFSET; if (gba->idleOptimization >= IDLE_LOOP_REMOVE && memory->activeRegion != REGION_BIOS) { if (address == gba->idleLoop) { - GBAHalt(gba); + if (gba->haltPending) { + gba->haltPending = false; + GBAHalt(gba); + } else { + gba->haltPending = true; + } } else if (gba->idleOptimization >= IDLE_LOOP_DETECT && newRegion == memory->activeRegion) { if (address == gba->lastJump) { switch (gba->idleDetectionStep) {