mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-20 11:27:48 +02:00
Backwards from 5.01, one release at a time, against all 39 versions that ship on a disc plus the download-only 6.61. Nothing here is an offset - it's almost entirely Sony renumbering the kernel *_driver NIDs, which sends an import we mean to HLE into the real firmware module instead. Four more NIDs each for sceRtc_driver/sceRtcSetAlarmTick and sceHprm_driver/sceHprmReadLatch, covering 1.50 up. The rtc one is what parked every thread on a SceSysconSync semaphore; the hprm one runs once a frame, so unresolved it was most of the boot log. Also sceImposeGetParam/sceImposeChanges (1.50 - 2.xx) and sceKernelLoadModuleVSH (1.x, which is how the shell loads its own plugins - unresolved it got module id 0 and StartModule failed). sceRtcIsAlarmed had to be implemented too; it returns 0, as in JPCSP. As a null entry it returned LIBRARY_NOT_YET_LINKED, and the 3.0x-3.5x VSH read that as "ask the hardware instead" and went back to blocking on syscon. Two structural findings: - Up to 4.05, scePaf's heap allocator is a separate heaparea1.prx that paf imports as scePafHeaparea. Load it when it's there. Its pool pointer needs the same pre-fill paf's does, at gp - 0x7FCC rather than gp - 0x7E88. - 1.50's vshmain.prx declares no module attributes at all - PSP_MODULE_VSH_MODE only appears from 1.52 - so the whole VSH bootstrap was being skipped. Accept the module name too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
114 lines
5.0 KiB
C++
114 lines
5.0 KiB
C++
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
// Official git repository and contact information can be found at
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
#include "Core/HLE/HLE.h"
|
|
#include "Core/HLE/FunctionWrappers.h"
|
|
#include "Core/HLE/sceHprm.h"
|
|
#include "Core/MemMap.h"
|
|
#include "Core/MIPS/MIPS.h"
|
|
|
|
static u32 sceHprmPeekCurrentKey(u32 keyAddress) {
|
|
Memory::WriteOrException_U32(0, keyAddress);
|
|
return hleLogDebug(Log::HLE, 0);
|
|
}
|
|
|
|
// TODO: Might make sense to reflect the headphone status of the host here,
|
|
// if the games adjust their sound.
|
|
static u32 sceHprmIsHeadphoneExist() {
|
|
return hleLogDebug(Log::HLE, 0);
|
|
}
|
|
|
|
static u32 sceHprmIsMicrophoneExist() {
|
|
return hleLogDebug(Log::HLE, 0);
|
|
}
|
|
|
|
static u32 sceHprmIsRemoteExist() {
|
|
return hleLogDebug(Log::HLE, 0);
|
|
}
|
|
|
|
static u32 sceHprmRegisterCallback() {
|
|
return hleLogError(Log::HLE, 0, "UNIMPL");
|
|
}
|
|
|
|
static u32 sceHprmUnregisterCallback() {
|
|
return hleLogError(Log::HLE, 0, "UNIMPL");
|
|
}
|
|
|
|
static u32 sceHprmPeekLatch(u32 latchAddr) {
|
|
return hleLogDebug(Log::HLE,0, "latchAddr %08x", latchAddr);
|
|
}
|
|
|
|
static u32 sceHprmReadLatch(u32 latchAddr) {
|
|
// Real hardware/JPCSP: 4 x u32 output struct, dummied out to all-zero (nothing held/pressed).
|
|
for (int i = 0; i < 4; i++)
|
|
Memory::WriteOrException_U32(0, latchAddr + i * 4);
|
|
return hleLogDebug(Log::HLE, 0, "latchAddr %08x", latchAddr);
|
|
}
|
|
|
|
const HLEFunction sceHprm[] =
|
|
{
|
|
{0X089FDFA4, nullptr, "sceHprm_089fdfa4", '?', "" },
|
|
{0X1910B327, &WrapU_U<sceHprmPeekCurrentKey>, "sceHprmPeekCurrentKey", 'x', "x"},
|
|
{0X208DB1BD, &WrapU_V<sceHprmIsRemoteExist>, "sceHprmIsRemoteExist", 'x', "" },
|
|
{0X7E69EDA4, &WrapU_V<sceHprmIsHeadphoneExist>, "sceHprmIsHeadphoneExist", 'x', "" },
|
|
{0X219C58F1, &WrapU_V<sceHprmIsMicrophoneExist>, "sceHprmIsMicrophoneExist", 'x', "" },
|
|
{0XC7154136, &WrapU_V<sceHprmRegisterCallback>, "sceHprmRegisterCallback", 'x', "" },
|
|
{0xFD7DE6CD, &WrapU_V<sceHprmUnregisterCallback>,"sceHprmUnregisterCallback", 'x', "" },
|
|
{0X444ED0B7, nullptr, "sceHprmUnregitserCallback", '?', "" }, // Typo.
|
|
{0X2BCEC83E, &WrapU_U<sceHprmPeekLatch>, "sceHprmPeekLatch", 'x', "x"},
|
|
{0X40D2F9F0, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"},
|
|
};
|
|
|
|
void Register_sceHprm()
|
|
{
|
|
RegisterHLEModule("sceHprm", ARRAY_SIZE(sceHprm), sceHprm);
|
|
}
|
|
|
|
// Kernel-mode variant library used by VSH modules (e.g. vshbridge). NID 0xE9B776BE is the
|
|
// firmware 6.60+ alias of sceHprmReadLatch, listed as nid=0xE9B776BE version=660 alongside the
|
|
// 0x40D2F9F0 version=150 NID in JPCSP's sceHprm.java - both resolve to the same function there.
|
|
static u32 sceHprm_driver_DC895B2B() {
|
|
return hleLogWarning(Log::sceMisc, 0, "UNIMPL");
|
|
}
|
|
|
|
const HLEFunction sceHprm_driver[] =
|
|
{
|
|
{0XE9B776BE, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"},
|
|
// Purpose unknown - JPCSP names it after its NID too, and returns 0. Present so the VSH's
|
|
// one startup call resolves instead of trapping.
|
|
{0XDC895B2B, &WrapU_V<sceHprm_driver_DC895B2B>, "sceHprm_driver_DC895B2B", 'x', ""},
|
|
// Older firmwares number these two differently. Same functions - matched by address against
|
|
// the same module's user-mode sceHprm exports (sceHprmReadLatch is sceHprm/0x40D2F9F0 in
|
|
// every build). The VSH calls ReadLatch once a frame, so without these an older firmware's
|
|
// XMB spends the whole boot trapping on an unresolved import.
|
|
// NOTE: new entries go at the end - the syscall opcode in a savestate is an index into this array.
|
|
{0XA3A87975, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 6.31 - 6.39
|
|
{0X5FC5E53B, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 6.00 - 6.20
|
|
{0X748FC3C8, &WrapU_V<sceHprm_driver_DC895B2B>, "sceHprm_driver_DC895B2B", 'x', ""}, // 6.31 - 6.39
|
|
{0X605DEA7A, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 5.03 - 5.55
|
|
{0XA6E8D4F0, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 3.95 - 4.05
|
|
{0X8C728076, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 3.72 - 3.90
|
|
{0XF0AA1FB9, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 3.71
|
|
// Same story as sceRtc_driver: 3.51 and older export it to kernel mode under the user-mode NID.
|
|
{0X40D2F9F0, &WrapU_U<sceHprmReadLatch>, "sceHprmReadLatch", 'x', "x"}, // 1.50 - 3.51
|
|
};
|
|
|
|
void Register_sceHprm_driver()
|
|
{
|
|
RegisterHLEModule("sceHprm_driver", ARRAY_SIZE(sceHprm_driver), sceHprm_driver);
|
|
}
|