Skip to content

Load sceSifLoadModuleBuffer IRXs from IOP RAM - #407

Open
0xLeathery wants to merge 4 commits into
ran-j:mainfrom
0xLeathery:fix/iop-module-buffer-from-iop-ram
Open

0xLeathery wants to merge 4 commits into
ran-j:mainfrom
0xLeathery:fix/iop-module-buffer-from-iop-ram

Conversation

@0xLeathery

Copy link
Copy Markdown

Problem

sceSifLoadModuleBuffer takes an IOP RAM address. The EE first DMAs the IRX across with sceSifSetDma, then passes the IOP-side address to the loader. IopEmulator::Impl::loadModuleBuffer read that address through IopHost::readGuest, which looks in EE memory. It found no ELF there and returned -1 without logging anything.

Games that keep their IRXs inside the main ELF and retry the load until it succeeds then hang forever at boot. Sly 2 (SCUS-97316) does exactly that: it DMAs each embedded module to IOP 0x120000, calls sceSifLoadModuleBuffer(0x120000, ...) and loops on a negative result.

Fix

  • Move the ELF-sizing logic in IopModuleLoader::readElfFromGuest into a shared helper, and add IopModuleLoader::readElfFromIop, which reads through IopMemory::readRam.
  • loadModuleBuffer tries IOP RAM first and falls back to EE memory, so existing callers that pass the EE copy (including the current IOP tests) keep working.

Testing

  • New case in ps2xIOP/tests/iop_emulator_tests.cpp: it writes a minimal IRX only into IOP RAM at 0x120000 and checks that it loads and starts. It fails before this change and passes after it.
  • All four IOP test binaries pass. They're off by default; build them with -DPS2X_IOP_BUILD_TESTS=ON.
  • ps2x_tests: 446/446. The GS cache CTest suite: 45/45.
  • With a recompiled Sly 2 (USA), boot now gets past the module loop: all 7 embedded IRXs load, including 989snd, and the game reaches its main loop. It then waits on cdvdman imports, which this PR doesn't touch.

Built and tested on macOS arm64 (Apple clang, sse2neon path).

Move the ELF-sizing logic into a shared helper so the same reader works
for both the EE guest and the IOP's own RAM.
sceSifLoadModuleBuffer takes the IOP address the EE has DMA'd the IRX to.
The loader read that address from EE memory, found no ELF, and failed
silently, so games that retry the load (Sly 2) loop forever. Fall back to
EE memory for callers that pass the EE copy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant