mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-30 19:24:23 +01:00
POPS: Boot PS1 EBOOTs through the firmware's POPS manager
A PS1 EBOOT now boots the installed firmware's POPS manager (flash0:/kd/popsman.prx), which loads its PS1 emulator (pops_0Xg.prx) for the game. Load_PSP_POPS stands in for the kernel's reboot into its POPS configuration: it loads the manager and that configuration's user modules, and a helper thread makes the kernel init's scePopsManLoadModule(path, 0) call. InitForKernel reports a POPS boot from the memory stick. The emulator plays its sound on the Media Engine, so a PS1 boot always gets the emulated ME, whatever the homebrew setting says, and is refused on platforms that can't emulate it. The manager boots the ME with its own code (POPS's reboot has no me_wrapper, so Sony's ME firmware isn't booted for it), and its ME loop runs there unchanged, playing through the audio block. Everything in POPS that reaches hardware registers is kernel code, so a POPS boot leaves the ME's kernel mode stopgap (g_kernelModeAnywhere) off: 7% fewer host instructions in Crash Bandicoot. The manager also drives the GE directly: its stall register and FINISH status are an MMIO device that only answers during a POPS boot, and stall writes extend the HLE GPU's current list. The 6.60 and 6.61 popsman.prx and pops_01g/02g.prx have the same code. The manager's is checked when it's loaded, and any other one fails the boot with a message. Savestates include the boot's threads. Reading a game's disc image needs the next two changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4f80c08fc9
commit
0b1e1a9bb3
27 files changed
+556
-10
No files matched your search
+13
-4
@@ -28,6 +28,7 @@
|
||||
#include "Core/ELF/PrxDecrypter.h"
|
||||
#include "Core/FileSystems/MetaFileSystem.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HW/MeMMIO.h"
|
||||
@@ -69,9 +70,10 @@ enum : u32 {
|
||||
MEState *g_meState = nullptr;
|
||||
static int meIntrEvent = -1;
|
||||
|
||||
// Booting the VSH counts as homebrew: vshmain.prx loads as an ELF.
|
||||
bool Wanted(bool homebrew) {
|
||||
return homebrew && g_Config.bEmulateMediaEngine;
|
||||
// Booting the VSH counts as homebrew: vshmain.prx loads as an ELF. A PS1 game always gets the ME:
|
||||
// the firmware's PS1 emulator plays its sound on it.
|
||||
bool Wanted(bool homebrew, bool pops) {
|
||||
return pops || (homebrew && g_Config.bEmulateMediaEngine);
|
||||
}
|
||||
|
||||
static void MeIntrCallback(u64 userdata, int cyclesLate) {
|
||||
@@ -124,7 +126,9 @@ bool Init() {
|
||||
g_meState->tickBase = CoreTiming::GetTicks(&mipsr4k);
|
||||
PowerOn(g_meState);
|
||||
meIntrEvent = CoreTiming::RegisterEvent("MeIntr", &MeIntrCallback);
|
||||
Memory::g_kernelModeAnywhere = true;
|
||||
// Not for POPS, whose code that reaches hardware is all kernel code anyway. A savestate's POPS boot
|
||||
// is known by now; a new one turns it off in KernelInit().
|
||||
Memory::g_kernelModeAnywhere = !PopsBootActive();
|
||||
INFO_LOG(Log::ME, "Media Engine created, %d KB eDRAM", space->edramSize / 1024);
|
||||
return true;
|
||||
}
|
||||
@@ -260,6 +264,11 @@ static u32 CreateSysEventHandler(const char *name) {
|
||||
void KernelInit() {
|
||||
if (!g_meState)
|
||||
return;
|
||||
// The POPS manager boots the ME with its own code (POPS's reboot has no me_wrapper).
|
||||
if (PopsBootActive()) {
|
||||
Memory::g_kernelModeAnywhere = false;
|
||||
return;
|
||||
}
|
||||
if (const u32 data = LoadFirmwareImage()) {
|
||||
BootFirmware(g_meState, data);
|
||||
g_meState->booting = true;
|
||||
|
||||
Reference in new issue
Block a user