From 1c10743995da4951a245cb66f7b2c67e0abd6518 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sat, 21 Mar 2015 18:15:06 -0700 Subject: [PATCH 1/6] GBA: Loosen checks on idle loops --- src/gba/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/memory.c b/src/gba/memory.c index 3ea0b7ece..bc5a32e20 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -197,7 +197,7 @@ 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->lastJump && address == gba->idleLoop) { + if (address == gba->idleLoop) { GBAHalt(gba); } else if (gba->idleOptimization >= IDLE_LOOP_DETECT && newRegion == memory->activeRegion) { if (address == gba->lastJump) { From 6e16b2992c8df8d8380cf2757711fda261fc7e09 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sat, 21 Mar 2015 18:16:50 -0700 Subject: [PATCH 2/6] GBA: Add idle loops for Advance Wars --- src/gba/supervisor/overrides.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gba/supervisor/overrides.c b/src/gba/supervisor/overrides.c index 2c5759040..f2f15d280 100644 --- a/src/gba/supervisor/overrides.c +++ b/src/gba/supervisor/overrides.c @@ -11,6 +11,10 @@ #include "util/configuration.h" static const struct GBACartridgeOverride _overrides[] = { + // Advance Wars + { "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, + { "AWRP", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, + // Boktai: The Sun is in Your Hand { "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, From f0cebb3fe72b7b4044cd746a46c6ecedd369e17a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sat, 21 Mar 2015 18:21:05 -0700 Subject: [PATCH 3/6] GBA: Add some idle loops for different regions of the same game --- src/gba/supervisor/overrides.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gba/supervisor/overrides.c b/src/gba/supervisor/overrides.c index f2f15d280..1afff6c70 100644 --- a/src/gba/supervisor/overrides.c +++ b/src/gba/supervisor/overrides.c @@ -73,13 +73,13 @@ static const struct GBACartridgeOverride _overrides[] = { { "AXPF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, // Pokemon Emerald - { "BPEJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, + { "BPEJ", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, { "BPEE", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, - { "BPEP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, - { "BPEI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, - { "BPES", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, - { "BPED", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, - { "BPEF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE }, + { "BPEP", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPEI", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPES", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPED", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, + { "BPEF", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6 }, // Pokemon Mystery Dungeon { "B24J", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, @@ -119,10 +119,14 @@ static const struct GBACartridgeOverride _overrides[] = { { "U33J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, // Super Mario Advance 2 + { "AA2J", SAVEDATA_EEPROM, HW_NONE, 0x800052E }, { "AA2E", SAVEDATA_EEPROM, HW_NONE, 0x800052E }, + { "AA2P", SAVEDATA_EEPROM, HW_NONE, 0x800052E }, // Super Mario Advance 3 + { "A3AJ", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, { "A3AE", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, + { "A3AP", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, // Super Mario Advance 4 { "AX4J", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, From 475954aff13370093efa3303b36d0e8b975152e7 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sat, 21 Mar 2015 18:22:37 -0700 Subject: [PATCH 4/6] GBA: Add idle loops for Super Mario Advance 4 --- src/gba/supervisor/overrides.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gba/supervisor/overrides.c b/src/gba/supervisor/overrides.c index 1afff6c70..1140a3b42 100644 --- a/src/gba/supervisor/overrides.c +++ b/src/gba/supervisor/overrides.c @@ -129,9 +129,9 @@ static const struct GBACartridgeOverride _overrides[] = { { "A3AP", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C }, // Super Mario Advance 4 - { "AX4J", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, - { "AX4E", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, - { "AX4P", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE }, + { "AX4J", SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, + { "AX4E", SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, + { "AX4P", SAVEDATA_FLASH1M, HW_NONE, 0x800072A }, // Top Gun - Combat Zones { "A2YE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE }, From 64cbdf8aa0cf86281f78037403db58219d6f9a4a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 23 Mar 2015 01:15:56 -0700 Subject: [PATCH 5/6] 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) { From 817dec97c2c54ffb63ce536525f55bfa7b746b9b Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 23 Mar 2015 01:16:15 -0700 Subject: [PATCH 6/6] GBA: Add Mega Man Zero override --- src/gba/supervisor/overrides.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gba/supervisor/overrides.c b/src/gba/supervisor/overrides.c index 1140a3b42..fc9b5cbb3 100644 --- a/src/gba/supervisor/overrides.c +++ b/src/gba/supervisor/overrides.c @@ -51,6 +51,9 @@ static const struct GBACartridgeOverride _overrides[] = { // Mega Man Battle Network { "AREE", SAVEDATA_SRAM, HW_NONE, 0x800032E }, + // Mega Man Zero + { "AZCE", SAVEDATA_SRAM, HW_NONE, 0x80004E8 }, + // Metal Slug Advance { "BSME", SAVEDATA_EEPROM, HW_NONE, 0x8000290 },