summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2026-04-04 16:31:15 +0200
committerJosJuice <josjuice@gmail.com>2026-04-04 17:45:17 +0200
commitf3adef75ed17d285f91c28212f2005bc380b3151 (patch)
tree0a102112d1d3a2db212c319483849b8f1b11059c /Source/Core
parentd3b89b4c39a312b52546c3604379b3f51ec3c876 (diff)
Core: Raise PI interrupt when accessing unmapped memory
Unmapped on the physical level, not the MMU level. Fixes booting Game Boy Interface. Previously, Game Boy Interface thought it was running on a Wii because accessing MEM2 didn't raise a PI interrupt, and as a result tried to exit to the Homebrew Channel in a way Dolphin's HLE doesn't recognize. (Dolphin's HLE catches jumps to 0x80001800, but GBI is running without address translation at this point and therefore jumps to 0x00001800 instead.)
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/MMU.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp
index 934956a224..940e93c7ea 100644
--- a/Source/Core/Core/PowerPC/MMU.cpp
+++ b/Source/Core/Core/PowerPC/MMU.cpp
@@ -302,12 +302,21 @@ T MMU::ReadFromHardware(u32 em_address)
return bswap(value);
}
- PanicAlertFmt("Unable to resolve read address {:x} PC {:x}", em_address, m_ppc_state.pc);
- if (m_system.IsPauseOnPanicMode())
+ // Memory access error. Game Boy Interface relies on this to confirm that MEM2 isn't present.
+ // TODO: This interrupt is supposed to have associated cause and address registers.
+ m_system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_PI);
+
+ // Don't show a panic alert for the specific access Game Boy Interface does.
+ if (em_address != 0x10000000 || (m_ppc_state.pc >> 28) != 0)
{
- m_system.GetCPU().Break();
- m_ppc_state.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
+ PanicAlertFmt("Unable to resolve read address {:x} PC {:x}", em_address, m_ppc_state.pc);
+ if (m_system.IsPauseOnPanicMode())
+ {
+ m_system.GetCPU().Break();
+ m_ppc_state.Exceptions |= EXCEPTION_DSI | EXCEPTION_FAKE_MEMCHECK_HIT;
+ }
}
+
return 0;
}
@@ -492,6 +501,10 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
return;
}
+ // Memory access error.
+ // TODO: This interrupt is supposed to have associated cause and address registers.
+ m_system.GetProcessorInterface().SetInterrupt(ProcessorInterface::INT_CAUSE_PI);
+
PanicAlertFmt("Unable to resolve write address {:x} PC {:x}", em_address, m_ppc_state.pc);
if (m_system.IsPauseOnPanicMode())
{