GBA: New idle loop detection metrics + Advance Wars 2 loops
Jeffrey Pfau jeffrey@endrift.com
Tue, 01 Sep 2015 02:59:19 -0700
4 files changed,
34 insertions(+),
2 deletions(-)
M
src/gba/context/overrides.c
→
src/gba/context/overrides.c
@@ -15,6 +15,10 @@ // Advance Wars
{ "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, { "AWRP", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, + // Advance Wars 2: Black Hole Rising + { "AW2E", SAVEDATA_FLASH512, HW_NONE, 0x8036E08 }, + { "AW2P", SAVEDATA_FLASH512, HW_NONE, 0x803719C }, + // 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 },
M
src/gba/io.c
→
src/gba/io.c
@@ -565,8 +565,34 @@ gba->memory.io[address >> 1] = value;
gba->memory.io[(address >> 1) + 1] = value >> 16; } +bool GBAIOIsReadConstant(uint32_t address) { + switch (address) { + default: + return false; + case REG_BG0CNT: + case REG_BG1CNT: + case REG_BG2CNT: + case REG_BG3CNT: + case REG_WININ: + case REG_WINOUT: + case REG_BLDCNT: + case REG_BLDALPHA: + case REG_DMA0CNT_LO: + case REG_DMA1CNT_LO: + case REG_DMA2CNT_LO: + case REG_DMA3CNT_LO: + case REG_KEYINPUT: + case REG_IE: + return true; + } +} + uint16_t GBAIORead(struct GBA* gba, uint32_t address) { - gba->haltPending = false; // IO reads need to invalidate detected idle loops + if (!GBAIOIsReadConstant(address)) { + // Most IO reads need to disable idle removal + gba->haltPending = false; + } + switch (address) { case REG_TM0CNT_LO: GBATimerUpdateRegister(gba, 0);
M
src/gba/io.h
→
src/gba/io.h
@@ -159,6 +159,8 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value);
void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value); uint16_t GBAIORead(struct GBA* gba, uint32_t address); +bool GBAIOIsReadConstant(uint32_t address); + struct GBASerializedState; void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state); void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state);
M
src/gba/memory.c
→
src/gba/memory.c
@@ -156,7 +156,7 @@ loadAddress -= offset;
} else { loadAddress += offset; } - if ((loadAddress >> BASE_OFFSET) == REGION_IO) { + if ((loadAddress >> BASE_OFFSET) == REGION_IO && !GBAIOIsReadConstant(loadAddress)) { gba->idleDetectionStep = -1; return; }