GBA: Ensure idle loops are not removed on the first iteration

This commit is contained in:
Jeffrey Pfau 2015-03-23 01:15:56 -07:00
parent 475954aff1
commit 64cbdf8aa0
4 changed files with 9 additions and 2 deletions

View File

@ -87,6 +87,7 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
gba->idleOptimization = IDLE_LOOP_REMOVE; gba->idleOptimization = IDLE_LOOP_REMOVE;
gba->idleLoop = IDLE_LOOP_NONE; gba->idleLoop = IDLE_LOOP_NONE;
gba->lastJump = 0; gba->lastJump = 0;
gba->haltPending = false;
gba->idleDetectionStep = 0; gba->idleDetectionStep = 0;
gba->idleDetectionFailures = 0; gba->idleDetectionFailures = 0;
gba->performingDMA = false; gba->performingDMA = false;

View File

@ -157,6 +157,7 @@ struct GBA {
enum GBAIdleLoopOptimization idleOptimization; enum GBAIdleLoopOptimization idleOptimization;
uint32_t idleLoop; uint32_t idleLoop;
uint32_t lastJump; uint32_t lastJump;
bool haltPending;
int idleDetectionStep; int idleDetectionStep;
int idleDetectionFailures; int idleDetectionFailures;
int32_t cachedRegisters[16]; int32_t cachedRegisters[16];

View File

@ -567,7 +567,7 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
} }
uint16_t GBAIORead(struct GBA* gba, uint32_t address) { 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) { switch (address) {
case REG_TM0CNT_LO: case REG_TM0CNT_LO:
GBATimerUpdateRegister(gba, 0); GBATimerUpdateRegister(gba, 0);

View File

@ -198,7 +198,12 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
int newRegion = address >> BASE_OFFSET; int newRegion = address >> BASE_OFFSET;
if (gba->idleOptimization >= IDLE_LOOP_REMOVE && memory->activeRegion != REGION_BIOS) { if (gba->idleOptimization >= IDLE_LOOP_REMOVE && memory->activeRegion != REGION_BIOS) {
if (address == gba->idleLoop) { 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) { } else if (gba->idleOptimization >= IDLE_LOOP_DETECT && newRegion == memory->activeRegion) {
if (address == gba->lastJump) { if (address == gba->lastJump) {
switch (gba->idleDetectionStep) { switch (gba->idleDetectionStep) {