GBA: New idle loop detection metrics + Advance Wars 2 loops

This commit is contained in:
Jeffrey Pfau 2015-09-01 02:59:19 -07:00
parent 52048db173
commit caef2fe9a5
4 changed files with 34 additions and 2 deletions

View File

@ -15,6 +15,10 @@ static const struct GBACartridgeOverride _overrides[] = {
{ "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810 }, { "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810 },
{ "AWRP", 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 // Boktai: The Sun is in Your Hand
{ "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE },
{ "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE }, { "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE },

View File

@ -565,8 +565,34 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
gba->memory.io[(address >> 1) + 1] = value >> 16; 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) { 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) { switch (address) {
case REG_TM0CNT_LO: case REG_TM0CNT_LO:
GBATimerUpdateRegister(gba, 0); GBATimerUpdateRegister(gba, 0);

View File

@ -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); 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);
bool GBAIOIsReadConstant(uint32_t address);
struct GBASerializedState; struct GBASerializedState;
void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state); void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state);
void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state); void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state);

View File

@ -156,7 +156,7 @@ static void _analyzeForIdleLoop(struct GBA* gba, struct ARMCore* cpu, uint32_t a
} else { } else {
loadAddress += offset; loadAddress += offset;
} }
if ((loadAddress >> BASE_OFFSET) == REGION_IO) { if ((loadAddress >> BASE_OFFSET) == REGION_IO && !GBAIOIsReadConstant(loadAddress)) {
gba->idleDetectionStep = -1; gba->idleDetectionStep = -1;
return; return;
} }