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 },
{ "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 },

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;
}
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);

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);
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);

View File

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