Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,4 @@ RAPrefs_PPSSPP.cfg
cmake-build-*/

/.vscode/
smw.sfc
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2444,6 +2444,12 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/sceNp2.h
Core/HLE/scePauth.cpp
Core/HLE/scePauth.h
Core/HLE/sceSysEvent.cpp
Core/HLE/sceSysEvent.h
Core/HLE/sceSysreg.cpp
Core/HLE/sceSysreg.h
Core/HLE/sceMeCore.cpp
Core/HLE/sceMeCore.h
Core/HW/SimpleAudioDec.cpp
Core/HW/SimpleAudioDec.h
Core/HW/Atrac3Standalone.cpp
Expand Down
2 changes: 1 addition & 1 deletion Common/ExceptionHandlerSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void UninstallExceptionHandler() {
g_badAccessHandler = nullptr;
}

#elif defined(__APPLE__)
#elif defined(__APPLE__) && PPSSPP_ARCH(AMD64)

static void CheckKR(const char* name, kern_return_t kr) {
_assert_msg_(kr == 0, "%s failed: kr=%x", name, kr);
Expand Down
9 changes: 9 additions & 0 deletions Common/MachineContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ typedef x86_thread_state64_t SContext;
#define CTX_R15 __r15
#define CTX_RIP __rip

#elif PPSSPP_ARCH(ARM64)

#define MACHINE_CONTEXT_SUPPORTED

typedef _STRUCT_MCONTEXT64 SContext;
#define CTX_REG(x) __ss.__x[(x)]
#define CTX_SP __ss.__sp
#define CTX_PC __ss.__pc

#else

// No context definition for architecture
Expand Down
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ static const ConfigSetting achievementSettings[] = {

static const ConfigSetting cpuSettings[] = {
ConfigSetting("CPUCore", SETTING(g_Config, iCpuCore), &DefaultCpuCore, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("MECpuCore", SETTING(g_Config, iMECpuCore), (int)CPUCore::JIT_IR, CfgFlag::PER_GAME),
ConfigSetting("SeparateSASThread", SETTING(g_Config, bSeparateSASThread), &DefaultSasThread, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("IOTimingMethod", SETTING(g_Config, iIOTimingMethod), IOTIMING_FAST, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("FastMemoryAccess", SETTING(g_Config, bFastMemory), true, CfgFlag::PER_GAME),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ struct Config : public ConfigBlock {

bool bFastMemory;
int iCpuCore;
int iMECpuCore; // Media Engine CPU backend (0=interpreter, 2=IR interpreter)
bool bCheckForNewVersion;
bool bForceLagSync;
bool bFuncReplacements;
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,11 @@
<ClCompile Include="HLE\sceOpenPSID.cpp" />
<ClCompile Include="HLE\sceParseHttp.cpp" />
<ClCompile Include="HLE\sceParseUri.cpp" />
<ClCompile Include="HLE\sceMeCore.cpp" />
<ClCompile Include="HLE\scePauth.cpp" />
<ClCompile Include="HLE\scePower.cpp" />
<ClCompile Include="HLE\sceSysEvent.cpp" />
<ClCompile Include="HLE\sceSysreg.cpp" />
<ClCompile Include="HLE\scePsmf.cpp" />
<ClCompile Include="HLE\scePspNpDrm_user.cpp" />
<ClCompile Include="HLE\sceP3da.cpp" />
Expand Down Expand Up @@ -1137,8 +1140,11 @@
<ClInclude Include="HLE\sceOpenPSID.h" />
<ClInclude Include="HLE\sceParseHttp.h" />
<ClInclude Include="HLE\sceParseUri.h" />
<ClInclude Include="HLE\sceMeCore.h" />
<ClInclude Include="HLE\scePauth.h" />
<ClInclude Include="HLE\scePower.h" />
<ClInclude Include="HLE\sceSysEvent.h" />
<ClInclude Include="HLE\sceSysreg.h" />
<ClInclude Include="HLE\scePsmf.h" />
<ClInclude Include="HLE\scePspNpDrm_user.h" />
<ClInclude Include="HLE\sceP3da.h" />
Expand Down
18 changes: 18 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,18 @@
<ClCompile Include="ELF\PBPReader.cpp">
<Filter>ELF</Filter>
</ClCompile>
<ClCompile Include="HLE\sceMeCore.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\scePauth.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\sceSysEvent.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\sceSysreg.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\sceNp.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
Expand Down Expand Up @@ -1746,9 +1755,18 @@
<ClInclude Include="ELF\PBPReader.h">
<Filter>ELF</Filter>
</ClInclude>
<ClInclude Include="HLE\sceMeCore.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\scePauth.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\sceSysEvent.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\sceSysreg.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\sceNp.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
Expand Down
10 changes: 8 additions & 2 deletions Core/HLE/HLETables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
#include "sceNetResolver.h"
// #include "sceNp2.h"
#include "sceNet_lib.h"
#include "sceSysEvent.h"
#include "sceSysreg.h"
#include "sceMeCore.h"

#define N(s) s

Expand Down Expand Up @@ -203,7 +206,6 @@ const HLEFunction pspeDebug[] =
{0XDEADBEAF, nullptr, "pspeDebugWrite", '?', "" },
};


const HLEModule moduleList[] =

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use this moduleList thing. Instead, make new Register_...() functions, and importantly, call them at the end of RegisterAllModules.

Otherwise syscall module numbering gets messed up which breaks save state compatibility.

{
{"FakeSysCalls", ARRAY_SIZE(FakeSysCalls), FakeSysCalls},
Expand Down Expand Up @@ -328,6 +330,10 @@ void RegisterAllModules() {
// Not ready to enable this due to apparent softlocks in Patapon 3.
// Register_sceNpMatching2();

// Media Engine HLE modules.
Register_sceSysEventForKernel();
Register_sceSysreg_driver();
Register_sceMeCore_driver();

// add new modules here.
}

90 changes: 90 additions & 0 deletions Core/HLE/sceKernelInterrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ static void sceKernelCpuResumeIntrWithSync(u32 enable)

bool IntrHandler::run(PendingInterrupt& pend)
{
if (pend.subintr == PSP_INTR_SUB_NONE) {
if (baseHandlerAddress_ == 0 || !baseEnabled_) {
WARN_LOG(Log::sceIntc, "Ignoring base interrupt %d without enabled handler.", pend.intr);
return false;
}

copyArgsToCPU(pend);
return true;
}

SubIntrHandler *handler = get(pend.subintr);
if (!handler) {
WARN_LOG(Log::sceIntc, "Ignoring interrupt, already been released.");
Expand All @@ -144,6 +154,14 @@ bool IntrHandler::run(PendingInterrupt& pend)

void IntrHandler::copyArgsToCPU(PendingInterrupt& pend)
{
if (pend.subintr == PSP_INTR_SUB_NONE) {
DEBUG_LOG(Log::CPU, "Entering base interrupt handler %08x", baseHandlerAddress_);
currentMIPS->pc = baseHandlerAddress_;
currentMIPS->r[MIPS_REG_A0] = pend.intr;
currentMIPS->r[MIPS_REG_A1] = baseHandlerArg_;
return;
}

SubIntrHandler* handler = get(pend.subintr);
DEBUG_LOG(Log::CPU, "Entering interrupt handler %08x", handler->handlerAddress);
currentMIPS->pc = handler->handlerAddress;
Expand Down Expand Up @@ -189,11 +207,35 @@ SubIntrHandler* IntrHandler::get(int subIntrNum)
}
void IntrHandler::clear()
{
baseEnabled_ = false;
baseHandlerAddress_ = 0;
baseHandlerArg_ = 0;
subIntrHandlers.clear();
}

void IntrHandler::setBase(u32 handlerAddress, u32 handlerArg) {
baseHandlerAddress_ = handlerAddress;
baseHandlerArg_ = handlerArg;
}

void IntrHandler::clearBase() {
baseEnabled_ = false;
baseHandlerAddress_ = 0;
baseHandlerArg_ = 0;
}

void IntrHandler::enableBase() {
baseEnabled_ = true;
}

void IntrHandler::disableBase() {
baseEnabled_ = false;
}

void IntrHandler::queueUp(int subintr) {
if (subintr == PSP_INTR_SUB_NONE) {
// Always queue here. Derived handlers may override run(), and the base
// handler check belongs in IntrHandler::run().
pendingInterrupts.push_back(PendingInterrupt(intrNumber, subintr));
} else {
// Just call execute on all the subintr handlers for this interrupt.
Expand Down Expand Up @@ -590,6 +632,50 @@ static int QueryIntrHandlerInfo()
return 0;
}

static u32 sceKernelRegisterIntrHandler(u32 intrNumber, u32 unknown, u32 handler, u32 handlerArg, u32 subCount) {
(void)unknown;
(void)subCount;
if (intrNumber >= PSP_NUMBER_INTERRUPTS) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_INTRCODE, "invalid interrupt");
}
IntrHandler *intr = intrHandlers[intrNumber];
if (handler == 0) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "NULL handler");
}
if (intr == nullptr) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_INTRCODE, "missing interrupt");
}
if (intrNumber == PSP_MECODEC_INTR) {
DEBUG_LOG(Log::sceIntc, "Registering base handler for MECODEC intr at %08x", handler);
}
intr->setBase(handler, handlerArg);
return hleLogDebug(Log::sceIntc, 0);
}

static u32 sceKernelReleaseIntrHandler(u32 intrNumber) {
if (intrNumber >= PSP_NUMBER_INTERRUPTS) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_INTRCODE, "invalid interrupt");
}
IntrHandler *intr = intrHandlers[intrNumber];
if (intr == nullptr) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_INTRCODE, "missing interrupt");
}
intr->clearBase();
return hleLogDebug(Log::sceIntc, 0);
}

static u32 sceKernelEnableIntr(u32 intrNumber) {
if (intrNumber >= PSP_NUMBER_INTERRUPTS) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_INTRCODE, "invalid interrupt");
}
IntrHandler *intr = intrHandlers[intrNumber];
if (intr == nullptr) {
return hleLogError(Log::sceIntc, SCE_KERNEL_ERROR_ILLEGAL_INTRCODE, "missing interrupt");
}
intr->enableBase();
return hleLogDebug(Log::sceIntc, 0);
}

static u32 sceKernelMemset(u32 addr, u32 fillc, u32 n) {
u8 c = fillc & 0xff;
bool skip = false;
Expand Down Expand Up @@ -1053,6 +1139,10 @@ const HLEFunction InterruptManagerForKernel[] =
{0XFA835CDE, &WrapI_I<sceKernelGetTlsAddr>, "sceKernelGetTlsAddr", 'i', "i" ,HLE_KERNEL_SYSCALL },
{0X05572A5F, &WrapV_V<sceKernelExitGame>, "sceKernelExitGame", 'v', "" ,HLE_KERNEL_SYSCALL },
{0X4AC57943, &WrapI_I<sceKernelRegisterExitCallback>, "sceKernelRegisterExitCallback", 'i', "i" ,HLE_KERNEL_SYSCALL },
// Media Engine base interrupt handlers (added at end to preserve syscall numbering).
{0XF987B1F0, &WrapU_U<sceKernelReleaseIntrHandler>, "sceKernelReleaseIntrHandler", 'x', "x" ,HLE_KERNEL_SYSCALL },

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add new functions at the end of the list.

{0X58DD8978, &WrapU_UUUUU<sceKernelRegisterIntrHandler>, "sceKernelRegisterIntrHandler", 'x', "xxxxx",HLE_KERNEL_SYSCALL },
{0X4D6E7305, &WrapU_U<sceKernelEnableIntr>, "sceKernelEnableIntr", 'x', "x" ,HLE_KERNEL_SYSCALL },
};

void Register_InterruptManagerForKernel()
Expand Down
7 changes: 7 additions & 0 deletions Core/HLE/sceKernelInterrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,19 @@ class IntrHandler
void disable(int subIntrNum);
SubIntrHandler *get(int subIntrNum);
void clear();
void setBase(u32 handlerAddress, u32 handlerArg);
void clearBase();
void enableBase();
void disableBase();


void DoState(PointerWrap &p);

private:
int intrNumber;
bool baseEnabled_ = false;
u32 baseHandlerAddress_ = 0;
u32 baseHandlerArg_ = 0;
std::map<int, SubIntrHandler> subIntrHandlers;
};

Expand Down
36 changes: 36 additions & 0 deletions Core/HLE/sceMeCore.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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"

static u32 sceMeBootStartStub(u32 arg) { return 0; }

const HLEFunction sceMeCore_driver[] = {
{0X47DB48C2, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart", 'x', "x" },
{0XC287AD90, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart371", 'x', "x" },
{0XD857CF93, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart380", 'x', "x" },
{0X8988AD49, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart395", 'x', "x" },
{0X051C1601, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart500", 'x', "x" },
{0X3A2E60BB, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart620", 'x', "x" },
{0X99E4DBFA, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart635", 'x', "x" },
{0X5DFF5C50, &WrapU_U<sceMeBootStartStub>, "sceMeBootStart660", 'x', "x" },
};

void Register_sceMeCore_driver() {
RegisterHLEModule("sceMeCore_driver", ARRAY_SIZE(sceMeCore_driver), sceMeCore_driver);
}
20 changes: 20 additions & 0 deletions Core/HLE/sceMeCore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 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

void Register_sceMeCore_driver();
Loading
Loading