From 64cbdf8aa0cf86281f78037403db58219d6f9a4a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 23 Mar 2015 01:15:56 -0700 Subject: [PATCH] GBA: Ensure idle loops are not removed on the first iteration --- src/gba/gba.c | 1 + src/gba/gba.h | 1 + src/gba/io.c | 2 +- src/gba/memory.c | 7 ++++++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gba/gba.c b/src/gba/gba.c index 97b4668fe..e3023ebc8 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -87,6 +87,7 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) { 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; diff --git a/src/gba/gba.h b/src/gba/gba.h index 3594b4ab8..1366fd1e6 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -157,6 +157,7 @@ struct GBA { enum GBAIdleLoopOptimization idleOptimization; uint32_t idleLoop; uint32_t lastJump; + bool haltPending; int idleDetectionStep; int idleDetectionFailures; int32_t cachedRegisters[16]; diff --git a/src/gba/io.c b/src/gba/io.c index 76305cb1d..65f178fde 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -567,7 +567,7 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) { } 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); diff --git a/src/gba/memory.c b/src/gba/memory.c index bc5a32e20..eddc33601 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -198,7 +198,12 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) { 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) {