mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 10:49:05 +02: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
@@ -391,6 +391,8 @@ add_library(Core STATIC
|
||||
HLE/sceSysreg.cpp
|
||||
HLE/Plugins.h
|
||||
HLE/Plugins.cpp
|
||||
HLE/PopsBoot.cpp
|
||||
HLE/PopsBoot.h
|
||||
HLE/ThreadQueueList.h
|
||||
HLE/__sceAudio.cpp
|
||||
HLE/__sceAudio.h
|
||||
@@ -586,6 +588,8 @@ add_library(Core STATIC
|
||||
HW/MeMMIO.h
|
||||
HW/MMIO.cpp
|
||||
HW/MMIO.h
|
||||
HW/PopsMMIO.cpp
|
||||
HW/PopsMMIO.h
|
||||
HW/AvcDecoder.cpp
|
||||
HW/AvcDecoder.h
|
||||
HW/MediaEngine.cpp
|
||||
|
||||
@@ -477,6 +477,7 @@
|
||||
<ClCompile Include="HLE\sceSysreg.cpp" />
|
||||
<ClCompile Include="HLE\NetInetConstants.cpp" />
|
||||
<ClCompile Include="HLE\Plugins.cpp" />
|
||||
<ClCompile Include="HLE\PopsBoot.cpp" />
|
||||
<ClCompile Include="HLE\sceAac.cpp" />
|
||||
<ClCompile Include="HLE\sceChkreg.cpp" />
|
||||
<ClCompile Include="HLE\sceKernelHeap.cpp" />
|
||||
@@ -496,6 +497,7 @@
|
||||
<ClCompile Include="HW\GpioMMIO.cpp" />
|
||||
<ClCompile Include="HW\MMIO.cpp" />
|
||||
<ClCompile Include="HW\MeMMIO.cpp" />
|
||||
<ClCompile Include="HW\PopsMMIO.cpp" />
|
||||
<ClCompile Include="HW\GranularMixer.cpp" />
|
||||
<ClCompile Include="Instance.cpp" />
|
||||
<ClCompile Include="KeyMap.cpp" />
|
||||
@@ -853,6 +855,7 @@
|
||||
<ClInclude Include="HLE\sceSysreg.h" />
|
||||
<ClInclude Include="HLE\NetInetConstants.h" />
|
||||
<ClInclude Include="HLE\Plugins.h" />
|
||||
<ClInclude Include="HLE\PopsBoot.h" />
|
||||
<ClInclude Include="HLE\PSPThreadContext.h" />
|
||||
<ClInclude Include="HLE\sceAac.h" />
|
||||
<ClInclude Include="HLE\sceChkreg.h" />
|
||||
@@ -872,6 +875,7 @@
|
||||
<ClInclude Include="HW\GpioMMIO.h" />
|
||||
<ClInclude Include="HW\MMIO.h" />
|
||||
<ClInclude Include="HW\MeMMIO.h" />
|
||||
<ClInclude Include="HW\PopsMMIO.h" />
|
||||
<ClInclude Include="HW\GranularMixer.h" />
|
||||
<ClInclude Include="Instance.h" />
|
||||
<ClInclude Include="KeyMap.h" />
|
||||
|
||||
@@ -772,6 +772,9 @@
|
||||
<ClCompile Include="HLE\Plugins.cpp">
|
||||
<Filter>HLE</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HLE\PopsBoot.cpp">
|
||||
<Filter>HLE</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\ext\snappy\snappy-stubs-internal.cpp">
|
||||
<Filter>Ext\Snappy</Filter>
|
||||
</ClCompile>
|
||||
@@ -1184,6 +1187,7 @@
|
||||
<Filter>HW</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\MeMMIO.cpp">
|
||||
<ClCompile Include="HW\PopsMMIO.cpp">
|
||||
<Filter>HW</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HLE\sceNp2.cpp">
|
||||
@@ -2118,6 +2122,9 @@
|
||||
<ClInclude Include="HLE\Plugins.h">
|
||||
<Filter>HLE</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HLE\PopsBoot.h">
|
||||
<Filter>HLE</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\ext\gason\gason.h">
|
||||
<Filter>Ext\gason</Filter>
|
||||
</ClInclude>
|
||||
@@ -2200,6 +2207,7 @@
|
||||
<Filter>HW</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HW\MeMMIO.h">
|
||||
<ClInclude Include="HW\PopsMMIO.h">
|
||||
<Filter>HW</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HLE\sceNp2.h">
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "Core/System.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Dialog/PSPDialog.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/scePower.h"
|
||||
@@ -170,8 +171,10 @@ void PSPDialog::FinishVolatile() {
|
||||
|
||||
if (KernelVolatileMemUnlock(0) == 0) {
|
||||
volatileLocked_ = false;
|
||||
// Simulate modifications to volatile memory.
|
||||
Memory::Memset(PSP_GetVolatileMemoryStart(), 0, PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart());
|
||||
// Simulate modifications to volatile memory. Not under the PS1 emulator, which keeps its heap there.
|
||||
if (!PopsBootActive()) {
|
||||
Memory::Memset(PSP_GetVolatileMemoryStart(), 0, PSP_GetVolatileMemoryEnd() - PSP_GetVolatileMemoryStart());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -792,6 +792,17 @@ u64 hleDelayResult(u64 result, const char *reason, int usec) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Ends a thread's 32-bit hleDelayResult() early. Returns whether it was in one.
|
||||
bool hleWakeDelayedThread(int threadID) {
|
||||
u32 error;
|
||||
if (__KernelGetWaitID(threadID, WAITTYPE_HLEDELAY, error) != 1 || error != 0) {
|
||||
return false;
|
||||
}
|
||||
CoreTiming::UnscheduleEvent(delayedResultEvent, (u64)(u32)threadID);
|
||||
__KernelResumeThreadFromWait(threadID, __KernelGetWaitValue(threadID, error));
|
||||
return true;
|
||||
}
|
||||
|
||||
void hleEatCycles(int cycles) {
|
||||
if (hleAfterSyscall & HLE_SPLIT_SYSCALL_OVER_GE) {
|
||||
splitSyscallEatCycles = cycles;
|
||||
|
||||
@@ -159,6 +159,7 @@ void hleEnqueueCall(u32 func, int argc, const u32 *argv, PSPAction *afterAction
|
||||
// Delays the result for usec microseconds, allowing other threads to run during this time.
|
||||
u32 hleDelayResult(u32 result, const char *reason, int usec);
|
||||
u64 hleDelayResult(u64 result, const char *reason, int usec);
|
||||
bool hleWakeDelayedThread(int threadID);
|
||||
void hleEatCycles(int cycles);
|
||||
void hleEatMicro(int usec);
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@ public:
|
||||
u32 Entry() {
|
||||
return entry_;
|
||||
}
|
||||
SceUID Id() const {
|
||||
return id_;
|
||||
}
|
||||
|
||||
private:
|
||||
void AllocEntry(u32 size);
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
#include "sceSfmt19937.h"
|
||||
#include "sceG729.h"
|
||||
#include "KUBridge.h"
|
||||
#include "PopsBoot.h"
|
||||
#include "sceAmctrl.h"
|
||||
#include "sceNetInet.h"
|
||||
#include "sceNetResolver.h"
|
||||
@@ -361,6 +362,7 @@ void RegisterAllModules() {
|
||||
Register_sceSysreg_driver();
|
||||
Register_sceSysEventForKernel();
|
||||
Register_sceAmctrl_driver();
|
||||
Register_InitForKernel();
|
||||
|
||||
// Not ready to enable this due to apparent softlocks in Patapon 3.
|
||||
// Register_sceNpMatching2();
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
// 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/.
|
||||
|
||||
// PS1 EBOOTs, run by the firmware's own POPS manager (popsman.prx) and emulator (pops_0Xg.prx).
|
||||
// This stands in for the parts of the POPS boot PPSSPP doesn't run: the kernel's init, and the
|
||||
// Media Engine the manager's ME loop runs on. See docs/POPS.md.
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
#include "Common/Serialize/Serializer.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/Serialize/SerializeFuncs.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/FileSystems/MetaFileSystem.h"
|
||||
#include "Core/HLE/FunctionWrappers.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/HLEHelperThread.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HLE/sceKernelModule.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HW/PopsMMIO.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "Core/MIPS/MIPSCodeUtils.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/MemMapHelpers.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
static bool g_popsBoot = false;
|
||||
static std::unique_ptr<HLEHelperThread> g_popsInitThread;
|
||||
static u32 g_popsInitPath = 0;
|
||||
|
||||
// The 6.60 POPS manager (6.61's has the same code), from its base: scePopsManLoadModule. Its ME loop
|
||||
// (+2F88) runs on the emulated ME.
|
||||
enum : u32 {
|
||||
POPSMAN_LOAD_MODULE = 0x1E20,
|
||||
};
|
||||
|
||||
// What the places used here hold in the 6.60/6.61 manager. Checked when it's loaded.
|
||||
static const struct {
|
||||
u32 offset;
|
||||
u32 original;
|
||||
} POPSMAN_CODE[] = {
|
||||
{ POPSMAN_LOAD_MODULE, 0x27BDFEE0 }, // addiu sp, sp, -0x120
|
||||
};
|
||||
|
||||
static const u32 SCE_POPSMAN_LOAD_MODULE_NID = 0x29B3FB24;
|
||||
|
||||
void __PopsBootInit() {
|
||||
g_popsBoot = true;
|
||||
}
|
||||
|
||||
void __PopsBootShutdown() {
|
||||
g_popsBoot = false;
|
||||
// The kernel objects and memory are already gone with the kernel.
|
||||
if (g_popsInitThread) {
|
||||
g_popsInitThread->Forget();
|
||||
}
|
||||
g_popsInitThread.reset();
|
||||
g_popsInitPath = 0;
|
||||
}
|
||||
|
||||
bool PopsBootActive() {
|
||||
return g_popsBoot;
|
||||
}
|
||||
|
||||
static void DoHelperThread(PointerWrap &p, std::unique_ptr<HLEHelperThread> &thread) {
|
||||
bool has = thread != nullptr;
|
||||
Do(p, has);
|
||||
if (p.mode == PointerWrap::MODE_READ) {
|
||||
// The kernel objects come back with the kernel's own state.
|
||||
if (thread) {
|
||||
thread->Forget();
|
||||
}
|
||||
thread.reset(has ? new HLEHelperThread() : nullptr);
|
||||
}
|
||||
if (thread) {
|
||||
thread->DoState(p);
|
||||
}
|
||||
}
|
||||
|
||||
void __PopsBootDoState(PointerWrap &p) {
|
||||
auto s = p.Section("PopsBoot", 0, 1);
|
||||
if (!s) {
|
||||
if (p.mode == PointerWrap::MODE_READ) {
|
||||
__PopsBootShutdown();
|
||||
}
|
||||
return;
|
||||
}
|
||||
Do(p, g_popsBoot);
|
||||
Do(p, g_popsInitPath);
|
||||
DoHelperThread(p, g_popsInitThread);
|
||||
}
|
||||
|
||||
static u32 PopsManBase() {
|
||||
const u32 loadModule = KernelFindModuleExport("scePopsMan", SCE_POPSMAN_LOAD_MODULE_NID);
|
||||
return loadModule ? loadModule - POPSMAN_LOAD_MODULE : 0;
|
||||
}
|
||||
|
||||
// The user modules the 6.60 POPS boot configuration (pspbtcnf) starts after the manager.
|
||||
void __PopsBootLoadModules() {
|
||||
static const char *const paths[] = {
|
||||
"flash0:/vsh/module/libfont_hv.prx",
|
||||
"flash0:/vsh/module/pafmini.prx",
|
||||
"flash0:/vsh/module/libpspvmc.prx",
|
||||
};
|
||||
for (const char *path : paths) {
|
||||
std::string error;
|
||||
const SceUID moduleId = KernelLoadModule(path, &error);
|
||||
if (moduleId < 0) {
|
||||
WARN_LOG(Log::sceKernel, "POPS: failed to load %s: %s", path, error.c_str());
|
||||
continue;
|
||||
}
|
||||
if (__KernelStartModule(moduleId, 0, 0, 0, nullptr, nullptr) < 0) {
|
||||
WARN_LOG(Log::sceKernel, "POPS: failed to start %s", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __PopsBootPatchEmulator(u32 textAddr, u32 textSize) {
|
||||
}
|
||||
|
||||
// The installed firmware's version, from flash0:/vsh/etc/version.txt ("release:6.61:"). Empty if there's
|
||||
// none, as in a partial install.
|
||||
static std::string FirmwareVersion() {
|
||||
std::vector<u8> data;
|
||||
if (pspFileSystem.ReadEntireFile("flash0:/vsh/etc/version.txt", data, true) < 0)
|
||||
return "";
|
||||
const std::string text(data.begin(), data.end());
|
||||
const size_t start = text.find("release:");
|
||||
if (start == std::string::npos)
|
||||
return "";
|
||||
const size_t end = text.find(':', start + 8);
|
||||
return end == std::string::npos ? "" : text.substr(start + 8, end - start - 8);
|
||||
}
|
||||
|
||||
bool __PopsBootStartInit(FileLoader *pbp, const std::string &gamePath, std::string *error) {
|
||||
const u32 base = PopsManBase();
|
||||
bool known = base != 0;
|
||||
for (const auto &code : POPSMAN_CODE) {
|
||||
known = known && Memory::ReadUnchecked_U32(base + code.offset) == code.original;
|
||||
}
|
||||
// 6.35-6.39's manager has the same code at those places, but imports kernel functions by other
|
||||
// NIDs.
|
||||
const std::string version = FirmwareVersion();
|
||||
if (!version.empty() && version != "6.60" && version != "6.61") {
|
||||
known = false;
|
||||
}
|
||||
if (!known) {
|
||||
auto er = GetI18NCategory(I18NCat::ERRORS);
|
||||
*error = er->T("PS1FirmwareVersion", "So far, PS1 games only run with firmware 6.60 or 6.61, and a different version is installed. Install one of those from an official PSP update file in Settings > Tools > PSP Firmware.");
|
||||
return false;
|
||||
}
|
||||
const u32 loadModule = base + POPSMAN_LOAD_MODULE;
|
||||
|
||||
const u32 pathSize = (u32)gamePath.size() + 1;
|
||||
u32 allocSize = pathSize;
|
||||
g_popsInitPath = kernelMemory.Alloc(allocSize, false, "PopsInitPath");
|
||||
Memory::Memcpy(g_popsInitPath, gamePath.c_str(), pathSize, "PopsInitPath");
|
||||
|
||||
// The kernel's init: scePopsManLoadModule(path, 0). Starts with a1 = its copy of the path, below
|
||||
// the manager's priority so it runs once module_start is done.
|
||||
const u32 code[] = {
|
||||
0x00A02021, // move a0, a1
|
||||
MIPS_MAKE_J(loadModule), // returns to the thread's end
|
||||
0x24050000, // li a1, 0
|
||||
};
|
||||
g_popsInitThread.reset(new HLEHelperThread("ScePopsInit", code, (u32)ARRAY_SIZE(code), 0x40, 0x4000));
|
||||
g_popsInitThread->Start(pathSize, g_popsInitPath);
|
||||
INFO_LOG(Log::sceKernel, "POPS: init will call scePopsManLoadModule(%s, 0)", gamePath.c_str());
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 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/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
|
||||
class FileLoader;
|
||||
class PointerWrap;
|
||||
|
||||
void __PopsBootInit();
|
||||
void __PopsBootShutdown();
|
||||
void __PopsBootDoState(PointerWrap &p);
|
||||
bool PopsBootActive();
|
||||
|
||||
// After the POPS manager is loaded: the user modules of the POPS boot configuration.
|
||||
void __PopsBootLoadModules();
|
||||
// After the POPS manager is loaded: have it load the emulator for the game, as the kernel's init does.
|
||||
// Fails for a manager other than 6.60's.
|
||||
bool __PopsBootStartInit(FileLoader *pbp, const std::string &gamePath, std::string *error);
|
||||
// The emulator module is loaded, not yet started.
|
||||
void __PopsBootPatchEmulator(u32 textAddr, u32 textSize);
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "sceKernelHeap.h"
|
||||
#include "sceKernelInterrupt.h"
|
||||
#include "sceKernelThread.h"
|
||||
#include "PopsBoot.h"
|
||||
#include "sceKernelMemory.h"
|
||||
#include "sceKernelModule.h"
|
||||
#include "sceKernelMutex.h"
|
||||
@@ -199,6 +200,7 @@ void __KernelShutdown()
|
||||
kernelObjects.Clear();
|
||||
|
||||
__RegShutdown();
|
||||
__PopsBootShutdown();
|
||||
__HttpShutdown();
|
||||
__OpenPSIDShutdown();
|
||||
__UsbCamShutdown();
|
||||
@@ -327,6 +329,7 @@ void __KernelDoState(PointerWrap &p)
|
||||
__DmacDoState(p);
|
||||
__UsbCamDoState(p);
|
||||
__NpDrmDoState(p);
|
||||
__PopsBootDoState(p);
|
||||
|
||||
// IMPORTANT! Add new sections last!
|
||||
}
|
||||
@@ -1780,3 +1783,39 @@ const char *KernelErrorToString(u32 err) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
enum : u32 {
|
||||
PSP_BOOT_DISC = 0x20,
|
||||
PSP_BOOT_MS = 0x40,
|
||||
PSP_INIT_KEYCONFIG_GAME = 0x200,
|
||||
PSP_INIT_KEYCONFIG_POPS = 0x300,
|
||||
};
|
||||
|
||||
// The POPS manager stays resident only when booted from the memory stick.
|
||||
static u32 sceKernelBootFrom() {
|
||||
return hleLogInfo(Log::sceKernel, PopsBootActive() ? PSP_BOOT_MS : PSP_BOOT_DISC);
|
||||
}
|
||||
|
||||
// The key configuration the kernel was booted with. Also known as sceKernelInitKeyConfig.
|
||||
static u32 sceKernelApplicationType() {
|
||||
return hleLogInfo(Log::sceKernel, PopsBootActive() ? PSP_INIT_KEYCONFIG_POPS : PSP_INIT_KEYCONFIG_GAME);
|
||||
}
|
||||
|
||||
static int sceKernelGetChunk(int chunkId) {
|
||||
return hleLogWarning(Log::sceKernel, -1, "UNIMPL chunk %d", chunkId);
|
||||
}
|
||||
|
||||
static int InitForKernel_9D33A110() {
|
||||
return hleLogWarning(Log::sceKernel, 0, "UNIMPL");
|
||||
}
|
||||
|
||||
const HLEFunction InitForKernel[] = {
|
||||
{0x27932388, &WrapU_V<sceKernelBootFrom>, "sceKernelBootFrom", 'x', "", HLE_KERNEL_SYSCALL },
|
||||
{0x7233B5BC, &WrapU_V<sceKernelApplicationType>, "sceKernelApplicationType", 'x', "", HLE_KERNEL_SYSCALL },
|
||||
{0x2C6E9FE9, &WrapI_I<sceKernelGetChunk>, "sceKernelGetChunk", 'i', "i", HLE_KERNEL_SYSCALL },
|
||||
{0x9D33A110, &WrapI_V<InitForKernel_9D33A110>, "InitForKernel_9D33A110", 'i', "", HLE_KERNEL_SYSCALL },
|
||||
};
|
||||
|
||||
void Register_InitForKernel() {
|
||||
RegisterHLEModule("InitForKernel", ARRAY_SIZE(InitForKernel), InitForKernel);
|
||||
}
|
||||
@@ -340,6 +340,7 @@ void Register_LoadExecForUser();
|
||||
void Register_LoadExecForKernel();
|
||||
void Register_ExceptionManagerForKernel();
|
||||
void Register_UtilsForKernel();
|
||||
void Register_InitForKernel();
|
||||
|
||||
// returns nullptr if not found.
|
||||
const char *KernelErrorToString(u32 err);
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/ErrorCodes.h"
|
||||
#include "Core/HLE/FunctionWrappers.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
#include "Core/HLE/sceKernelHeap.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
@@ -216,6 +217,15 @@ static int sceKernelSetUmdCacheOn(int on) {
|
||||
return hleLogWarning(Log::sceKernel, 0, "UNIMPL");
|
||||
}
|
||||
|
||||
// A PS1 EBOOT declares none, and the POPS manager breaks unless it reads at least 3.00.
|
||||
static int sceKernelGetCompiledSdkVersionForKernel() {
|
||||
int version = sceKernelGetCompiledSdkVersion();
|
||||
if (version == 0 && PopsBootActive()) {
|
||||
version = 0x06060010;
|
||||
}
|
||||
return hleLogDebug(Log::sceKernel, version);
|
||||
}
|
||||
|
||||
static u32 sceKernelMemset(u32 addr, int value, u32 size) {
|
||||
if (Memory::IsValidRange(addr, size)) {
|
||||
Memory::Memset(addr, (u8)value, size, "KernelMemset");
|
||||
@@ -257,6 +267,8 @@ const HLEFunction SysMemForKernel[] = {
|
||||
{ 0xF91FE6AA, &WrapI_V<sceKernelSetParamSfo>, "sceKernelSetParamSfo", 'i', "", HLE_KERNEL_SYSCALL },
|
||||
{ 0xC2460DD5, &WrapI_V<sceKernelSetParamSfo>, "sceKernelSetParamSfo", 'i', "", HLE_KERNEL_SYSCALL },
|
||||
{ 0x807179E7, &WrapI_V<sceKernelSetParamSfo>, "sceKernelSetParamSfo", 'i', "", HLE_KERNEL_SYSCALL },
|
||||
// 6.60's NID.
|
||||
{ 0xB4F00CB5, &WrapI_V<sceKernelGetCompiledSdkVersionForKernel>, "sceKernelGetCompiledSdkVersion", 'x', "", HLE_KERNEL_SYSCALL },
|
||||
{ 0x8AE776AF, &WrapU_UIU<sceKernelMemset>, "sceKernelMemset", 'x', "xix", HLE_KERNEL_SYSCALL },
|
||||
{ 0xC90B0992, &WrapI_IU<sceKernelGetUIDcontrolBlock>, "sceKernelGetUIDcontrolBlock", 'i', "ix", HLE_KERNEL_SYSCALL },
|
||||
};
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include "Core/HLE/sceKernelModule.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HLE/sceMpeg.h"
|
||||
#include "Core/HLE/scePsmf.h"
|
||||
@@ -503,6 +504,23 @@ struct SceKernelSMOption {
|
||||
static int actionAfterModule;
|
||||
|
||||
static std::set<SceUID> loadedModules;
|
||||
|
||||
u32 KernelFindModuleExport(const char *libraryName, u32 nid) {
|
||||
u32 error;
|
||||
for (SceUID moduleId : loadedModules) {
|
||||
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
|
||||
if (!module) {
|
||||
continue;
|
||||
}
|
||||
for (const FuncSymbolExport &func : module->exportedFuncs) {
|
||||
if (func.nid == nid && !strncmp(func.moduleName, libraryName, KERNELOBJECT_MAX_NAME_LENGTH)) {
|
||||
return func.symAddr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set once we've seen a PSP_MODULE_VSH_MODE module load (i.e. we're booting the VSH rather
|
||||
// than a game), and reset on the next __KernelLoadExec. See ShouldHLEModuleForLoad below.
|
||||
static bool g_runningVSH = false;
|
||||
@@ -2233,6 +2251,10 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
|
||||
}
|
||||
}
|
||||
|
||||
if (PopsBootActive() && !strcmp(modinfo->name, "pops")) {
|
||||
__PopsBootPatchEmulator(module->nm.text_addr, module->nm.text_size);
|
||||
}
|
||||
|
||||
System_Notify(SystemNotification::SYMBOL_MAP_UPDATED);
|
||||
|
||||
u32 moduleSize = sizeof(module->nm);
|
||||
|
||||
@@ -280,3 +280,6 @@ void Register_SystemCtrlForUser();
|
||||
// Expose for use by KUBridge.
|
||||
u32 sceKernelLoadModule(MIPSState *mips, const char *name, u32 flags, u32 optionAddr);
|
||||
u32 sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr);
|
||||
|
||||
// Address of a function a loaded module exports, or 0.
|
||||
u32 KernelFindModuleExport(const char *libraryName, u32 nid);
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Core/HW/GpioMMIO.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
#include "Core/HW/MeMMIO.h"
|
||||
#include "Core/HW/PopsMMIO.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
|
||||
@@ -145,6 +146,9 @@ void Init() {
|
||||
MeMMIO::AudioDevice(),
|
||||
&g_kernelUncached,
|
||||
};
|
||||
for (MMIODevice *device : PopsMMIO::Devices()) {
|
||||
g_devices.push_back(device);
|
||||
}
|
||||
for (MMIODevice *device : g_devices) {
|
||||
device->Reset();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// 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 <cstring>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Serialize/Serializer.h"
|
||||
#include "Common/Serialize/SerializeFuncs.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
#include "Core/HW/PopsMMIO.h"
|
||||
#include "GPU/GPU.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
|
||||
namespace PopsMMIO {
|
||||
|
||||
namespace {
|
||||
|
||||
// The manager extends the emulator's stalled display list each frame: a FINISH, then the stall.
|
||||
class GeDevice : public MMIODevice {
|
||||
public:
|
||||
GeDevice() : MMIODevice("GE", 0xBD400000, 0x400) {}
|
||||
|
||||
bool Read(MIPSState *mips, u32 offset, int size, u32 *value) override {
|
||||
if (!PopsBootActive() || size != 4) {
|
||||
return false;
|
||||
}
|
||||
DisplayList list;
|
||||
const bool running = gpu && gpu->GetCurrentDisplayList(list);
|
||||
if (offset == REG_STALL) {
|
||||
*value = running ? list.stall : 0;
|
||||
return true;
|
||||
}
|
||||
if (offset == REG_INTR_STATUS) {
|
||||
// The HLE GPU runs up to the stall right away, so the FINISH before it is done.
|
||||
const bool atStall = running && list.stall != 0 && (list.pc & 0x0FFFFFFF) == (list.stall & 0x0FFFFFFF);
|
||||
*value = atStall ? INTR_FINISH : 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Write(MIPSState *mips, u32 offset, int size, u32 value) override {
|
||||
if (!PopsBootActive() || size != 4) {
|
||||
return false;
|
||||
}
|
||||
if (offset == REG_INTR_ACK) {
|
||||
return true;
|
||||
}
|
||||
if (offset != REG_STALL) {
|
||||
return false;
|
||||
}
|
||||
DisplayList list;
|
||||
if (!gpu || !gpu->GetCurrentDisplayList(list)) {
|
||||
WARN_LOG(Log::G3D, "GE stall register write %08x with no list running", value);
|
||||
return true;
|
||||
}
|
||||
bool runList = false;
|
||||
const u32 result = gpu->UpdateStall(list.id, value, &runList);
|
||||
if (result & 0x80000000) {
|
||||
WARN_LOG(Log::G3D, "GE stall register write %08x: list %d refused it (%08x)", value, list.id, result);
|
||||
} else if (runList) {
|
||||
gpu->ProcessDLQueue();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Reset() override {}
|
||||
void DoState(PointerWrap &p) override {}
|
||||
|
||||
private:
|
||||
static constexpr u32 REG_STALL = 0x10C;
|
||||
static constexpr u32 REG_INTR_STATUS = 0x304;
|
||||
static constexpr u32 REG_INTR_ACK = 0x310;
|
||||
static constexpr u32 INTR_FINISH = 4;
|
||||
};
|
||||
|
||||
GeDevice g_ge;
|
||||
|
||||
} // namespace
|
||||
|
||||
const std::vector<MMIODevice *> &Devices() {
|
||||
static const std::vector<MMIODevice *> devices = { &g_ge };
|
||||
return devices;
|
||||
}
|
||||
|
||||
} // namespace PopsMMIO
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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/.
|
||||
|
||||
// Hardware the firmware's POPS manager (flash0:/kd/popsman.prx) drives directly during a PS1 boot
|
||||
// (Core/HLE/PopsBoot.cpp), besides the Media Engine's: the GE's stall and interrupt registers. The
|
||||
// devices only answer during that boot.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
class MMIODevice;
|
||||
|
||||
namespace PopsMMIO {
|
||||
|
||||
const std::vector<MMIODevice *> &Devices();
|
||||
|
||||
} // namespace PopsMMIO
|
||||
+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;
|
||||
|
||||
+2
-2
@@ -104,8 +104,8 @@ struct MEState {
|
||||
// Null when the ME isn't emulated.
|
||||
extern MEState *g_meState;
|
||||
|
||||
// Whether the config and this boot (homebrew) want the ME.
|
||||
bool Wanted(bool homebrew);
|
||||
// Whether this boot wants the ME: homebrew with the setting on, or a PS1 game.
|
||||
bool Wanted(bool homebrew, bool pops);
|
||||
// Creates the ME, in reset. Fails on platforms without an ME address space.
|
||||
bool Init();
|
||||
void Shutdown();
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "Core/System.h"
|
||||
#include "Core/PSPLoaders.h"
|
||||
#include "Core/HLE/sceKernelModule.h"
|
||||
#include "Core/HLE/PopsBoot.h"
|
||||
|
||||
static void UseLargeMem(int memsize) {
|
||||
if (memsize != 1) {
|
||||
@@ -658,6 +659,34 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string_view discId, bool load
|
||||
return __KernelLoadExec(currentMIPS, finalName.c_str(), 0, error_string);
|
||||
}
|
||||
|
||||
// A PS1 EBOOT, run by the firmware's POPS manager, which loads its PS1 emulator for the game.
|
||||
bool Load_PSP_POPS(FileLoader *fileLoader, std::string *error_string) {
|
||||
static const char *const popsmanPath = "flash0:/kd/popsman.prx";
|
||||
if (!pspFileSystem.GetFileInfo(popsmanPath).exists) {
|
||||
auto er = GetI18NCategory(I18NCat::ERRORS);
|
||||
*error_string = er->T("PS1NoFirmware", "PS1 games need the PS1 emulator in the PSP's firmware, and no firmware is installed. Install firmware 6.60 or 6.61 from an official PSP update file in Settings > Tools > PSP Firmware. Starting a PSP game whose disc has an updater on it also installs its firmware.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Its directory as host0:, as for a homebrew EBOOT.
|
||||
const Path fullPath = fileLoader->GetPath();
|
||||
auto fs = std::make_shared<DirectoryFileSystem>(&pspFileSystem, fullPath.NavigateUp(), FileSystemFlags::SIMULATE_FAT32 | FileSystemFlags::CARD);
|
||||
pspFileSystem.Mount("host0:", fs);
|
||||
pspFileSystem.SetStartingDirectory("host0:/");
|
||||
|
||||
__PopsBootInit();
|
||||
const std::string gamePath = "host0:/" + fullPath.GetFilename();
|
||||
INFO_LOG(Log::Loader, "POPS: booting %s through %s", gamePath.c_str(), popsmanPath);
|
||||
if (!__KernelLoadExec(currentMIPS, popsmanPath, 0, error_string)) {
|
||||
return false;
|
||||
}
|
||||
__PopsBootLoadModules();
|
||||
if (!__PopsBootStartInit(fileLoader, gamePath, error_string)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) {
|
||||
auto umd = std::make_shared<BlobFileSystem>(&pspFileSystem, fileLoader, "data.ppdmp");
|
||||
pspFileSystem.Mount("disc0:", umd);
|
||||
|
||||
@@ -26,6 +26,7 @@ class BlockDevice;
|
||||
bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string);
|
||||
bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string_view discId, bool loadGameConfigs, std::string *error_string);
|
||||
bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string);
|
||||
bool Load_PSP_POPS(FileLoader *fileLoader, std::string *error_string);
|
||||
|
||||
bool MountGameISO(FileLoader *fileLoader, std::string *errorString);
|
||||
bool LoadParamSFOFromDisc();
|
||||
|
||||
+16
-2
@@ -462,6 +462,10 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
||||
gameTitle = g_CoreParameter.fileToStart.GetFilename();
|
||||
}
|
||||
break;
|
||||
case IdentifiedFileType::PSP_PS1_PBP:
|
||||
// Title and disc ID; the PS1 image itself is read by the firmware's POPS manager.
|
||||
LoadParamSFOFromPBP(fileLoader);
|
||||
break;
|
||||
case IdentifiedFileType::PSP_UMD_VIDEO_ISO:
|
||||
{
|
||||
ERROR_LOG(Log::Loader, "PPSSPP doesn't support UMD Video.");
|
||||
@@ -557,8 +561,12 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
||||
|
||||
CoreTiming::Init(&mipsr4k);
|
||||
MMIO::Init();
|
||||
if (MeCore::Wanted(homebrew)) {
|
||||
MeCore::Init();
|
||||
const bool pops = type == IdentifiedFileType::PSP_PS1_PBP;
|
||||
if (MeCore::Wanted(homebrew, pops) && !MeCore::Init() && pops) {
|
||||
// The firmware's PS1 emulator plays its sound on the ME.
|
||||
auto er = GetI18NCategory(I18NCat::ERRORS);
|
||||
*errorString = er->T("PS1NoMediaEngine", "PS1 games need the PSP's Media Engine, which PPSSPP can't emulate on this platform yet.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DisplayHWInit();
|
||||
@@ -636,6 +644,12 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin
|
||||
}
|
||||
break;
|
||||
|
||||
case IdentifiedFileType::PSP_PS1_PBP:
|
||||
if (!Load_PSP_POPS(fileLoader, errorString)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
GetBootError(type, errorString);
|
||||
g_CoreParameter.fileToStart.clear();
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
<ClInclude Include="..\..\Core\HLE\KernelWaitHelpers.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\KUBridge.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\sceSysreg.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\PopsBoot.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\proAdhoc.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\proAdhocServer.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\ReplaceTables.h" />
|
||||
@@ -263,6 +264,7 @@
|
||||
<ClInclude Include="..\..\Core\HW\Camera.h" />
|
||||
<ClInclude Include="..\..\Core\HW\Display.h" />
|
||||
<ClInclude Include="..\..\Core\HW\GpioMMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\PopsMMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MeMMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\AvcDecoder.h" />
|
||||
@@ -481,6 +483,7 @@
|
||||
<ClCompile Include="..\..\Core\HLE\HLETables.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\KUBridge.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\sceSysreg.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\PopsBoot.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\proAdhoc.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\proAdhocServer.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\ReplaceTables.cpp" />
|
||||
@@ -563,6 +566,7 @@
|
||||
<ClCompile Include="..\..\Core\HW\Camera.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\Display.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\GpioMMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\PopsMMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\MMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\MeMMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\AvcDecoder.cpp" />
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
<ClCompile Include="..\..\Core\HLE\HLETables.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\KUBridge.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\sceSysreg.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\PopsBoot.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\proAdhoc.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\proAdhocServer.cpp" />
|
||||
<ClCompile Include="..\..\Core\HLE\ReplaceTables.cpp" />
|
||||
@@ -172,6 +173,7 @@
|
||||
<ClCompile Include="..\..\Core\HW\GpioMMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\MMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\MeMMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\PopsMMIO.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\AvcDecoder.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\MediaEngine.cpp" />
|
||||
<ClCompile Include="..\..\Core\HW\MemoryStick.cpp" />
|
||||
@@ -507,6 +509,7 @@
|
||||
<ClInclude Include="..\..\Core\HLE\KernelWaitHelpers.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\KUBridge.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\sceSysreg.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\PopsBoot.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\proAdhoc.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\proAdhocServer.h" />
|
||||
<ClInclude Include="..\..\Core\HLE\ReplaceTables.h" />
|
||||
@@ -593,6 +596,7 @@
|
||||
<ClInclude Include="..\..\Core\HW\GpioMMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MeMMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\PopsMMIO.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MediaEngine.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MemoryStick.h" />
|
||||
<ClInclude Include="..\..\Core\HW\MpegDemux.h" />
|
||||
|
||||
@@ -658,6 +658,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/Core/HW/GpioMMIO.cpp \
|
||||
$(SRC)/Core/HW/MMIO.cpp \
|
||||
$(SRC)/Core/HW/MeMMIO.cpp \
|
||||
$(SRC)/Core/HW/PopsMMIO.cpp \
|
||||
$(SRC)/Core/HW/MemoryStick.cpp \
|
||||
$(SRC)/Core/HW/MpegDemux.cpp.arm \
|
||||
$(SRC)/Core/HW/AvcDecoder.cpp.arm \
|
||||
@@ -752,6 +753,7 @@ EXEC_AND_LIB_FILES := \
|
||||
$(SRC)/Core/HLE/NetInetConstants.cpp \
|
||||
$(SRC)/Core/HLE/SocketManager.cpp \
|
||||
$(SRC)/Core/HLE/Plugins.cpp \
|
||||
$(SRC)/Core/HLE/PopsBoot.cpp \
|
||||
$(SRC)/Core/HLE/sceAdler.cpp \
|
||||
$(SRC)/Core/HLE/sceAmctrl.cpp \
|
||||
$(SRC)/Core/HLE/sceAtrac.cpp \
|
||||
|
||||
@@ -759,6 +759,7 @@ SOURCES_CXX += \
|
||||
$(COREDIR)/HLE/NetInetConstants.cpp \
|
||||
$(COREDIR)/HLE/SocketManager.cpp \
|
||||
$(COREDIR)/HLE/Plugins.cpp \
|
||||
$(COREDIR)/HLE/PopsBoot.cpp \
|
||||
$(COREDIR)/HLE/sceSha256.cpp \
|
||||
$(COREDIR)/HLE/sceSircs.cpp \
|
||||
$(COREDIR)/HLE/sceG729.cpp \
|
||||
@@ -852,6 +853,7 @@ SOURCES_CXX += \
|
||||
$(COREDIR)/HW/GpioMMIO.cpp \
|
||||
$(COREDIR)/HW/MMIO.cpp \
|
||||
$(COREDIR)/HW/MeMMIO.cpp \
|
||||
$(COREDIR)/HW/PopsMMIO.cpp \
|
||||
$(COREDIR)/HW/SimpleAudioDec.cpp \
|
||||
$(COREDIR)/HW/Atrac3Standalone.cpp \
|
||||
$(COREDIR)/HW/AsyncIOManager.cpp \
|
||||
|
||||
Reference in new issue
Block a user