Implement a batch of the VSH's unresolved imports (and document three we must not)

Mostly small stubs:

- sceImpose: GetParam/SetParam/Changes/SetStatus, plus the 6.60 alias of
  sceImposeGetBatteryIconStatus. Also fixes that function's first output - it
  is a plain "is it charging" boolean, not a BATTICON_ value. We wrote
  PSP_IMPOSE_BATTICON_NONE (0x80000000) there, which games ignore but which the
  VSH reads as "no battery" and draws the empty-battery indicator for. These
  are the bulk of the traffic: the VSH calls sceImposeChanges once a frame, so
  this alone removes ~10000 trapped calls from a boot.
- SysMemForKernel: sceKernelSetRebootKernel, sceKernelSetUmdCacheOn.
- scePower_driver: scePowerSetWakeupCondition.
- sceHprm_driver, sceUsb: one NID-named call each, as in JPCSP.

Three groups are deliberately left unresolved, with comments explaining why,
because resolving them lets real flash0 drivers walk into hardware we do not
emulate and the boot dies where it used to reach the shell:

- ThreadManForKernel mutex/fpl NIDs: the NAND and ID storage drivers use these
  to init, then poll the NAND controller at 0xbd101300 forever.
- InterruptManagerForKernel intr registration: 31 calls, then a stall in GE
  list execution with no plugin module ever started.

73 unresolved import hits over 37 distinct module/NID pairs remain in a VSH
boot, mostly sceSysEventForKernel, sceSuspendForKernel and the various
*_driver modules that need real hardware behind them.

The sceImpose savestate section goes to v2 for the two new state variables.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
This commit is contained in:
Henrik RydgårdandClaude Opus 5 committed 2026-08-24 10:58:35 +02:00
1 parent 4667f5e2da
commit f449fa6ab2
7 files changed
+143 -3

No files matched your search

+10
View File
@@ -1052,6 +1052,7 @@ static int sceKernelIsIntrContext() {
return hleLogDebug(Log::sceKernel, __IsInInterrupt() ? 1 : 0);
}
const HLEFunction InterruptManagerForKernel[] =
{
{0x092968F4, &WrapI_V<sceKernelCpuSuspendIntr>, "sceKernelCpuSuspendIntr", 'i', "" ,HLE_KERNEL_SYSCALL },
@@ -1073,6 +1074,15 @@ const HLEFunction InterruptManagerForKernel[] =
{0X05572A5F, &WrapV_V<sceKernelExitGame>, "sceKernelExitGame", 'v', "" ,HLE_KERNEL_SYSCALL },
{0X4AC57943, &WrapI_I<sceKernelRegisterExitCallback>, "sceKernelRegisterExitCallback", 'i', "i" ,HLE_KERNEL_SYSCALL },
{0XFE28C6D9, &WrapI_V<sceKernelIsIntrContext>, "sceKernelIsIntrContext", 'i', "" ,HLE_KERNEL_SYSCALL },
// NOT added on purpose, even though JPCSP implements all four: sceKernelRegisterIntrHandler
// (0x58DD8978), sceKernelReleaseIntrHandler (0xF987B1F0), sceKernelEnableIntr (0x4D6E7305)
// and sceKernelDisableIntr (0xD774BA45). JPCSP can honour them because it emulates the
// interrupt controller as MMIO; we dispatch the few interrupts we emulate ourselves (see
// __RegisterIntrHandler and its callers in sceGe/sceKernelAlarm/sceKernelVTimer) and have no
// way to run a guest handler for one. Stubbing them to return success is therefore a lie the
// real flash0 drivers act on - measured while booting the VSH, they make 31 such calls
// (interrupts 4, 12, 15-18, 20-24, 31), and the boot then stalls in GE list execution without
// ever starting a plugin module, where leaving them unresolved reaches the shell.
};
void Register_InterruptManagerForKernel()