Skip to content

Commit f69eeaf

Browse files
committed
IOP: Reset recompiler and map RAM mirrors on IOP soft reset
When SifIopReset triggers (SBUS_F240 bit 19), psxReset() reloads the IOP BIOS kernel into RAM but does not flush the IOP recompiler cache. The recompiler keeps stale compiled blocks for IOP RAM addresses that now contain different code. When the fresh kernel executes, the recompiler serves old translations, causing the IOP to crash on garbage instructions (psxUNK). Add psxCpu->Reset() after psxReset() in the SBUS_F240 handler to flush all cached recompiler blocks. This forces fresh recompilation from the new RAM contents, allowing IOP soft resets to complete correctly. This fixes SifIopReset as used by ps2link and other PS2 homebrew that perform runtime IOP resets. Additionally, map IOP RAM mirrors throughout kuseg (pages 0x0000- 0x1DFF) in the recompiler lookup table. The PS2 IOP mirrors its 2MB RAM across the entire kuseg address space (0x00000000- 0x1DFFFFFF). The BIOS uses these mirrored addresses during IOP soft resets (e.g. jumping to 0x0d000100 which mirrors to physical 0x00000100). Without the mirrored pages in recLUT, code execution at mirrored addresses would hit unmapped pages.
1 parent 06616ec commit f69eeaf

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

pcsx2/HwWrite.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ void _hwWrite32( u32 mem, u32 value )
178178
u64 cycle = psxRegs.cycle;
179179
//pgifInit();
180180
psxReset();
181+
psxCpu->Reset();
181182
PSXCLK = 33868800;
182183
SPU2::Reset(true);
183184
setPs1CDVDSpeed(cdvd.Speed);

pcsx2/x86/iR3000A.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -955,16 +955,23 @@ void recResetIOP()
955955
// The bottom 2 bits of PC are always zero, so we <<14 to "compress"
956956
// the pc indexer into it's lower common denominator.
957957

958-
// We're only mapping 20 pages here in 4 places.
959-
// 0x80 comes from : (Ps2MemSize::IopRam / _64kb) * 4
960-
961-
for (int i = 0; i < 0x80; i++)
958+
// Map IOP RAM with mirrors throughout kuseg (0x0000-0x1DFF).
959+
// The PS2 IOP mirrors its 2MB (or 8MB) RAM across the entire kuseg
960+
// address space. The BIOS uses mirrored addresses (e.g. 0x0d000100
961+
// which maps to physical 0x00000100) during IOP soft resets.
962962
{
963-
u32 mask = (Ps2MemSize::ExposedIopRam / _64kb) - 1;
963+
const u32 mask = (Ps2MemSize::ExposedIopRam / _64kb) - 1;
964+
965+
for (int i = 0; i < 0x1e00; i++)
966+
{
967+
recLUT_SetPage(psxRecLUT, psxhwLUT, recRAM, 0x0000, i, i & mask);
968+
}
964969

965-
recLUT_SetPage(psxRecLUT, psxhwLUT, recRAM, 0x0000, i, i & mask);
966-
recLUT_SetPage(psxRecLUT, psxhwLUT, recRAM, 0x8000, i, i & mask);
967-
recLUT_SetPage(psxRecLUT, psxhwLUT, recRAM, 0xa000, i, i & mask);
970+
for (int i = 0; i < 0x80; i++)
971+
{
972+
recLUT_SetPage(psxRecLUT, psxhwLUT, recRAM, 0x8000, i, i & mask);
973+
recLUT_SetPage(psxRecLUT, psxhwLUT, recRAM, 0xa000, i, i & mask);
974+
}
968975
}
969976

970977
for (int i = 0x1fc0; i < 0x2000; i++)

0 commit comments

Comments
 (0)