mirror of https://github.com/mgba-emu/mgba.git
GBA: New idle loop detection metrics + Advance Wars 2 loops
This commit is contained in:
parent
52048db173
commit
caef2fe9a5
|
@ -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 },
|
||||
|
|
28
src/gba/io.c
28
src/gba/io.c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue