From 7dd1475ed7bc608aef476b7ccb823d73b59e05b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 20 Oct 2026 15:45:14 +0200 Subject: [PATCH] HLE: Pass the MIPSState to syscalls and their implementations HLEFunc and ReplaceFunc now take the MIPSState they run on. The dispatch paths (both interpreters and every JIT backend) pass in the state they belong to, and CallSyscall*, hleFinishSyscall and the HLE mips call machinery use it instead of currentMIPS. The wrappers in FunctionWrappers.h take the function as `auto` and call it through HLECall, which also accepts an implementation with an extra leading MIPSState * parameter and passes the state to it. Any other signature still fails to compile, as before. PARAM/RETURN now refer to a local `mips`. The HLE functions (and replacement functions) that used currentMIPS now take the state that way. Callers outside a syscall's own frame - CoreTiming events, the adhoc matching thread, dialogs, PPGe, the debugger UIs - pass currentMIPS or &mipsr4k explicitly. The kernel's thread internals still use currentMIPS. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/Core.cpp | 2 +- Core/Dialog/PSPNetconfDialog.cpp | 14 +- Core/HLE/FunctionWrappers.h | 749 +++++++++--------- Core/HLE/HLE.cpp | 114 +-- Core/HLE/HLE.h | 31 +- Core/HLE/HLETables.cpp | 4 +- Core/HLE/KUBridge.cpp | 4 +- Core/HLE/ReplaceTables.cpp | 514 ++++++------ Core/HLE/ReplaceTables.h | 2 +- Core/HLE/sceDisplay.cpp | 8 +- Core/HLE/sceDmac.cpp | 12 +- Core/HLE/sceGe.cpp | 8 +- Core/HLE/sceGe.h | 6 +- Core/HLE/sceHttp.cpp | 8 +- Core/HLE/sceIo.cpp | 10 +- Core/HLE/sceKernel.cpp | 16 +- Core/HLE/sceKernel.h | 9 +- Core/HLE/sceKernelInterrupt.cpp | 18 +- Core/HLE/sceKernelInterrupt.h | 3 +- Core/HLE/sceKernelMemory.cpp | 2 +- Core/HLE/sceKernelModule.cpp | 32 +- Core/HLE/sceKernelModule.h | 6 +- Core/HLE/sceKernelMutex.cpp | 8 +- Core/HLE/sceKernelMutex.h | 4 +- Core/HLE/sceKernelThread.cpp | 80 +- Core/HLE/sceKernelThread.h | 20 +- Core/HLE/sceKernelVTimer.cpp | 2 +- Core/HLE/sceKernelVTimer.h | 2 +- Core/HLE/sceNet.cpp | 32 +- Core/HLE/sceNet.h | 2 +- Core/HLE/sceNetAdhoc.cpp | 212 ++--- Core/HLE/sceNetAdhoc.h | 18 +- Core/HLE/sceNetAdhocMatching.cpp | 64 +- Core/HLE/sceNetInet.cpp | 34 +- Core/HLE/sceNetInet.h | 4 +- Core/HLE/sceNp2.cpp | 32 +- Core/HLE/sceParseHttp.cpp | 4 +- Core/HLE/sceParseUri.cpp | 12 +- Core/HLE/scePsmf.cpp | 4 +- Core/HLE/sceUtility.cpp | 4 +- Core/MIPS/ARM/ArmIRCompSystem.cpp | 16 +- Core/MIPS/ARM64/Arm64IRCompSystem.cpp | 16 +- Core/MIPS/IR/IRInterpreter.cpp | 6 +- Core/MIPS/Interpreter.cpp | 4 +- .../LoongArch64/LoongArch64CompSystem.cpp | 16 +- Core/MIPS/RiscV/RiscVCompSystem.cpp | 26 +- Core/MIPS/x86/X64IRCompSystem.cpp | 12 +- Core/Util/PPGeDraw.cpp | 2 +- UI/ImDebugger/ImDebugger.cpp | 2 +- Windows/Debugger/Debugger_Lists.cpp | 2 +- docs/HLEModules.md | 3 + unittest/JitHarness.cpp | 6 +- 52 files changed, 1138 insertions(+), 1083 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 84fbeca516..01434daaa6 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -456,7 +456,7 @@ void Core_RunLoopUntil(u64 globalticks) { case DLResult::Error: // We should elegantly report the error somehow, or I guess ignore it. case DLResult::Done: // Done executing for now - hleFinishSyscallAfterGe(); + hleFinishSyscallAfterGe(&mipsr4k); coreState = preGeCoreState; break; diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index f8a846ccb7..5615b7d7c1 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -195,7 +195,7 @@ int PSPNetconfDialog::Update(int animSpeed) { } else if (state == PSP_NET_APCTL_STATE_DISCONNECTED) { // When connecting with infrastructure, simulate a connection using the first network configuration entry. if (connResult < 0) { - connResult = hleCall(sceNetApctl, int, sceNetApctlConnect, 1); + connResult = hleCall(sceNetApctl, int, sceNetApctlConnect, currentMIPS, 1); } } @@ -248,13 +248,13 @@ int PSPNetconfDialog::Update(int animSpeed) { { case NETCONF_CREATE_ADHOC: if (connResult < 0) { - connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlCreate, request.NetconfData->groupName); + connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlCreate, currentMIPS, request.NetconfData->groupName); } break; case NETCONF_JOIN_ADHOC: // FIXME: Should we Scan for a matching group first before Joining a Group (like adhoc games normally do)? Or Is it really allowed to join non-existing group? if (scanStep == 0) { - if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlScan) >= 0) { + if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlScan, currentMIPS) >= 0) { u32 structsz = sizeof(ScanInfos); if (Memory::IsValidAddress(scanInfosAddr)) userMemory.Free(scanInfosAddr); @@ -267,7 +267,7 @@ int PSPNetconfDialog::Update(int animSpeed) { else if (scanStep == 1) { s32 sz = Memory::ReadOrException_U32(scanInfosAddr); // Get required buffer size - if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlGetScanInfo, scanInfosAddr, 0) >= 0) { + if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlGetScanInfo, currentMIPS, scanInfosAddr, 0) >= 0) { s32 reqsz = Memory::ReadOrException_U32(scanInfosAddr); if (reqsz > sz) { sz = reqsz; @@ -278,7 +278,7 @@ int PSPNetconfDialog::Update(int animSpeed) { Memory::WriteOrException_U32(sz, scanInfosAddr); } if (reqsz > 0) { - if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlGetScanInfo, scanInfosAddr, scanInfosAddr + (u32)sizeof(s32)) >= 0) { + if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlGetScanInfo, currentMIPS, scanInfosAddr, scanInfosAddr + (u32)sizeof(s32)) >= 0) { ScanInfos* scanInfos = (ScanInfos*)Memory::GetPointerOrException(scanInfosAddr); int n = scanInfos->sz / sizeof(SceNetAdhocctlScanInfoEmu); // Assuming returned SceNetAdhocctlScanInfoEmu(s) are contiguous where next is pointing to current addr + sizeof(SceNetAdhocctlScanInfoEmu) @@ -306,7 +306,7 @@ int PSPNetconfDialog::Update(int animSpeed) { } else if (scanStep == 2) { if (connResult < 0) { - connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlJoin, scanInfosAddr + (u32)sizeof(s32)); + connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlJoin, currentMIPS, scanInfosAddr + (u32)sizeof(s32)); if (connResult >= 0) { // We are done! if (Memory::IsValidAddress(scanInfosAddr)) @@ -318,7 +318,7 @@ int PSPNetconfDialog::Update(int animSpeed) { break; default: if (connResult < 0) { - connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlConnect, request.NetconfData->groupName); + connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlConnect, currentMIPS, request.NetconfData->groupName); } break; } diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index fc7765fd23..46759c4fd9 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -17,915 +17,940 @@ #pragma once +#include + #include "Common/CommonTypes.h" #include "Core/HLE/HLE.h" #include "Core/MemMap.h" // For easy parameter parsing and return value processing. +// Each wrapper names the signature it unpacks. The function may also take the MIPSState it runs on +// as an extra first parameter, which is how an implementation gets at the CPU (instead of currentMIPS). +template +struct HLEFuncTypes; + +template +struct HLEFuncTypes { + typedef R (*Plain)(Args...); + typedef R (*WithState)(MIPSState *, Args...); +}; + +template +inline auto HLECall(MIPSState *mips, CallArgs... args) { + typedef HLEFuncTypes Types; + typedef std::decay_t FuncType; + if constexpr (std::is_same_v) { + return func(mips, args...); + } else { + static_assert(std::is_same_v, "HLE function doesn't match the signature of its wrapper"); + return func(args...); + } +} + // 64bit wrappers // 64bit values are always "aligned" in regs (never start on an odd reg.) -template void WrapU64_V() { - u64 retval = func(); +template void WrapU64_V(MIPSState *mips) { + u64 retval = HLECall(mips); RETURN64(retval); } -template void WrapU64_U() { - u64 retval = func(PARAM(0)); +template void WrapU64_U(MIPSState *mips) { + u64 retval = HLECall(mips, PARAM(0)); RETURN64(retval); } -template void WrapU64_I() { - u64 retval = func(PARAM(0)); +template void WrapU64_I(MIPSState *mips) { + u64 retval = HLECall(mips, PARAM(0)); RETURN64(retval); } -template void WrapU64_UU64() { - u64 retval = func(PARAM(0), PARAM64(2)); +template void WrapU64_UU64(MIPSState *mips) { + u64 retval = HLECall(mips, PARAM(0), PARAM64(2)); RETURN64(retval); } -template void WrapU64_IU64() { - u64 retval = func(PARAM(0), PARAM64(2)); +template void WrapU64_IU64(MIPSState *mips) { + u64 retval = HLECall(mips, PARAM(0), PARAM64(2)); RETURN64(retval); } -template void WrapI_IU64() { - int retval = func(PARAM(0), PARAM64(2)); +template void WrapI_IU64(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM64(2)); RETURN(retval); } -template void WrapI_UU64() { - int retval = func(PARAM(0), PARAM64(2)); +template void WrapI_UU64(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM64(2)); RETURN(retval); } -template void WrapU_UU64() { - u32 retval = func(PARAM(0), PARAM64(2)); +template void WrapU_UU64(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM64(2)); RETURN(retval); } -template void WrapI_UUU64() { - int retval = func(PARAM(0), PARAM(1), PARAM64(2)); +template void WrapI_UUU64(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM64(2)); RETURN(retval); } -template void WrapU_II64I() { - u32 retval = func(PARAM(0), PARAM64(2), PARAM(4)); +template void WrapU_II64I(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM64(2), PARAM(4)); RETURN(retval); } -template void WrapU_UU64UU() { - u32 retval = func(PARAM(0), PARAM64(2), PARAM(4), PARAM(5)); +template void WrapU_UU64UU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM64(2), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapU_IU64UU() { - u32 retval = func(PARAM(0), PARAM64(2), PARAM(4), PARAM(5)); +template void WrapU_IU64UU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM64(2), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_IICU64() { - int retval = func(PARAM(0), PARAM(1), Memory::GetCharPointer(PARAM(2)), PARAM64(4)); +template void WrapI_IICU64(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), Memory::GetCharPointer(PARAM(2)), PARAM64(4)); RETURN(retval); } -template void WrapI64_II64I() { - s64 retval = func(PARAM(0), PARAM64(2), PARAM(4)); +template void WrapI64_II64I(MIPSState *mips) { + s64 retval = HLECall(mips, PARAM(0), PARAM64(2), PARAM(4)); RETURN64(retval); } //32bit wrappers -template void WrapV_V() { - func(); +template void WrapV_V(MIPSState *mips) { + HLECall(mips); } -template void WrapU_V() { - RETURN(func()); +template void WrapU_V(MIPSState *mips) { + RETURN((HLECall(mips))); } -template void WrapU_IVI() { - u32 retval = func(PARAM(0), Memory::GetPointerWriteOrException(PARAM(1)), PARAM(2)); +template void WrapU_IVI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetPointerWriteOrException(PARAM(1)), PARAM(2)); RETURN(retval); } -template void WrapI_CIIU() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_CIIU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_ICUVVUI() { - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointerWriteOrException(PARAM(3)),Memory::GetPointerWriteOrException(PARAM(4)), PARAM(5), PARAM(6) ); +template void WrapI_ICUVVUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointerWriteOrException(PARAM(3)),Memory::GetPointerWriteOrException(PARAM(4)), PARAM(5), PARAM(6) ); RETURN(retval); } // Hm, do so many params get passed in registers? -template void WrapI_CICIIIII() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), Memory::GetCharPointer(PARAM(2)), +template void WrapI_CICIIIII(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), Memory::GetCharPointer(PARAM(2)), PARAM(3), PARAM(4), PARAM(5), PARAM(6), PARAM(7)); RETURN(retval); } // Hm, do so many params get passed in registers? -template void WrapI_CIIIIII() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CIIIIII(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_IIIC() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), Memory::GetCharPointer(PARAM(3))); +template void WrapI_IIIC(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), Memory::GetCharPointer(PARAM(3))); RETURN(retval); } // Hm, do so many params get passed in registers? -template void WrapI_IIIIIIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); +template void WrapI_IIIIIIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } // Hm, do so many params get passed in registers? -template void WrapI_IIIIIIIIU() { +template void WrapI_IIIIIIIIU(MIPSState *mips) { u32 param8 = *(const u32_le *)Memory::GetPointerWriteOrException(currentMIPS->r[29]); //Fixed 9th parameter, thanks to Kingcom - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6), PARAM(7), param8); + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6), PARAM(7), param8); RETURN(retval); } -template void WrapU_IV() { - u32 retval = func(PARAM(0), Memory::GetPointerWriteOrException(PARAM(1))); +template void WrapU_IV(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetPointerWriteOrException(PARAM(1))); RETURN(retval); } -template void WrapF_V() { - RETURNF(func()); +template void WrapF_V(MIPSState *mips) { + RETURNF((HLECall(mips))); } // TODO: Not sure about the floating point parameter passing -template void WrapF_IFU() { - RETURNF(func(PARAM(0), PARAMF(0), PARAM(1))); +template void WrapF_IFU(MIPSState *mips) { + RETURNF((HLECall(mips, PARAM(0), PARAMF(0), PARAM(1)))); } -template void WrapU_U() { - u32 retval = func(PARAM(0)); +template void WrapU_U(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0)); RETURN(retval); } -template void WrapU_UI() { - u32 retval = func(PARAM(0), PARAM(1)); +template void WrapU_UI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapI_U() { - int retval = func(PARAM(0)); +template void WrapI_U(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0)); RETURN(retval); } -template void WrapI_UI() { - int retval = func(PARAM(0), PARAM(1)); +template void WrapI_UI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapI_UIIU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UIIU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_IUI() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_IUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_UU() { - int retval = func(PARAM(0), PARAM(1)); +template void WrapI_UU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapI_UFF() { +template void WrapI_UFF(MIPSState *mips) { // Not sure about the float arguments. - int retval = func(PARAM(0), PARAMF(0), PARAMF(1)); + int retval = HLECall(mips, PARAM(0), PARAMF(0), PARAMF(1)); RETURN(retval); } -template void WrapI_UUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_UUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_UUUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UUUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_UUUIIII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); +template void WrapI_UUUIIII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_UUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_UUUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_UUUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_UCUUI() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_UCUUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_UICUU() { - int retval = func(PARAM(0), PARAM(1), Memory::GetCharPointer(PARAM(2)), PARAM(3), PARAM(4)); +template void WrapI_UICUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), Memory::GetCharPointer(PARAM(2)), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_UUIC() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), Memory::GetCharPointer(PARAM(3))); +template void WrapI_UUIC(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), Memory::GetCharPointer(PARAM(3))); RETURN(retval); } -template void WrapI_UUIUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_UUIUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_V() { - int retval = func(); +template void WrapI_V(MIPSState *mips) { + int retval = HLECall(mips); RETURN(retval); } -template void WrapU_I() { - u32 retval = func(PARAM(0)); +template void WrapU_I(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0)); RETURN(retval); } -template void WrapU_IIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_IIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_I() { - int retval = func(PARAM(0)); +template void WrapI_I(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0)); RETURN(retval); } -template void WrapV_U() { - func(PARAM(0)); +template void WrapV_U(MIPSState *mips) { + HLECall(mips, PARAM(0)); } -template void WrapV_I() { - func(PARAM(0)); +template void WrapV_I(MIPSState *mips) { + HLECall(mips, PARAM(0)); } -template void WrapV_UU() { - func(PARAM(0), PARAM(1)); +template void WrapV_UU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1)); } -template void WrapV_II() { - func(PARAM(0), PARAM(1)); +template void WrapV_II(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1)); } -template void WrapV_UC() { - func(PARAM(0), Memory::GetCharPointer(PARAM(1))); +template void WrapV_UC(MIPSState *mips) { + HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1))); } -template void WrapI_UC() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1))); +template void WrapI_UC(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1))); RETURN(retval); } -template void WrapI_UCI() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2)); +template void WrapI_UCI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2)); RETURN(retval); } -template void WrapU_UIIIII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapU_UIIIII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapU_IIIIIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapU_IIIIIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapU_UIIIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapU_UIIIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapU_UIIIIII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); +template void WrapU_UIIIIII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapU_UU() { - u32 retval = func(PARAM(0), PARAM(1)); +template void WrapU_UU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapU_UUI() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_UUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_UUII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UUII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_CUUU() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_CUUU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapV_UIUII() { - func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapV_UIUII(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); } -template void WrapU_UIUII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapU_UIUII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_UIUII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_UIUII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapU_UIUI() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UIUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_UIUI() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UIUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_UIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_UIUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UIUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_UII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_UIIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UIIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_UIIUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_UIIUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_UUII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UUII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_UUIII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_UUIII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapV_UIII() { - func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapV_UIII(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); } -template void WrapV_UIIIII() { - func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapV_UIIIII(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); } -template void WrapV_UII() { - func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapV_UII(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); } -template void WrapU_IU() { - int retval = func(PARAM(0), PARAM(1)); +template void WrapU_IU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapI_IU() { - int retval = func(PARAM(0), PARAM(1)); +template void WrapI_IU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapI_UUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_UUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_UUIU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UUIU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_II() { - int retval = func(PARAM(0), PARAM(1)); +template void WrapI_II(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapI_III() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_III(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_IUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_IUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_IIII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_IIII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_UIII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UIII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_IIIUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_IIIUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_IIIUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_IIIUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_IUUII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_IUUII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_IUUIII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapI_IUUIII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_ICIUU() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_ICIUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_IIU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_IIU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapV_IU() { - func(PARAM(0), PARAM(1)); +template void WrapV_IU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1)); } -template void WrapV_UI() { - func(PARAM(0), PARAM(1)); +template void WrapV_UI(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1)); } -template void WrapU_C() { - u32 retval = func(Memory::GetCharPointer(PARAM(0))); +template void WrapU_C(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0))); RETURN(retval); } -template void WrapU_CCCU() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), +template void WrapU_CCCU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3)); RETURN(retval); } -template void WrapI_C() { - int retval = func(Memory::GetCharPointer(PARAM(0))); +template void WrapI_C(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0))); RETURN(retval); } -template void WrapI_CU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); +template void WrapI_CU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1)); RETURN(retval); } -template void WrapI_ICU() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2)); +template void WrapI_ICU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2)); RETURN(retval); } -template void WrapI_CUI() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapI_CUI(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_CUI() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapU_CUI(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_ICIU() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); +template void WrapI_ICIU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_ICUU() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); +template void WrapI_ICUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_ICUUU() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_ICUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_IIUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_IIUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_CIU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapI_CIU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_CUU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapI_CUU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_CUUU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CUUU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_CCII() { - int retval = func(Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); +template void WrapI_CCII(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_CUUIUU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CUUIUU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_CIIUII() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CIIUII(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_CIIIUUI() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CIIIUUI(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_CIUUU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CIUUU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_CUUUUU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CUUUUU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapU_CU() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); +template void WrapU_CU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1)); RETURN((u32) retval); } -template void WrapU_UC() { - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1))); +template void WrapU_UC(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1))); RETURN(retval); } -template void WrapU_CUU() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapU_CUU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN((u32) retval); } -template void WrapU_III() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_III(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_II() { - u32 retval = func(PARAM(0), PARAM(1)); +template void WrapU_II(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1)); RETURN(retval); } -template void WrapU_IIII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_IIII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_IUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_IUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_IUUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_IUUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_IUUUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapU_IUUUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapU_UUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapU_UUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapV_IUU() { - func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapV_IUU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); } -template void WrapV_IIU() { - func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapV_IIU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); } -template void WrapV_UIU() { - func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapV_UIU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); } -template void WrapI_UIU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_UIU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapV_IUUUU() { - func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapV_IUUUU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); } -template void WrapV_UUU() { - func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapV_UUU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); } -template void WrapV_UUUU() { - func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapV_UUUU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); } -template void WrapV_CUIU() { - func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); +template void WrapV_CUIU(MIPSState *mips) { + HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); } -template void WrapI_CUIU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_CUIU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapV_UCUIU() { - func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), +template void WrapV_UCUIU(MIPSState *mips) { + HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); } -template void WrapI_UCUIU() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), +template void WrapI_UCUIU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapV_CUIIU() { - func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), +template void WrapV_CUIIU(MIPSState *mips) { + HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); } -template void WrapI_CUIIU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapI_CUIIU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapU_UUUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UUUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UCUU() { - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); +template void WrapU_UCUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UUUI() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UUUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UUUIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapU_UUUIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapU_UUUIUI() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapU_UUUIUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapU_UUIU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UUIU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UIII() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapU_UIII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_IUUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapI_IUUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_IUUUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapI_IUUUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_IUUIUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapI_IUUIUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_IUII() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_IUII(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapU_UUUUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapU_UUUUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapV_UUUUU() { - func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); +template void WrapV_UUUUU(MIPSState *mips) { + HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); } -template void WrapU_CC() { - int retval = func(Memory::GetCharPointer(PARAM(0)), +template void WrapU_CC(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1))); RETURN(retval); } -template void WrapV_CI() { - func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); +template void WrapV_CI(MIPSState *mips) { + HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1)); } -template void WrapU_CI() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); +template void WrapU_CI(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1)); RETURN(retval); } -template void WrapU_CII() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapU_CII(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_CIUIU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapU_CIUIU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapU_CIUIUI() { - u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), +template void WrapU_CIUIUI(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapU_UUUUUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), +template void WrapU_UUUUUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_IUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_IUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_IUUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_IUUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_IUIIUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapI_IUIIUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_IUIIUI() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); +template void WrapI_IUIIUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } -template void WrapI_IUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); +template void WrapI_IUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_UUUUUUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); +template void WrapU_UUUUUUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_UUUUUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); +template void WrapI_UUUUUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_IUUUUUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); +template void WrapI_IUUUUUU(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_UIUU() { - u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)); +template void WrapI_UIUU(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); } -template void WrapI_IC() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1))); +template void WrapI_IC(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1))); RETURN(retval); } -template void WrapI_ICCUI() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3), PARAM(4)); +template void WrapI_ICCUI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3), PARAM(4)); RETURN(retval); } -template void WrapI_ICCI() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3)); +template void WrapI_ICCI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3)); RETURN(retval); } -template void WrapI_CII() { - int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapI_CII(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapI_ICI() { - int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2)); +template void WrapI_ICI(MIPSState *mips) { + int retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2)); RETURN(retval); } -template void WrapI_IVVVVUI(){ - u32 retval = func(PARAM(0), Memory::GetPointerWriteOrException(PARAM(1)), Memory::GetPointerWriteOrException(PARAM(2)), Memory::GetPointerWriteOrException(PARAM(3)), Memory::GetPointerWriteOrException(PARAM(4)), PARAM(5), PARAM(6) ); +template void WrapI_IVVVVUI(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetPointerWriteOrException(PARAM(1)), Memory::GetPointerWriteOrException(PARAM(2)), Memory::GetPointerWriteOrException(PARAM(3)), Memory::GetPointerWriteOrException(PARAM(4)), PARAM(5), PARAM(6) ); RETURN(retval); } -template void WrapI_ICUVIII(){ - u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointerWriteOrException(PARAM(3)), PARAM(4), PARAM(5), PARAM(6)); +template void WrapI_ICUVIII(MIPSState *mips) { + u32 retval = HLECall(mips, PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointerWriteOrException(PARAM(3)), PARAM(4), PARAM(5), PARAM(6)); RETURN(retval); } -template void WrapI_VUI(){ - u32 retval = func(Memory::GetPointerWriteOrException(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapI_VUI(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetPointerWriteOrException(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_VUU() { - u32 retval = func(Memory::GetPointerWriteOrException(PARAM(0)), PARAM(1), PARAM(2)); +template void WrapU_VUU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetPointerWriteOrException(PARAM(0)), PARAM(1), PARAM(2)); RETURN(retval); } -template void WrapU_VC() { - u32 retval = func(Memory::GetPointerWriteOrException(PARAM(0)), Memory::GetCharPointer(PARAM(1))); +template void WrapU_VC(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetPointerWriteOrException(PARAM(0)), Memory::GetCharPointer(PARAM(1))); RETURN(retval); } -template void WrapI_CCU() { - int retval = func(Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2)); +template void WrapI_CCU(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2)); RETURN(retval); } -template void WrapI_CC() { - int retval = func(Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1))); +template void WrapI_CC(MIPSState *mips) { + int retval = HLECall(mips, Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1))); RETURN(retval); } -template void WrapU_VCU() { - u32 retval = func(Memory::GetPointerWriteOrException(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2)); +template void WrapU_VCU(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetPointerWriteOrException(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2)); RETURN(retval); } -template void WrapU_VI() { - u32 retval = func(Memory::GetPointerWriteOrException(PARAM(0)), PARAM(1)); +template void WrapU_VI(MIPSState *mips) { + u32 retval = HLECall(mips, Memory::GetPointerWriteOrException(PARAM(0)), PARAM(1)); RETURN(retval); } diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index ff0808b005..e5adbd149f 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -868,12 +868,12 @@ static void hleFlushCalls(MIPSState *mips) { } enqueuedMipsCalls.clear(); - DEBUG_LOG(Log::HLE, "Executing HLE mips call at %08x, sp=%08x", currentMIPS->pc, sp); + DEBUG_LOG(Log::HLE, "Executing HLE mips call at %08x, sp=%08x", mips->pc, sp); } // This is a HLE function. -void HLEReturnFromMipsCall() { - u32 &sp = currentMIPS->r[MIPS_REG_SP]; +void HLEReturnFromMipsCall(MIPSState *mips) { + u32 &sp = mips->r[MIPS_REG_SP]; PSPPointer stackData; // At this point, we may have another mips call to run, or be at the end... @@ -919,9 +919,9 @@ void HLEReturnFromMipsCall() { if (stackData->nextOff == 0xFFFFFFFF) { // We're done. Grab the HLE result's v0/v1 and return from the syscall. - currentMIPS->pc = stackData->ra; - currentMIPS->r[MIPS_REG_V0] = stackData->v0; - currentMIPS->r[MIPS_REG_V1] = stackData->v1; + mips->pc = stackData->ra; + mips->r[MIPS_REG_V0] = stackData->v0; + mips->r[MIPS_REG_V1] = stackData->v1; sp += sizeof(HLEMipsCallStack); @@ -933,43 +933,43 @@ void HLEReturnFromMipsCall() { mipsCallActions.clear(); } - VERBOSE_LOG(Log::HLE, "Finished HLE mips calls, v0=%08x, sp=%08x", currentMIPS->r[MIPS_REG_V0], sp); + VERBOSE_LOG(Log::HLE, "Finished HLE mips calls, v0=%08x, sp=%08x", mips->r[MIPS_REG_V0], sp); hleNoLogVoid(); return; } // Alright, we have another to call. hleSkipDeadbeef(); - currentMIPS->pc = stackData->func; - currentMIPS->r[MIPS_REG_RA] = HLEMipsCallReturnAddress(); + mips->pc = stackData->func; + mips->r[MIPS_REG_RA] = HLEMipsCallReturnAddress(); for (int i = 0; i < (int)stackData->argc; i++) { // The check at the start of the function should be enough to use an unchecked read (well, kinda..) - currentMIPS->r[MIPS_REG_A0 + i] = Memory::ReadUnchecked_U32(sp + sizeof(HLEMipsCallStack) + i * sizeof(u32)); + mips->r[MIPS_REG_A0 + i] = Memory::ReadUnchecked_U32(sp + sizeof(HLEMipsCallStack) + i * sizeof(u32)); } - DEBUG_LOG(Log::HLE, "Executing next HLE mips call at %08x, sp=%08x", currentMIPS->pc, sp); + DEBUG_LOG(Log::HLE, "Executing next HLE mips call at %08x, sp=%08x", mips->pc, sp); hleNoLogVoid(); } const static u32 deadbeefRegs[12] = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF}; -inline static void SetDeadbeefRegs() +inline static void SetDeadbeefRegs(MIPSState *mips) { // Not exactly the same, but any time a syscall happens, it should clear ll. - currentMIPS->llBit = 0; + mips->llBit = 0; if (g_Config.bSkipDeadbeefFilling) return; - currentMIPS->r[MIPS_REG_COMPILER_SCRATCH] = 0xDEADBEEF; + mips->r[MIPS_REG_COMPILER_SCRATCH] = 0xDEADBEEF; // Set all the arguments and temp regs. TODO: Use SIMD to just do three writes. - memcpy(¤tMIPS->r[MIPS_REG_A0], deadbeefRegs, sizeof(deadbeefRegs)); - currentMIPS->r[MIPS_REG_T8] = 0xDEADBEEF; - currentMIPS->r[MIPS_REG_T9] = 0xDEADBEEF; + memcpy(&mips->r[MIPS_REG_A0], deadbeefRegs, sizeof(deadbeefRegs)); + mips->r[MIPS_REG_T8] = 0xDEADBEEF; + mips->r[MIPS_REG_T9] = 0xDEADBEEF; - currentMIPS->lo = 0xDEADBEEF; - currentMIPS->hi = 0xDEADBEEF; + mips->lo = 0xDEADBEEF; + mips->hi = 0xDEADBEEF; } -static void hleFinishSyscall(const HLEFunction *info) { +static void hleFinishSyscall(MIPSState *mips, const HLEFunction *info) { if (hleAfterSyscall & HLE_SPLIT_SYSCALL_OVER_GE) { hleAfterSyscall &= ~HLE_SPLIT_SYSCALL_OVER_GE; hleAfterSyscall |= HLE_SPLIT_SYSCALL_PART2; @@ -981,20 +981,20 @@ static void hleFinishSyscall(const HLEFunction *info) { if (hleAfterSyscall & HLE_SPLIT_SYSCALL_PART2) { // Eat the extra cycle we added above. - hleEatCycles(splitSyscallEatCycles + 1); + mips->downcount -= splitSyscallEatCycles + 1; // Make sure to zero it so it's not accidentally re-used. splitSyscallEatCycles = 0; } if (hleAfterSyscall & HLE_AFTER_CORETIMING_FORCE_CHECK) { - CoreTiming::ForceCheck(currentMIPS); + CoreTiming::ForceCheck(mips); } if ((hleAfterSyscall & HLE_AFTER_SKIP_DEADBEEF) == 0) - SetDeadbeefRegs(); + SetDeadbeefRegs(mips); if ((hleAfterSyscall & HLE_AFTER_QUEUED_CALLS) != 0) - hleFlushCalls(currentMIPS); + hleFlushCalls(mips); if ((hleAfterSyscall & HLE_AFTER_CURRENT_CALLBACKS) != 0 && (hleAfterSyscall & HLE_AFTER_RESCHED_CALLBACKS) == 0) __KernelForceCallbacks(); @@ -1019,8 +1019,8 @@ static void hleFinishSyscall(const HLEFunction *info) { hleAfterSyscallReschedReason = 0; } -void hleFinishSyscallAfterGe() { - hleFinishSyscall(nullptr); +void hleFinishSyscallAfterGe(MIPSState *mips) { + hleFinishSyscall(mips, nullptr); } static void UpdateSyscallStats(int modulenum, int funcnum, double total) { @@ -1052,7 +1052,7 @@ static void UpdateSyscallStats(int modulenum, int funcnum, double total) { } } -static void CallSyscallWithFlags(const HLEFunction *info) { +static void CallSyscallWithFlags(MIPSState *mips, const HLEFunction *info) { // _dbg_assert_(g_stackSize == 0); g_stackSize = 0; @@ -1061,14 +1061,14 @@ static void CallSyscallWithFlags(const HLEFunction *info) { g_stack[0] = info; g_stackSize = 1; } - g_syscallPC = currentMIPS->pc; + g_syscallPC = mips->pc; const u32 flags = info->flags; if (flags & HLE_CLEAR_STACK_BYTES) { u32 stackStart = __KernelGetCurThreadStackStart(); - if (currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear >= stackStart) { - Memory::Memset(currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear, 0, info->stackBytesToClear, "HLEStackClear"); + if (mips->r[MIPS_REG_SP] - info->stackBytesToClear >= stackStart) { + Memory::Memset(mips->r[MIPS_REG_SP] - info->stackBytesToClear, 0, info->stackBytesToClear, "HLEStackClear"); } } @@ -1077,7 +1077,7 @@ static void CallSyscallWithFlags(const HLEFunction *info) { } else if ((flags & HLE_NOT_IN_INTERRUPT) && __IsInInterrupt()) { RETURN(hleLogDebug(Log::HLE, SCE_KERNEL_ERROR_ILLEGAL_CONTEXT, "in interrupt")); } else { - info->func(); + info->func(mips); } // Now, g_stackSize should be back to 0. Enable this for "pedantic mode", will find a lot of problems. @@ -1085,14 +1085,14 @@ static void CallSyscallWithFlags(const HLEFunction *info) { // _dbg_assert_(g_stackSize == 0); if (hleAfterSyscall != HLE_AFTER_NOTHING) - hleFinishSyscall(info); + hleFinishSyscall(mips, info); else - SetDeadbeefRegs(); + SetDeadbeefRegs(mips); g_stackSize = 0; } -static void CallSyscallWithoutFlags(const HLEFunction *info) { +static void CallSyscallWithoutFlags(MIPSState *mips, const HLEFunction *info) { // _dbg_assert_(g_stackSize == 0); g_stackSize = 0; @@ -1101,18 +1101,18 @@ static void CallSyscallWithoutFlags(const HLEFunction *info) { g_stack[0] = info; g_stackSize = 1; } - g_syscallPC = currentMIPS->pc; + g_syscallPC = mips->pc; - info->func(); + info->func(mips); // Now, g_stackSize should be back to 0. Enable this for "pedantic mode", will find a lot of problems. // Check g_stack[0] in the debugger. // _dbg_assert_(g_stackSize == 0); if (hleAfterSyscall != HLE_AFTER_NOTHING) - hleFinishSyscall(info); + hleFinishSyscall(mips, info); else - SetDeadbeefRegs(); + SetDeadbeefRegs(mips); g_stackSize = 0; } @@ -1178,7 +1178,7 @@ void hleSetFlipTime(double t) { hleFlipTime = t; } -void CallSyscallWithPC(MIPSOpcode op, u32 pc) { +void CallSyscallWithPC(MIPSState *mips, MIPSOpcode op, u32 pc) { PROFILE_THIS_SCOPE("syscall"); const bool collectStats = g_coreCollectDebugStats; double start = 0.0; @@ -1195,11 +1195,11 @@ void CallSyscallWithPC(MIPSOpcode op, u32 pc) { if (info->func) { if (op == g_idleOp) - info->func(); + info->func(mips); else if (info->flags != 0) - CallSyscallWithFlags(info); + CallSyscallWithFlags(mips, info); else - CallSyscallWithoutFlags(info); + CallSyscallWithoutFlags(mips, info); } else { // We haven't incremented the stack yet. RETURN(SCE_KERNEL_ERROR_LIBRARY_NOT_YET_LINKED); @@ -1219,11 +1219,11 @@ void CallSyscallWithPC(MIPSOpcode op, u32 pc) { } } -void CallSyscall(MIPSOpcode op) { - CallSyscallWithPC(op, 0); +void CallSyscall(MIPSState *mips, MIPSOpcode op) { + CallSyscallWithPC(mips, op, 0); } -void CallSyscallUnresolvedAtPC(u32 pc) { +void CallSyscallUnresolvedAtPC(MIPSState *mips, u32 pc) { LogBadSyscallAtPC(pc, false); // Same as the !info path in CallSyscallWithPC - the call has to leave an error in v0, // otherwise the caller sees a stale value and thinks the unresolved import succeeded. @@ -1249,16 +1249,16 @@ void hlePushFuncDesc(std::string_view module, std::string_view funcName) { // Fetches one word of a variadic argument list. Note that this is not the o32 layout - psp-gcc // builds for the MIPS EABI, where the first eight arguments go in a0-a3 and t0-t3, and the rest // on the stack starting at sp+0 (o32 would pass four in registers and start the stack at sp+16). -static bool ReadVarArgWord(int index, u32 *value) { +static bool ReadVarArgWord(const MIPSState *mips, int index, u32 *value) { if (index < 4) { - *value = currentMIPS->r[MIPS_REG_A0 + index]; + *value = mips->r[MIPS_REG_A0 + index]; return true; } if (index < 8) { - *value = currentMIPS->r[MIPS_REG_T0 + index - 4]; + *value = mips->r[MIPS_REG_T0 + index - 4]; return true; } - const u32 addr = currentMIPS->r[MIPS_REG_SP] + (index - 8) * 4; + const u32 addr = mips->r[MIPS_REG_SP] + (index - 8) * 4; if (!Memory::IsValid4AlignedAddress(addr)) { ERROR_LOG(Log::HLE, "printf: bad stack pointer %08x", addr); return false; @@ -1267,7 +1267,7 @@ static bool ReadVarArgWord(int index, u32 *value) { return true; } -bool HLEFormatPrintf(u32 fmtAddr, int firstVarArg, std::string *result) { +bool HLEFormatPrintf(const MIPSState *mips, u32 fmtAddr, int firstVarArg, std::string *result) { if (!Memory::IsValidNullTerminatedString(fmtAddr)) { ERROR_LOG(Log::HLE, "printf: bad format string at %08x", fmtAddr); return false; @@ -1275,10 +1275,10 @@ bool HLEFormatPrintf(u32 fmtAddr, int firstVarArg, std::string *result) { VERBOSE_LOG(Log::HLE, "printf fmt: %s", Memory::GetCharPointerUnchecked(fmtAddr)); VERBOSE_LOG(Log::HLE, "printf a0-a3, t0-t3: %08x %08x %08x %08x %08x %08x %08x %08x", - currentMIPS->r[MIPS_REG_A0], currentMIPS->r[MIPS_REG_A1], - currentMIPS->r[MIPS_REG_A2], currentMIPS->r[MIPS_REG_A3], - currentMIPS->r[MIPS_REG_T0], currentMIPS->r[MIPS_REG_T1], - currentMIPS->r[MIPS_REG_T2], currentMIPS->r[MIPS_REG_T3]); + mips->r[MIPS_REG_A0], mips->r[MIPS_REG_A1], + mips->r[MIPS_REG_A2], mips->r[MIPS_REG_A3], + mips->r[MIPS_REG_T0], mips->r[MIPS_REG_T1], + mips->r[MIPS_REG_T2], mips->r[MIPS_REG_T3]); bool processingSpecifier = false; std::string specifier; @@ -1310,7 +1310,7 @@ bool HLEFormatPrintf(u32 fmtAddr, int firstVarArg, std::string *result) { case 's': { u32 val = 0; - if (!ReadVarArgWord(argIndex++, &val)) { + if (!ReadVarArgWord(mips, argIndex++, &val)) { return false; } if (!Memory::IsValidNullTerminatedString(val)) { @@ -1344,7 +1344,7 @@ bool HLEFormatPrintf(u32 fmtAddr, int firstVarArg, std::string *result) { int readCount = 0; while (bytesToRead != 0) { u32 word = 0; - if (!ReadVarArgWord(argIndex++, &word)) { + if (!ReadVarArgWord(mips, argIndex++, &word)) { return false; } val = val | ((u64)word << (readCount * 32)); @@ -1391,7 +1391,7 @@ size_t HLEFormatLogArgs(const MIPSState *mips, char *message, size_t sz, const c for (size_t i = 0, n = strlen(argmask); i < n; ++i, ++reg) { u32 regval; if (reg < 8) { - regval = PARAM_MIPS(mips, reg); + regval = PARAM(reg); } else { u32 sp = mips->r[MIPS_REG_SP]; // Goes upward on stack. diff --git a/Core/HLE/HLE.h b/Core/HLE/HLE.h index fb65bbffd0..c4b5874f36 100644 --- a/Core/HLE/HLE.h +++ b/Core/HLE/HLE.h @@ -33,7 +33,7 @@ class PointerWrap; class PSPAction; -typedef void (* HLEFunc)(); +typedef void (* HLEFunc)(MIPSState *mips); enum { // The low 8 bits are a value, indicating special jit handling. @@ -91,14 +91,13 @@ struct Syscall { u32 nid; }; -#define PARAM(n) currentMIPS->r[MIPS_REG_A0 + n] -#define PARAM64(n) (currentMIPS->r[MIPS_REG_A0 + n] | ((u64)currentMIPS->r[MIPS_REG_A0 + n + 1] << 32)) -#define PARAMF(n) currentMIPS->f[12 + n] -#define RETURN(n) currentMIPS->r[MIPS_REG_V0] = n; -#define RETURN64(n) {u64 RETURN64_tmp = n; currentMIPS->r[MIPS_REG_V0] = RETURN64_tmp & 0xFFFFFFFF; currentMIPS->r[MIPS_REG_V1] = RETURN64_tmp >> 32;} -#define RETURNF(fl) currentMIPS->f[0] = fl - -#define PARAM_MIPS(mips, n) mips->r[MIPS_REG_A0 + n] +// These work on the MIPSState named mips, which HLE functions get passed (see HLEFunc and FunctionWrappers.h). +#define PARAM(n) mips->r[MIPS_REG_A0 + n] +#define PARAM64(n) (mips->r[MIPS_REG_A0 + n] | ((u64)mips->r[MIPS_REG_A0 + n + 1] << 32)) +#define PARAMF(n) mips->f[12 + n] +#define RETURN(n) mips->r[MIPS_REG_V0] = n; +#define RETURN64(n) {u64 RETURN64_tmp = n; mips->r[MIPS_REG_V0] = RETURN64_tmp & 0xFFFFFFFF; mips->r[MIPS_REG_V1] = RETURN64_tmp >> 32;} +#define RETURNF(fl) mips->f[0] = fl struct HLEModuleMeta { // This is the modname (name from the PRX header). Probably, we should really blacklist on the module names of the exported symbol metadata. @@ -174,7 +173,7 @@ void hleCoreTimingForceCheck(); void hleSplitSyscallOverGe(); // Called after a split syscall from System.cpp -void hleFinishSyscallAfterGe(); +void hleFinishSyscallAfterGe(MIPSState *mips); [[nodiscard]] inline int hleDelayResult(int result, const char *reason, int usec) { @@ -200,19 +199,19 @@ size_t HLEFormatLogArgs(const MIPSState *mips, char *message, size_t sz, const c // registers and stack. firstVarArg is the index of the first vararg, counting a0 as 0 - so 1 for a // printf(fmt, ...), 2 for an sprintf(dst, fmt, ...). Returns false, having logged why, if the format // string or an argument couldn't be read; the caller shouldn't use the result then. -bool HLEFormatPrintf(u32 fmtAddr, int firstVarArg, std::string *result); +bool HLEFormatPrintf(const MIPSState *mips, u32 fmtAddr, int firstVarArg, std::string *result); u32 GetSyscallOp(std::string_view module, u32 nib); bool WriteHLESyscall(std::string_view module, u32 nib, u32 address); -void CallSyscall(MIPSOpcode op); -void CallSyscallWithPC(MIPSOpcode op, u32 pc); // better diagnostics -void CallSyscallUnresolvedAtPC(u32 pc); +void CallSyscall(MIPSState *mips, MIPSOpcode op); +void CallSyscallWithPC(MIPSState *mips, MIPSOpcode op, u32 pc); // better diagnostics +void CallSyscallUnresolvedAtPC(MIPSState *mips, u32 pc); void WriteFuncStub(u32 stubAddr, u32 symAddr); void WriteFuncMissingStub(u32 stubAddr, u32 nid); -void HLEReturnFromMipsCall(); +void HLEReturnFromMipsCall(MIPSState *mips); const HLEFunction *GetSyscallFunctionData(MIPSOpcode op, u32 pcForDiagnostics); -// For jit, the returned function takes the arg: const HLEFunction * +// For jit, the returned function takes the args: MIPSState *, const HLEFunction * void *GetQuickSyscallFunc(const HLEFunction *info, MIPSOpcode op); void hleDoLogInternal(Log t, LogLevel level, u64 res, const char *file, int line, const char *reportTag, const char *reason, const char *formatted_reason); diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index f3215a3c61..64e3cf9419 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -181,9 +181,9 @@ static u32 sceKernelSm1ReferOperations() { // We format it and put it in the log, which is the useful thing to do with it. // Declared void in the SDK headers, so the return value doesn't matter, but 0 is what the // firmware leaves in v0. -static u32 Kprintf(u32 fmtAddr) { +static u32 Kprintf(MIPSState *mips, u32 fmtAddr) { std::string formatted; - if (!HLEFormatPrintf(fmtAddr, 1, &formatted)) { + if (!HLEFormatPrintf(mips, fmtAddr, 1, &formatted)) { return hleLogError(Log::Printf, 0, "bad format string or args"); } // Each log line is already a line, so don't double space. diff --git a/Core/HLE/KUBridge.cpp b/Core/HLE/KUBridge.cpp index aebb69a284..81342b604d 100644 --- a/Core/HLE/KUBridge.cpp +++ b/Core/HLE/KUBridge.cpp @@ -25,10 +25,10 @@ #include "Core/HLE/sceKernelModule.h" #include "Core/Config.h" -static int kuKernelLoadModule(const char *path, uint32_t flags, uint32_t lmOptionAddr) { +static int kuKernelLoadModule(MIPSState *mips, const char *path, uint32_t flags, uint32_t lmOptionAddr) { INFO_LOG(Log::sceKernel, "kuKernelLoadModule - forwarding to sceKernelLoadModule"); // Simply forward the call, like JPSCP does. - return sceKernelLoadModule(path, flags, lmOptionAddr); + return sceKernelLoadModule(mips, path, flags, lmOptionAddr); } static int kuKernelGetModel() { diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 246b74ef10..f1db1aad15 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -56,62 +56,62 @@ static int skipGPUReplacements = 0; // I think these have to be pretty accurate as these are libc replacements, // but we can probably get away with approximating the VFPU vsin/vcos and vrot // pretty roughly. -static int Replace_sinf() { +static int Replace_sinf(MIPSState *mips) { float f = PARAMF(0); RETURNF(sinf(f)); return 80; // guess number of cycles } -static int Replace_cosf() { +static int Replace_cosf(MIPSState *mips) { float f = PARAMF(0); RETURNF(cosf(f)); return 80; // guess number of cycles } -static int Replace_tanf() { +static int Replace_tanf(MIPSState *mips) { float f = PARAMF(0); RETURNF(tanf(f)); return 80; // guess number of cycles } -static int Replace_acosf() { +static int Replace_acosf(MIPSState *mips) { float f = PARAMF(0); RETURNF(acosf(f)); return 80; // guess number of cycles } -static int Replace_asinf() { +static int Replace_asinf(MIPSState *mips) { float f = PARAMF(0); RETURNF(asinf(f)); return 80; // guess number of cycles } -static int Replace_atanf() { +static int Replace_atanf(MIPSState *mips) { float f = PARAMF(0); RETURNF(atanf(f)); return 80; // guess number of cycles } -static int Replace_sqrtf() { +static int Replace_sqrtf(MIPSState *mips) { float f = PARAMF(0); RETURNF(sqrtf(f)); return 80; // guess number of cycles } -static int Replace_atan2f() { +static int Replace_atan2f(MIPSState *mips) { float f1 = PARAMF(0); float f2 = PARAMF(1); RETURNF(atan2f(f1, f2)); return 120; // guess number of cycles } -static int Replace_floorf() { +static int Replace_floorf(MIPSState *mips) { float f1 = PARAMF(0); RETURNF(floorf(f1)); return 30; // guess number of cycles } -static int Replace_ceilf() { +static int Replace_ceilf(MIPSState *mips) { float f1 = PARAMF(0); RETURNF(ceilf(f1)); return 30; // guess number of cycles @@ -119,7 +119,7 @@ static int Replace_ceilf() { // Should probably do JIT versions of this, possibly ones that only delegate // large copies to a C function. -static int Replace_memcpy() { +static int Replace_memcpy(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); @@ -176,7 +176,7 @@ static int Replace_memcpy() { return 10 + bytes / 4; // approximation } -static int Replace_memcpy_jak() { +static int Replace_memcpy_jak(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); @@ -215,17 +215,17 @@ static int Replace_memcpy_jak() { } if (sliced) { - currentMIPS->r[MIPS_REG_A0] += SLICE_SIZE; - currentMIPS->r[MIPS_REG_A1] += SLICE_SIZE; - currentMIPS->r[MIPS_REG_A2] -= SLICE_SIZE; + mips->r[MIPS_REG_A0] += SLICE_SIZE; + mips->r[MIPS_REG_A1] += SLICE_SIZE; + mips->r[MIPS_REG_A2] -= SLICE_SIZE; } else { // Jak relies on more registers coming out right than the ABI specifies. // See the disassembly of the function for the explanations for these... - currentMIPS->r[MIPS_REG_T0] = 0; - currentMIPS->r[MIPS_REG_A0] = -1; - currentMIPS->r[MIPS_REG_A2] = 0; + mips->r[MIPS_REG_T0] = 0; + mips->r[MIPS_REG_A0] = -1; + mips->r[MIPS_REG_A2] = 0; // Even after slicing, this ends up correct. - currentMIPS->r[MIPS_REG_A3] = destPtr + bytes; + mips->r[MIPS_REG_A3] = destPtr + bytes; RETURN(destPtr); } @@ -253,7 +253,7 @@ static int Replace_memcpy_jak() { return 5 + bytes * 8 + 2; // approximation. This is a slow memcpy - a byte copy loop.. } -static int Replace_memcpy16() { +static int Replace_memcpy16(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 bytes = PARAM(2) * 16; @@ -281,7 +281,7 @@ static int Replace_memcpy16() { return 10 + bytes / 4; // approximation } -static int Replace_memcpy_swizzled() { +static int Replace_memcpy_swizzled(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 pitch = PARAM(2); @@ -320,7 +320,7 @@ static int Replace_memcpy_swizzled() { return 10 + (pitch * h) / 4; // approximation } -static int Replace_memmove() { +static int Replace_memmove(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); @@ -348,7 +348,7 @@ static int Replace_memmove() { return 10 + bytes / 4; // approximation } -static int Replace_memset() { +static int Replace_memset(MIPSState *mips) { u32 destPtr = PARAM(0); u8 value = PARAM(1); u32 bytes = PARAM(2); @@ -369,7 +369,7 @@ static int Replace_memset() { return 10 + bytes / 4; // approximation } -static int Replace_memset_jak() { +static int Replace_memset_jak(MIPSState *mips) { u32 destPtr = PARAM(0); u8 value = PARAM(1); u32 bytes = PARAM(2); @@ -400,8 +400,8 @@ static int Replace_memset_jak() { NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemset"); if (sliced) { - currentMIPS->r[MIPS_REG_A0] += SLICE_SIZE; - currentMIPS->r[MIPS_REG_A2] -= SLICE_SIZE; + mips->r[MIPS_REG_A0] += SLICE_SIZE; + mips->r[MIPS_REG_A2] -= SLICE_SIZE; // This is approximate, and must be a negative value. // Negative causes the function to be run again for the next slice. @@ -409,9 +409,9 @@ static int Replace_memset_jak() { } // Even after slicing, this ends up correct. - currentMIPS->r[MIPS_REG_T0] = destPtr + bytes; - currentMIPS->r[MIPS_REG_A2] = -1; - currentMIPS->r[MIPS_REG_A3] = -1; + mips->r[MIPS_REG_T0] = destPtr + bytes; + mips->r[MIPS_REG_A2] = -1; + mips->r[MIPS_REG_A3] = -1; RETURN(destPtr); return 5 + bytes * 6 + 2; // approximation @@ -428,14 +428,14 @@ static uint32_t SafeStringLen(const uint32_t ptr, uint32_t maxLen = 0x07FFFFFF) return (uint32_t)(end - p); } -static int Replace_strlen() { +static int Replace_strlen(MIPSState *mips) { u32 srcPtr = PARAM(0); u32 len = SafeStringLen(srcPtr); RETURN(len); return 7 + len * 4; // approximation } -static int Replace_strcpy() { +static int Replace_strcpy(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 len = SafeStringLen(srcPtr); @@ -448,7 +448,7 @@ static int Replace_strcpy() { return 10; // approximation } -static int Replace_strncpy() { +static int Replace_strncpy(MIPSState *mips) { u32 destPtr = PARAM(0); u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); @@ -462,7 +462,7 @@ static int Replace_strncpy() { return 10; // approximation } -static int Replace_strcmp() { +static int Replace_strcmp(MIPSState *mips) { u32 aLen = SafeStringLen(PARAM(0)); const char *a = (const char *)Memory::GetPointerRangeOrException(PARAM(0), aLen); u32 bLen = SafeStringLen(PARAM(1)); @@ -475,7 +475,7 @@ static int Replace_strcmp() { return 10; // approximation } -static int Replace_strncmp() { +static int Replace_strncmp(MIPSState *mips) { u32 bytes = PARAM(2); u32 aLen = SafeStringLen(PARAM(0), bytes); const char *a = (const char *)Memory::GetPointerRangeOrException(PARAM(0), aLen == 0 ? bytes : aLen); @@ -489,12 +489,12 @@ static int Replace_strncmp() { return 10 + bytes / 4; // approximation } -static int Replace_fabsf() { +static int Replace_fabsf(MIPSState *mips) { RETURNF(fabsf(PARAMF(0))); return 4; } -static int Replace_vmmul_q_transp() { +static int Replace_vmmul_q_transp(MIPSState *mips) { float_le *out = (float_le *)Memory::GetPointerRangeOrException(PARAM(0), 16 * 4); const float_le *a = (const float_le *)Memory::GetPointerRangeOrException(PARAM(1), 16 * 4); const float_le *b = (const float_le *)Memory::GetPointerRangeOrException(PARAM(2), 16 * 4); @@ -521,7 +521,7 @@ static int Replace_vmmul_q_transp() { // a0 = pointer to destination address // a1 = matrix // a2 = source address -static int Replace_gta_dl_write_matrix() { +static int Replace_gta_dl_write_matrix(MIPSState *mips) { u32_le *ptr = (u32_le *)Memory::GetPointerWriteRangeOrException(PARAM(0), 4); const u32_le *src = (const u32_le *)Memory::GetPointerRangeOrException(PARAM(2), 16); u32 matrix = PARAM(1) << 24; @@ -580,7 +580,7 @@ static int Replace_gta_dl_write_matrix() { // TODO: Inline into a few NEON or SSE instructions - especially if a1 is a known immediate! // Anyway, not sure if worth it. There's not that many matrices written per frame normally. -static int Replace_dl_write_matrix() { +static int Replace_dl_write_matrix(MIPSState *mips) { u32_le *dlStruct = (u32_le *)Memory::GetPointerWriteRangeOrException(PARAM(0), 3 * 4); const u32_le *src = (const u32_le *)Memory::GetPointerRangeOrException(PARAM(2), 16 * 4); @@ -699,12 +699,12 @@ static int Replace_dl_write_matrix() { return 60; } -static bool GetMIPSStaticAddress(u32 &addr, s32 lui_offset, s32 lw_offset) { - const MIPSOpcode upper = Memory::Read_Instruction(currentMIPS->pc + lui_offset); +static bool GetMIPSStaticAddress(const MIPSState *mips, u32 &addr, s32 lui_offset, s32 lw_offset) { + const MIPSOpcode upper = Memory::Read_Instruction(mips->pc + lui_offset); if (upper != MIPS_MAKE_LUI(MIPS_GET_RT(upper), upper & 0xffff)) { return false; } - const MIPSOpcode lower = Memory::Read_Instruction(currentMIPS->pc + lw_offset); + const MIPSOpcode lower = Memory::Read_Instruction(mips->pc + lw_offset); if (lower != MIPS_MAKE_LW(MIPS_GET_RT(lower), MIPS_GET_RS(lower), lower & 0xffff)) { if (lower != MIPS_MAKE_ORI(MIPS_GET_RT(lower), MIPS_GET_RS(lower), lower & 0xffff)) { return false; @@ -714,26 +714,26 @@ static bool GetMIPSStaticAddress(u32 &addr, s32 lui_offset, s32 lw_offset) { return true; } -static bool GetMIPSGPAddress(u32 &addr, s32 offset) { - const MIPSOpcode loadOp = Memory::Read_Instruction(currentMIPS->pc + offset); +static bool GetMIPSGPAddress(const MIPSState *mips, u32 &addr, s32 offset) { + const MIPSOpcode loadOp = Memory::Read_Instruction(mips->pc + offset); if (MIPS_GET_RS(loadOp) == MIPS_REG_GP) { s16 gpoff = (s16)(u16)(loadOp & 0x0000FFFF); - addr = currentMIPS->r[MIPS_REG_GP] + gpoff; + addr = mips->r[MIPS_REG_GP] + gpoff; return true; } return false; } -static int Hook_godseaterburst_blit_texture() { +static int Hook_godseaterburst_blit_texture(MIPSState *mips) { u32 texaddr; // Only if there's no texture. - if (!GetMIPSStaticAddress(texaddr, 0x000c, 0x0030) || !Memory::IsValid4AlignedAddress(texaddr)) { + if (!GetMIPSStaticAddress(mips, texaddr, 0x000c, 0x0030) || !Memory::IsValid4AlignedAddress(texaddr)) { return 0; } u32 fb_infoaddr; - if (Memory::ReadUnchecked_U32(texaddr) != 0 || !GetMIPSStaticAddress(fb_infoaddr, 0x01d0, 0x01d4) || !Memory::IsValid4AlignedAddress(fb_infoaddr)) { + if (Memory::ReadUnchecked_U32(texaddr) != 0 || !GetMIPSStaticAddress(mips, fb_infoaddr, 0x01d0, 0x01d4) || !Memory::IsValid4AlignedAddress(fb_infoaddr)) { return 0; } @@ -750,14 +750,14 @@ static int Hook_godseaterburst_blit_texture() { return 0; } -static int Hook_godseaterburst_depthmask_5551() { +static int Hook_godseaterburst_depthmask_5551(MIPSState *mips) { // This function copies the 5551 framebuffer to a temporary, generating alpha based on depth. // Depth is optional, in which case all pixels get full alpha. // Called when your avatar changes to screenshot for save data. - uint32_t colorBuffer = currentMIPS->r[MIPS_REG_A1]; - uint32_t depthBuffer = currentMIPS->r[MIPS_REG_T2]; - uint32_t byteStride = currentMIPS->r[MIPS_REG_A2]; - uint32_t height = currentMIPS->r[MIPS_REG_T1]; + uint32_t colorBuffer = mips->r[MIPS_REG_A1]; + uint32_t depthBuffer = mips->r[MIPS_REG_T2]; + uint32_t byteStride = mips->r[MIPS_REG_A2]; + uint32_t height = mips->r[MIPS_REG_T1]; uint32_t size = byteStride * height; if (!Memory::IsVRAMAddress(colorBuffer) || !Memory::IsValidRange(colorBuffer, size)) @@ -779,9 +779,9 @@ static int Hook_godseaterburst_depthmask_5551() { return 0; } -static int Hook_hexyzforce_monoclome_thread() { +static int Hook_hexyzforce_monoclome_thread(MIPSState *mips) { u32 fb_info; - if (!GetMIPSStaticAddress(fb_info, -4, 0)) { + if (!GetMIPSStaticAddress(mips, fb_info, -4, 0)) { return 0; } if (!Memory::IsValid4AlignedAddress(fb_info)) { @@ -795,16 +795,16 @@ static int Hook_hexyzforce_monoclome_thread() { return 0; } -static int Hook_starocean_write_stencil() { - const u32 fb_address = currentMIPS->r[MIPS_REG_T7]; +static int Hook_starocean_write_stencil(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_T7]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformWriteStencilFromMemory(fb_address, 0x00088000, WriteStencil::IGNORE_ALPHA); } return 0; } -static int Hook_topx_create_saveicon() { - const u32 fb_address = currentMIPS->r[MIPS_REG_V0]; +static int Hook_topx_create_saveicon(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_V0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformMemoryCopy(fb_address, fb_address, 0x00044000, GPUCopyFlag::FORCE_DST_MATCH_MEM | GPUCopyFlag::DISALLOW_CREATE_VFB); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "topx_create_saveicon"); @@ -812,8 +812,8 @@ static int Hook_topx_create_saveicon() { return 0; } -static int Hook_ff1_battle_effect() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A1]; +static int Hook_ff1_battle_effect(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A1]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "ff1_battle_effect"); @@ -821,9 +821,9 @@ static int Hook_ff1_battle_effect() { return 0; } -static int Hook_dissidia_recordframe_avi() { +static int Hook_dissidia_recordframe_avi(MIPSState *mips) { // This is called once per frame, and records that frame's data to avi. - const u32 fb_address = currentMIPS->r[MIPS_REG_A1]; + const u32 fb_address = mips->r[MIPS_REG_A1]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "dissidia_recordframe_avi"); @@ -831,23 +831,23 @@ static int Hook_dissidia_recordframe_avi() { return 0; } -static int Hook_brandish_download_frame() { +static int Hook_brandish_download_frame(MIPSState *mips) { u32 fb_infoaddr; - if (!GetMIPSStaticAddress(fb_infoaddr, 0x2c, 0x30)) { + if (!GetMIPSStaticAddress(mips, fb_infoaddr, 0x2c, 0x30)) { return 0; } if (!Memory::IsValid4AlignedRange(fb_infoaddr, 256)) { // TODO: Figure out the right range to check. return 0; } const u32 fb_info = Memory::ReadUnchecked_U32(fb_infoaddr); - const MIPSOpcode fb_index_load = Memory::Read_Instruction(currentMIPS->pc + 0x38); + const MIPSOpcode fb_index_load = Memory::Read_Instruction(mips->pc + 0x38); if (fb_index_load != MIPS_MAKE_LW(MIPS_GET_RT(fb_index_load), MIPS_GET_RS(fb_index_load), fb_index_load & 0xffff)) { return 0; } const int fb_index_offset = (s16)(fb_index_load & 0xffff); const u32 fb_index = (Memory::ReadUnchecked_U32(fb_info + fb_index_offset) + 1) & 1; const u32 fb_address = 0x4000000 + (0x44000 * fb_index); - const u32 dest_address = currentMIPS->r[MIPS_REG_A1]; + const u32 dest_address = mips->r[MIPS_REG_A1]; if (Memory::IsRAMAddress(dest_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "brandish_download_frame"); @@ -855,9 +855,9 @@ static int Hook_brandish_download_frame() { return 0; } -static int Hook_growlanser_create_saveicon() { - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP] + 4); - const u32 fmt = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP]); +static int Hook_growlanser_create_saveicon(MIPSState *mips) { + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP] + 4); + const u32 fmt = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP]); const u32 sz = fmt == GE_FORMAT_8888 ? 0x00088000 : 0x00044000; if (Memory::IsVRAMAddress(fb_address) && fmt <= 3) { gpu->PerformMemoryCopy(fb_address, fb_address, sz, GPUCopyFlag::FORCE_DST_MATCH_MEM | GPUCopyFlag::DISALLOW_CREATE_VFB); @@ -866,9 +866,9 @@ static int Hook_growlanser_create_saveicon() { return 0; } -static int Hook_sd_gundam_g_generation_download_frame() { - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP] + 8); - const u32 fmt = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP] + 4); +static int Hook_sd_gundam_g_generation_download_frame(MIPSState *mips) { + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP] + 8); + const u32 fmt = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP] + 4); const u32 sz = fmt == GE_FORMAT_8888 ? 0x00088000 : 0x00044000; if (Memory::IsVRAMAddress(fb_address) && fmt <= 3) { gpu->PerformReadbackToMemory(fb_address, sz); @@ -877,8 +877,8 @@ static int Hook_sd_gundam_g_generation_download_frame() { return 0; } -static int Hook_narisokonai_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_V0]; +static int Hook_narisokonai_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_V0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "narisokonai_download_frame"); @@ -886,8 +886,8 @@ static int Hook_narisokonai_download_frame() { return 0; } -static int Hook_kirameki_school_life_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A2]; +static int Hook_kirameki_school_life_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A2]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kirameki_school_life_download_frame"); @@ -895,8 +895,8 @@ static int Hook_kirameki_school_life_download_frame() { return 0; } -static int Hook_orenoimouto_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A4]; +static int Hook_orenoimouto_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A4]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "orenoimouto_download_frame"); @@ -904,8 +904,8 @@ static int Hook_orenoimouto_download_frame() { return 0; } -static int Hook_sakurasou_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_V0]; +static int Hook_sakurasou_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_V0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "sakurasou_download_frame"); @@ -913,8 +913,8 @@ static int Hook_sakurasou_download_frame() { return 0; } -static int Hook_suikoden1_and_2_download_frame_1() { - const u32 fb_address = currentMIPS->r[MIPS_REG_S4]; +static int Hook_suikoden1_and_2_download_frame_1(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_S4]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "suikoden1_and_2_download_frame_1"); @@ -922,8 +922,8 @@ static int Hook_suikoden1_and_2_download_frame_1() { return 0; } -static int Hook_suikoden1_and_2_download_frame_2() { - const u32 fb_address = currentMIPS->r[MIPS_REG_S2]; +static int Hook_suikoden1_and_2_download_frame_2(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_S2]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "suikoden1_and_2_download_frame_2"); @@ -931,9 +931,9 @@ static int Hook_suikoden1_and_2_download_frame_2() { return 0; } -static int Hook_rezel_cross_download_frame() { - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP] + 0x1C); - const u32 fmt = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP] + 0x14); +static int Hook_rezel_cross_download_frame(MIPSState *mips) { + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP] + 0x1C); + const u32 fmt = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP] + 0x14); const u32 sz = fmt == GE_FORMAT_8888 ? 0x00088000 : 0x00044000; if (Memory::IsVRAMAddress(fb_address) && fmt <= 3) { gpu->PerformReadbackToMemory(fb_address, sz); @@ -942,8 +942,8 @@ static int Hook_rezel_cross_download_frame() { return 0; } -static int Hook_kagaku_no_ensemble_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_V0]; +static int Hook_kagaku_no_ensemble_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_V0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kagaku_no_ensemble_download_frame"); @@ -951,8 +951,8 @@ static int Hook_kagaku_no_ensemble_download_frame() { return 0; } -static int Hook_soranokiseki_fc_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A2]; +static int Hook_soranokiseki_fc_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A2]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "soranokiseki_fc_download_frame"); @@ -960,9 +960,9 @@ static int Hook_soranokiseki_fc_download_frame() { return 0; } -static int Hook_soranokiseki_sc_download_frame() { +static int Hook_soranokiseki_sc_download_frame(MIPSState *mips) { u32 fb_infoaddr; - if (!GetMIPSStaticAddress(fb_infoaddr, 0x28, 0x2C)) { + if (!GetMIPSStaticAddress(mips, fb_infoaddr, 0x28, 0x2C)) { return 0; } if (!Memory::IsValid4AlignedAddress(fb_infoaddr)) { @@ -970,14 +970,14 @@ static int Hook_soranokiseki_sc_download_frame() { } const u32 fb_info = Memory::ReadUnchecked_U32(fb_infoaddr); - const MIPSOpcode fb_index_load = Memory::Read_Instruction(currentMIPS->pc + 0x34); + const MIPSOpcode fb_index_load = Memory::Read_Instruction(mips->pc + 0x34); if (fb_index_load != MIPS_MAKE_LW(MIPS_GET_RT(fb_index_load), MIPS_GET_RS(fb_index_load), fb_index_load & 0xffff)) { return 0; } const int fb_index_offset = (s16)(fb_index_load & 0xffff); const u32 fb_index = (Memory::ReadUnchecked_U32(fb_info + fb_index_offset) + 1) & 1; const u32 fb_address = 0x4000000 + (0x44000 * fb_index); - const u32 dest_address = currentMIPS->r[MIPS_REG_A1]; + const u32 dest_address = mips->r[MIPS_REG_A1]; if (Memory::IsRAMAddress(dest_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "soranokiseki_sc_download_frame"); @@ -985,8 +985,8 @@ static int Hook_soranokiseki_sc_download_frame() { return 0; } -static int Hook_bokunonatsuyasumi4_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A3]; +static int Hook_bokunonatsuyasumi4_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A3]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "bokunonatsuyasumi4_download_frame"); @@ -994,9 +994,9 @@ static int Hook_bokunonatsuyasumi4_download_frame() { return 0; } -static int Hook_danganronpa2_1_download_frame() { - const u32 fb_base = currentMIPS->r[MIPS_REG_V0]; - const u32 fb_offset = currentMIPS->r[MIPS_REG_V1]; +static int Hook_danganronpa2_1_download_frame(MIPSState *mips) { + const u32 fb_base = mips->r[MIPS_REG_V0]; + const u32 fb_offset = mips->r[MIPS_REG_V1]; const u32 fb_offset_fix = fb_offset & 0xFFFFFFFC; const u32 fb_address = fb_base + fb_offset_fix; if (Memory::IsVRAMAddress(fb_address)) { @@ -1006,9 +1006,9 @@ static int Hook_danganronpa2_1_download_frame() { return 0; } -static int Hook_danganronpa2_2_download_frame() { - const u32 fb_base = currentMIPS->r[MIPS_REG_V0]; - const u32 fb_offset = currentMIPS->r[MIPS_REG_V1]; +static int Hook_danganronpa2_2_download_frame(MIPSState *mips) { + const u32 fb_base = mips->r[MIPS_REG_V0]; + const u32 fb_offset = mips->r[MIPS_REG_V1]; const u32 fb_offset_fix = fb_offset & 0xFFFFFFFC; const u32 fb_address = fb_base + fb_offset_fix; if (Memory::IsVRAMAddress(fb_address)) { @@ -1018,9 +1018,9 @@ static int Hook_danganronpa2_2_download_frame() { return 0; } -static int Hook_danganronpa1_1_download_frame() { - const u32 fb_base = currentMIPS->r[MIPS_REG_A5]; - const u32 fb_offset = currentMIPS->r[MIPS_REG_V0]; +static int Hook_danganronpa1_1_download_frame(MIPSState *mips) { + const u32 fb_base = mips->r[MIPS_REG_A5]; + const u32 fb_offset = mips->r[MIPS_REG_V0]; const u32 fb_offset_fix = fb_offset & 0xFFFFFFFC; const u32 fb_address = fb_base + fb_offset_fix; if (Memory::IsVRAMAddress(fb_address)) { @@ -1030,11 +1030,11 @@ static int Hook_danganronpa1_1_download_frame() { return 0; } -static int Hook_danganronpa1_2_download_frame() { - const MIPSOpcode instruction = Memory::Read_Instruction(currentMIPS->pc + 0x8); +static int Hook_danganronpa1_2_download_frame(MIPSState *mips) { + const MIPSOpcode instruction = Memory::Read_Instruction(mips->pc + 0x8); const int reg_num = instruction >> 11 & 31; - const u32 fb_base = currentMIPS->r[reg_num]; - const u32 fb_offset = currentMIPS->r[MIPS_REG_V0]; + const u32 fb_base = mips->r[reg_num]; + const u32 fb_offset = mips->r[MIPS_REG_V0]; const u32 fb_offset_fix = fb_offset & 0xFFFFFFFC; const u32 fb_address = fb_base + fb_offset_fix; if (Memory::IsVRAMAddress(fb_address)) { @@ -1044,8 +1044,8 @@ static int Hook_danganronpa1_2_download_frame() { return 0; } -static int Hook_kankabanchoutbr_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A1]; +static int Hook_kankabanchoutbr_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A1]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "kankabanchoutbr_download_frame"); @@ -1053,8 +1053,8 @@ static int Hook_kankabanchoutbr_download_frame() { return 0; } -static int Hook_orenoimouto_download_frame_2() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A4]; +static int Hook_orenoimouto_download_frame_2(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A4]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "orenoimouto_download_frame_2"); @@ -1062,8 +1062,8 @@ static int Hook_orenoimouto_download_frame_2() { return 0; } -static int Hook_rewrite_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_rewrite_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "rewrite_download_frame"); @@ -1071,8 +1071,8 @@ static int Hook_rewrite_download_frame() { return 0; } -static int Hook_kudwafter_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_kudwafter_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kudwafter_download_frame"); @@ -1080,8 +1080,8 @@ static int Hook_kudwafter_download_frame() { return 0; } -static int Hook_kumonohatateni_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_kumonohatateni_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kumonohatateni_download_frame"); @@ -1089,8 +1089,8 @@ static int Hook_kumonohatateni_download_frame() { return 0; } -static int Hook_otomenoheihou_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_otomenoheihou_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "otomenoheihou_download_frame"); @@ -1098,8 +1098,8 @@ static int Hook_otomenoheihou_download_frame() { return 0; } -static int Hook_grisaianokajitsu_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_grisaianokajitsu_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "grisaianokajitsu_download_frame"); @@ -1107,8 +1107,8 @@ static int Hook_grisaianokajitsu_download_frame() { return 0; } -static int Hook_kokoroconnect_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A3]; +static int Hook_kokoroconnect_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A3]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kokoroconnect_download_frame"); @@ -1116,8 +1116,8 @@ static int Hook_kokoroconnect_download_frame() { return 0; } -static int Hook_toheart2_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A1]; +static int Hook_toheart2_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A1]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "toheart2_download_frame"); @@ -1125,8 +1125,8 @@ static int Hook_toheart2_download_frame() { return 0; } -static int Hook_toheart2_download_frame_2() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_toheart2_download_frame_2(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "toheart2_download_frame_2"); @@ -1134,8 +1134,8 @@ static int Hook_toheart2_download_frame_2() { return 0; } -static int Hook_flowers_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_flowers_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "flowers_download_frame"); @@ -1143,11 +1143,11 @@ static int Hook_flowers_download_frame() { return 0; } -static int Hook_motorstorm_download_frame() { - if (!Memory::IsValid4AlignedAddress(currentMIPS->r[MIPS_REG_A1] + 0x18)) { +static int Hook_motorstorm_download_frame(MIPSState *mips) { + if (!Memory::IsValid4AlignedAddress(mips->r[MIPS_REG_A1] + 0x18)) { return 0; } - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A1] + 0x18); + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_A1] + 0x18); if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "motorstorm_download_frame"); @@ -1155,8 +1155,8 @@ static int Hook_motorstorm_download_frame() { return 0; } -static int Hook_utawarerumono_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_utawarerumono_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "utawarerumono_download_frame"); @@ -1164,8 +1164,8 @@ static int Hook_utawarerumono_download_frame() { return 0; } -static int Hook_photokano_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A1]; +static int Hook_photokano_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A1]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "photokano_download_frame"); @@ -1173,8 +1173,8 @@ static int Hook_photokano_download_frame() { return 0; } -static int Hook_photokano_download_frame_2() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A1]; +static int Hook_photokano_download_frame_2(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A1]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "photokano_download_frame_2"); @@ -1182,8 +1182,8 @@ static int Hook_photokano_download_frame_2() { return 0; } -static int Hook_gakuenheaven_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_gakuenheaven_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "gakuenheaven_download_frame"); @@ -1191,8 +1191,8 @@ static int Hook_gakuenheaven_download_frame() { return 0; } -static int Hook_youkosohitsujimura_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_V0]; +static int Hook_youkosohitsujimura_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_V0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "youkosohitsujimura_download_frame"); @@ -1200,30 +1200,30 @@ static int Hook_youkosohitsujimura_download_frame() { return 0; } -static int Hook_zettai_hero_update_minimap_tex() { - const MIPSOpcode storeOffset = Memory::Read_Instruction(currentMIPS->pc + 4); - const uint32_t texAddr = currentMIPS->r[MIPS_REG_A0] + SignExtend16ToS32(storeOffset); +static int Hook_zettai_hero_update_minimap_tex(MIPSState *mips) { + const MIPSOpcode storeOffset = Memory::Read_Instruction(mips->pc + 4); + const uint32_t texAddr = mips->r[MIPS_REG_A0] + SignExtend16ToS32(storeOffset); const uint32_t texSize = 64 * 64 * 1; - const uint32_t writeAddr = currentMIPS->r[MIPS_REG_V1] + SignExtend16ToS32(storeOffset); + const uint32_t writeAddr = mips->r[MIPS_REG_V1] + SignExtend16ToS32(storeOffset); if (Memory::IsValidRange(texAddr, texSize) && writeAddr >= texAddr && writeAddr < texAddr + texSize) { const uint8_t currentValue = Memory::ReadUnchecked_U8(writeAddr); - if (currentValue != currentMIPS->r[MIPS_REG_A3]) { + if (currentValue != mips->r[MIPS_REG_A3]) { gpu->InvalidateCache(texAddr, texSize, GPU_INVALIDATE_FORCE); } } return 0; } -static int Hook_tonyhawkp8_upload_tutorial_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_tonyhawkp8_upload_tutorial_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformWriteColorFromMemory(fb_address, 0x00088000); } return 0; } -static int Hook_sdgundamggenerationportable_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A3]; +static int Hook_sdgundamggenerationportable_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A3]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "sdgundamggenerationportable_download_frame"); @@ -1231,9 +1231,9 @@ static int Hook_sdgundamggenerationportable_download_frame() { return 0; } -static int Hook_atvoffroadfurypro_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_S2]; - const u32 fb_size = (currentMIPS->r[MIPS_REG_S4] >> 3) * currentMIPS->r[MIPS_REG_S3]; +static int Hook_atvoffroadfurypro_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_S2]; + const u32 fb_size = (mips->r[MIPS_REG_S4] >> 3) * mips->r[MIPS_REG_S3]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, fb_size); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "atvoffroadfurypro_download_frame"); @@ -1241,9 +1241,9 @@ static int Hook_atvoffroadfurypro_download_frame() { return 0; } -static int Hook_atvoffroadfuryblazintrails_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_S5]; - const u32 fb_size = (currentMIPS->r[MIPS_REG_S3] >> 3) * currentMIPS->r[MIPS_REG_S2]; +static int Hook_atvoffroadfuryblazintrails_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_S5]; + const u32 fb_size = (mips->r[MIPS_REG_S3] >> 3) * mips->r[MIPS_REG_S2]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, fb_size); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "atvoffroadfuryblazintrails_download_frame"); @@ -1251,8 +1251,8 @@ static int Hook_atvoffroadfuryblazintrails_download_frame() { return 0; } -static int Hook_littlebustersce_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_A0]; +static int Hook_littlebustersce_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_A0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "littlebustersce_download_frame"); @@ -1260,8 +1260,8 @@ static int Hook_littlebustersce_download_frame() { return 0; } -static int Hook_shinigamitoshoujo_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_S2]; +static int Hook_shinigamitoshoujo_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_S2]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "shinigamitoshoujo_download_frame"); @@ -1269,9 +1269,9 @@ static int Hook_shinigamitoshoujo_download_frame() { return 0; } -static int Hook_atvoffroadfuryprodemo_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_S5]; - const u32 fb_size = ((currentMIPS->r[MIPS_REG_A0] + currentMIPS->r[MIPS_REG_A1]) >> 3) * currentMIPS->r[MIPS_REG_S2]; +static int Hook_atvoffroadfuryprodemo_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_S5]; + const u32 fb_size = ((mips->r[MIPS_REG_A0] + mips->r[MIPS_REG_A1]) >> 3) * mips->r[MIPS_REG_S2]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, fb_size); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "atvoffroadfuryprodemo_download_frame"); @@ -1279,8 +1279,8 @@ static int Hook_atvoffroadfuryprodemo_download_frame() { return 0; } -static int Hook_unendingbloodycall_download_frame() { - const u32 fb_address = currentMIPS->r[MIPS_REG_T3]; +static int Hook_unendingbloodycall_download_frame(MIPSState *mips) { + const u32 fb_address = mips->r[MIPS_REG_T3]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "unendingbloodycall_download_frame"); @@ -1288,8 +1288,8 @@ static int Hook_unendingbloodycall_download_frame() { return 0; } -static int Hook_omertachinmokunookitethelegacy_download_frame() { - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_SP] + 4); +static int Hook_omertachinmokunookitethelegacy_download_frame(MIPSState *mips) { + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_SP] + 4); if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformReadbackToMemory(fb_address, 0x00044000); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "omertachinmokunookitethelegacy_download_frame"); @@ -1299,7 +1299,7 @@ static int Hook_omertachinmokunookitethelegacy_download_frame() { // Function at 0886665C in US version (Persona 1) // Function at 08807DC4 in EU version (Persona 2) -static int Hook_persona_download_frame() { +static int Hook_persona_download_frame(MIPSState *mips) { // Depending on a global (curframe kind of thing), this either reads from // 0x04088000 or 0x04000000 (the two addresses are hardcoded). // We'd have to do some gnarly stuff to get this address, so let's just download both. @@ -1311,9 +1311,9 @@ static int Hook_persona_download_frame() { return 0; } -static int Hook_steinsgate_download_frame() { +static int Hook_steinsgate_download_frame(MIPSState *mips) { u32 fb_offset_addr; - if (!GetMIPSStaticAddress(fb_offset_addr, 0x1C, 0x20)) { + if (!GetMIPSStaticAddress(mips, fb_offset_addr, 0x1C, 0x20)) { return 0; } if (!Memory::IsValid4AlignedAddress(fb_offset_addr)) { @@ -1327,12 +1327,12 @@ static int Hook_steinsgate_download_frame() { return 0; } -static int Hook_infinity_download_frame() { +static int Hook_infinity_download_frame(MIPSState *mips) { // There are a few games that share this same function. // The hash matches, but due to relocations, the addresses it references differ. // Because of this, the address, even though hardcoded, has to be fetched from the function. u32 magic_value_addr; - if (!GetMIPSStaticAddress(magic_value_addr, 0x08, 0x1C)) { + if (!GetMIPSStaticAddress(mips, magic_value_addr, 0x08, 0x1C)) { return 0; } if (!Memory::IsValid4AlignedAddress(magic_value_addr)) { @@ -1346,7 +1346,7 @@ static int Hook_infinity_download_frame() { return 0; } -static int Hook_takuyo_download_frame() { +static int Hook_takuyo_download_frame(MIPSState *mips) { gpu->PerformReadbackToMemory(0x04088000, 0x00088000); // The offset is hardcoded. NotifyMemInfo(MemBlockFlags::WRITE, 0x04088000, 0x00088000, "takuyo_download_frame"); return 0; @@ -1354,15 +1354,15 @@ static int Hook_takuyo_download_frame() { // Offsets in comments are valid for the US version of "KINGDOM HEARTS Birth by Sleep". // Function at 0x0881EF68 -static int Hook_kingdomhearts_download_frame() { +static int Hook_kingdomhearts_download_frame(MIPSState *mips) { const u32 fb_base = 0x04000000; // Set in 0x0880C458, doesn't seem like it's ever overwriten. - const u32 get_fb_offset = MIPSCodeUtils::GetJumpTarget(currentMIPS->pc + 0x5C); // Jump to function at 0x08821EB0. Said function returns the framebuffer offset. + const u32 get_fb_offset = MIPSCodeUtils::GetJumpTarget(mips->pc + 0x5C); // Jump to function at 0x08821EB0. Said function returns the framebuffer offset. if (get_fb_offset == INVALIDTARGET) { return 0; } u32 fb_offset_index_addr; - if (!GetMIPSStaticAddress(fb_offset_index_addr, get_fb_offset - currentMIPS->pc, get_fb_offset + 0x04 - currentMIPS->pc)) { + if (!GetMIPSStaticAddress(mips, fb_offset_index_addr, get_fb_offset - mips->pc, get_fb_offset + 0x04 - mips->pc)) { return 0; } if (!Memory::IsValidRange(fb_offset_index_addr, 4)) { @@ -1389,7 +1389,7 @@ static int Hook_kingdomhearts_download_frame() { const u32 fb_offset = Memory::ReadUnchecked_U32(fb_offset_table + fb_offset_index*4); // 0x08821E98-0x08821EB0 u32 magic_ptr_addr; - if (!GetMIPSStaticAddress(magic_ptr_addr, 0x08, 0x10)) { + if (!GetMIPSStaticAddress(mips, magic_ptr_addr, 0x08, 0x10)) { return 0; } const u32 magic_ptr = Memory::ReadUnchecked_U32(magic_ptr_addr); // 0x0881EF70, 0x0881EF78 @@ -1413,9 +1413,9 @@ static int Hook_kingdomhearts_download_frame() { // mirror at 0x04288000. So both are read back here, whole rows at a time. // Each version is hooked after the GE sync at the start, where y and h are in registers and the // framebuffer pointer is loaded from a global soon after. -static void EverybodysCopyPortrait(u32 y, u32 h, s32 luiOffset, s32 lwOffset) { +static void EverybodysCopyPortrait(MIPSState *mips, u32 y, u32 h, s32 luiOffset, s32 lwOffset) { u32 fb_info; - if (!GetMIPSStaticAddress(fb_info, luiOffset, lwOffset) || !Memory::IsValid4AlignedAddress(fb_info)) { + if (!GetMIPSStaticAddress(mips, fb_info, luiOffset, lwOffset) || !Memory::IsValid4AlignedAddress(fb_info)) { return; } const u32 fb_address = Memory::ReadUnchecked_U32(fb_info); @@ -1432,24 +1432,24 @@ static void EverybodysCopyPortrait(u32 y, u32 h, s32 luiOffset, s32 lwOffset) { } // Golf 2 (caller 0x0887C060) and Tennis (caller 0x0889B13C). -static int Hook_everybodys_copy_portrait() { - EverybodysCopyPortrait(currentMIPS->r[MIPS_REG_S4], currentMIPS->r[MIPS_REG_S1], 0x0C, 0x10); +static int Hook_everybodys_copy_portrait(MIPSState *mips) { + EverybodysCopyPortrait(mips, mips->r[MIPS_REG_S4], mips->r[MIPS_REG_S1], 0x0C, 0x10); return 0; } // Golf (caller 0x088A1FEC). -static int Hook_everybodysgolf_copy_portrait() { - EverybodysCopyPortrait(currentMIPS->r[MIPS_REG_S0], currentMIPS->r[MIPS_REG_S4], 0x00, 0x08); +static int Hook_everybodysgolf_copy_portrait(MIPSState *mips) { + EverybodysCopyPortrait(mips, mips->r[MIPS_REG_S0], mips->r[MIPS_REG_S4], 0x00, 0x08); return 0; } -static int Hook_everybodysgolf_spinner_background() { +static int Hook_everybodysgolf_spinner_background(MIPSState *mips) { // The loading screen spinner copies the displayed framebuffer under it into the transparent texels // of each of its frames, then memcpys a frame back to the screen every so often. // Hooked after the call to sceDisplayGetFrameBuf, where v0 is the framebuffer and s0 the spinner, // with y at 0x14 and the frame height at 0x1C. - const u32 fb_address = currentMIPS->r[MIPS_REG_V0]; - const u32 obj = currentMIPS->r[MIPS_REG_S0]; + const u32 fb_address = mips->r[MIPS_REG_V0]; + const u32 obj = mips->r[MIPS_REG_S0]; if (!Memory::IsVRAMAddress(fb_address) || !Memory::IsValidRange(obj + 0x14, 0xC)) { return 0; } @@ -1467,12 +1467,12 @@ static int Hook_everybodysgolf_spinner_background() { return 0; } -static int Hook_codedarms_stencil_check() { +static int Hook_codedarms_stencil_check(MIPSState *mips) { // The crosshair turns red, and lock-on works, when stencil bit 3 is set at the centre of the frame // just rendered, which the game tests by reading the pixel from VRAM (#17936). Hooked at the load, // where v0 is the pixel's address. Read back the stencil of the row it's in (the game's stride is // 512). Only stencil: the alpha the hardware backends keep doesn't follow it everywhere. - const u32 addr = currentMIPS->r[MIPS_REG_V0]; + const u32 addr = mips->r[MIPS_REG_V0]; if (!Memory::IsVRAMAddress(addr)) { return 0; } @@ -1483,7 +1483,7 @@ static int Hook_codedarms_stencil_check() { return 0; } -static int Hook_resistance_draw_trail() { +static int Hook_resistance_draw_trail(MIPSState *mips) { // Smoke trails get a new node per update rather than per unit of time, while the nodes expire by // time, so the higher the frame rate, the more of them are alive. After the angel boss in Bonn the // trails behind the debris make the display list overflow its buffer at 60fps, into the music @@ -1493,7 +1493,7 @@ static int Hook_resistance_draw_trail() { // check them here. Hooked where the node count is about to become the loop count: when the // current buffer is nearly full, skip the trail by making the count zero. u32 listPtrAddr; - if (!GetMIPSStaticAddress(listPtrAddr, 0x6C, 0x3A4) || !Memory::IsValid4AlignedRange(listPtrAddr - 0x10, 0x14 + 8)) { + if (!GetMIPSStaticAddress(mips, listPtrAddr, 0x6C, 0x3A4) || !Memory::IsValid4AlignedRange(listPtrAddr - 0x10, 0x14 + 8)) { return 0; } const u32 ptr = Memory::ReadUnchecked_U32(listPtrAddr) & 0x0FFFFFFF; @@ -1504,7 +1504,7 @@ static int Hook_resistance_draw_trail() { // A trail is at most 17 nodes of six sprites (0x84 bytes each), so this leaves room for it // and for everything drawn after it. if (limit - ptr < 0x18000) { - currentMIPS->r[MIPS_REG_A1] = (u32)-1; + mips->r[MIPS_REG_A1] = (u32)-1; } break; } @@ -1512,7 +1512,7 @@ static int Hook_resistance_draw_trail() { return 0; } -static int Hook_medievil_projectile_update() { +static int Hook_medievil_projectile_update(MIPSState *mips) { // The dragon armour's fire breath only works at 30fps, on hardware too. Each flame is a projectile // whose init looks up the "Volume_Attached_Hurt" node in its model and keeps it at +0x3F8. The // projectile dies on its first update if the node wasn't found. The model's node list is filled @@ -1520,7 +1520,7 @@ static int Hook_medievil_projectile_update() { // next one spawns, which keeps the resource loaded, so later flames find the node. At 60fps // each flame dies first, the resource is freed and reloaded, and no flame ever finds it. // Hooked where the update checks for the node: by then the list is filled, so look again. - const u32 obj = currentMIPS->r[MIPS_REG_S2]; + const u32 obj = mips->r[MIPS_REG_S2]; if (!Memory::IsValid4AlignedRange(obj + 0xBC, 4) || !Memory::IsValid4AlignedRange(obj + 0x3F8, 4)) { return 0; } @@ -1551,13 +1551,13 @@ static int Hook_medievil_projectile_update() { return 0; } -static int Hook_resistance_update_trail() { +static int Hook_resistance_update_trail(MIPSState *mips) { // The trail adds a node on every update that its emitter's rate allows (one per update at most, // and the explosion debris always allow one), and the effect's clock advances 1/60 per update // at 60fps. Keep the nodes at least 1/30 of that clock apart, as if the game ran at 30fps, so // running faster doesn't pack the smoke denser and multiply the trails (#19755). Hooked where the // accumulator is about to be tested: holding it under the threshold postpones the node. - const u32 trail = currentMIPS->r[MIPS_REG_S0]; + const u32 trail = mips->r[MIPS_REG_S0]; if (!Memory::IsValid4AlignedRange(trail + 0x140, 0x3C)) { return 0; } @@ -1571,7 +1571,7 @@ static int Hook_resistance_update_trail() { if (!Memory::IsValid4AlignedAddress(lastNode + 0x50)) { return 0; } - const float now = currentMIPS->f[20]; + const float now = mips->f[20]; const float lastNodeTime = Memory::ReadUnchecked_Float(lastNode + 0x50); // Updates come 1/60 apart, so this lets every other one through. if (now - lastNodeTime < 1.0f / 30.0f - 0.001f) { @@ -1582,24 +1582,24 @@ static int Hook_resistance_update_trail() { return 0; } -static int Hook_resistance_muzzle_light() { +static int Hook_resistance_muzzle_light(MIPSState *mips) { // Each shot spawns a light that is removed once its effect's clock reaches 0.1s, and the new // one only lights up an update after it's spawned. At 30fps the 303 assault rifle fires every // third update (0.1s), so the wall goes dark for one frame per shot and flickers. At 60fps it // fires every fifth update (1/12s), the light outlives the gap and the wall stays lit (#20420). // 0.075s keeps the 30fps pattern and gives 60fps four lit updates out of five. Hooked where // f13 holds the lifetime, about to be added to the clock. - currentMIPS->f[13] = 0.075f; + mips->f[13] = 0.075f; return 0; } -static int Hook_katamari_render_check() { - if (!Memory::IsValidRange(currentMIPS->r[MIPS_REG_A0] + 0x3C, 8)) { +static int Hook_katamari_render_check(MIPSState *mips) { + if (!Memory::IsValidRange(mips->r[MIPS_REG_A0] + 0x3C, 8)) { return 0; } - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x3C); - const u32 fbInfoPtr = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x40); + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_A0] + 0x3C); + const u32 fbInfoPtr = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_A0] + 0x40); if (Memory::IsVRAMAddress(fb_address) && fbInfoPtr != 0 && Memory::IsValid4AlignedRange(fbInfoPtr, 0x10)) { const u32 sizeInfoPtr = Memory::ReadUnchecked_U32(fbInfoPtr + 0x0C); if (Memory::IsValidRange(sizeInfoPtr, 0x10)) { @@ -1619,17 +1619,17 @@ static int Hook_katamari_render_check() { return 0; } -static int Hook_katamari_screenshot_to_565() { +static int Hook_katamari_screenshot_to_565(MIPSState *mips) { u32 fb_address; - if (GetMIPSStaticAddress(fb_address, 0x0040, 0x0044)) { + if (GetMIPSStaticAddress(mips, fb_address, 0x0040, 0x0044)) { gpu->PerformReadbackToMemory(0x04000000 | fb_address, 0x00088000); NotifyMemInfo(MemBlockFlags::WRITE, 0x04000000 | fb_address, 0x00088000, "katamari_screenshot_to_565"); } return 0; } -static int Hook_mytranwars_upload_frame() { - u32 fb_address = currentMIPS->r[MIPS_REG_S0]; +static int Hook_mytranwars_upload_frame(MIPSState *mips) { + u32 fb_address = mips->r[MIPS_REG_S0]; if (Memory::IsVRAMAddress(fb_address)) { gpu->PerformWriteColorFromMemory(fb_address, 0x00088000); } @@ -1640,10 +1640,10 @@ static u32 marvelalliance1_copy_src = 0; static u32 marvelalliance1_copy_dst = 0; static u32 marvelalliance1_copy_size = 0; -static int Hook_marvelalliance1_copy_a1_before() { - marvelalliance1_copy_src = currentMIPS->r[MIPS_REG_A1]; - marvelalliance1_copy_dst = currentMIPS->r[MIPS_REG_V1]; - marvelalliance1_copy_size = currentMIPS->r[MIPS_REG_V0] - currentMIPS->r[MIPS_REG_A1]; +static int Hook_marvelalliance1_copy_a1_before(MIPSState *mips) { + marvelalliance1_copy_src = mips->r[MIPS_REG_A1]; + marvelalliance1_copy_dst = mips->r[MIPS_REG_V1]; + marvelalliance1_copy_size = mips->r[MIPS_REG_V0] - mips->r[MIPS_REG_A1]; if (Memory::IsValidRange(marvelalliance1_copy_src, marvelalliance1_copy_size)) { gpu->PerformReadbackToMemory(marvelalliance1_copy_src, marvelalliance1_copy_size); @@ -1653,10 +1653,10 @@ static int Hook_marvelalliance1_copy_a1_before() { return 0; } -static int Hook_marvelalliance1_copy_a2_before() { - marvelalliance1_copy_src = currentMIPS->r[MIPS_REG_A2]; - marvelalliance1_copy_dst = currentMIPS->r[MIPS_REG_V0]; - marvelalliance1_copy_size = currentMIPS->r[MIPS_REG_A1] - currentMIPS->r[MIPS_REG_A2]; +static int Hook_marvelalliance1_copy_a2_before(MIPSState *mips) { + marvelalliance1_copy_src = mips->r[MIPS_REG_A2]; + marvelalliance1_copy_dst = mips->r[MIPS_REG_V0]; + marvelalliance1_copy_size = mips->r[MIPS_REG_A1] - mips->r[MIPS_REG_A2]; if (Memory::IsValidRange(marvelalliance1_copy_src, marvelalliance1_copy_size)) { gpu->PerformReadbackToMemory(marvelalliance1_copy_src, marvelalliance1_copy_size); @@ -1666,7 +1666,7 @@ static int Hook_marvelalliance1_copy_a2_before() { return 0; } -static int Hook_marvelalliance1_copy_after() { +static int Hook_marvelalliance1_copy_after(MIPSState *mips) { if (Memory::IsValidRange(marvelalliance1_copy_dst, marvelalliance1_copy_size)) { gpu->PerformWriteColorFromMemory(marvelalliance1_copy_dst, marvelalliance1_copy_size); NotifyMemInfo(MemBlockFlags::READ, marvelalliance1_copy_dst, marvelalliance1_copy_size, "marvelalliance1_copy_after"); @@ -1675,19 +1675,19 @@ static int Hook_marvelalliance1_copy_after() { return 0; } -static int Hook_starocean_clear_framebuf_before() { +static int Hook_starocean_clear_framebuf_before(MIPSState *mips) { skipGPUReplacements |= (int)GPUReplacementSkip::MEMSET; return 0; } -static int Hook_starocean_clear_framebuf_after() { +static int Hook_starocean_clear_framebuf_after(MIPSState *mips) { skipGPUReplacements &= ~(int)GPUReplacementSkip::MEMSET; // This hook runs after the copy, this is the final memcpy destination. - u32 framebuf = currentMIPS->r[MIPS_REG_V0] - 512 * 4 * 271; + u32 framebuf = mips->r[MIPS_REG_V0] - 512 * 4 * 271; u32 y_address, h_address; - if (GetMIPSGPAddress(y_address, -204) && GetMIPSGPAddress(h_address, -200)) { + if (GetMIPSGPAddress(mips, y_address, -204) && GetMIPSGPAddress(mips, h_address, -200)) { if (Memory::IsValid2AlignedAddress(y_address) && Memory::IsValid2AlignedAddress(h_address)) { int y = (s16)Memory::ReadUnchecked_U16(y_address); int h = (s16)Memory::ReadUnchecked_U16(h_address); @@ -1699,22 +1699,22 @@ static int Hook_starocean_clear_framebuf_after() { return 0; } -static int Hook_motorstorm_pixel_read() { - if (!Memory::IsValidRange(currentMIPS->r[MIPS_REG_A0] + 0x18, 0x20)) { +static int Hook_motorstorm_pixel_read(MIPSState *mips) { + if (!Memory::IsValidRange(mips->r[MIPS_REG_A0] + 0x18, 0x20)) { return 0; } - const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x18); - const u32 fb_height = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x26); - const u32 fb_stride = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x28); + const u32 fb_address = Memory::ReadUnchecked_U32(mips->r[MIPS_REG_A0] + 0x18); + const u32 fb_height = Memory::ReadUnchecked_U16(mips->r[MIPS_REG_A0] + 0x26); + const u32 fb_stride = Memory::ReadUnchecked_U16(mips->r[MIPS_REG_A0] + 0x28); gpu->PerformReadbackToMemory(fb_address, fb_height * fb_stride); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_height * fb_stride, "motorstorm_pixel_read"); return 0; } -static int Hook_worms_copy_normalize_alpha() { +static int Hook_worms_copy_normalize_alpha(MIPSState *mips) { // At this point in the function (0x0CC), s1 is the framebuf and a2 is the size. - const u32 fb_address = currentMIPS->r[MIPS_REG_S1]; - const u32 fb_size = currentMIPS->r[MIPS_REG_A2]; + const u32 fb_address = mips->r[MIPS_REG_S1]; + const u32 fb_size = mips->r[MIPS_REG_A2]; if (Memory::IsVRAMAddress(fb_address) && Memory::IsValidRange(fb_address, fb_size)) { gpu->PerformReadbackToMemory(fb_address, fb_size); NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "worms_copy_normalize_alpha"); @@ -1722,12 +1722,12 @@ static int Hook_worms_copy_normalize_alpha() { return 0; } -static int Hook_openseason_data_decode() { +static int Hook_openseason_data_decode(MIPSState *mips) { static u32 firstWritePtr = 0; - u32 curWritePtr = currentMIPS->r[MIPS_REG_A0]; - u32 endPtr = currentMIPS->r[MIPS_REG_A1]; - u32 writeBytes = currentMIPS->r[MIPS_REG_V0]; + u32 curWritePtr = mips->r[MIPS_REG_A0]; + u32 endPtr = mips->r[MIPS_REG_A1]; + u32 writeBytes = mips->r[MIPS_REG_V0]; u32 startPtr = curWritePtr - writeBytes; if (Memory::IsVRAMAddress(startPtr) && (firstWritePtr == 0 || startPtr < firstWritePtr)) { firstWritePtr = startPtr; @@ -1739,8 +1739,8 @@ static int Hook_openseason_data_decode() { return 0; } -static int Hook_soltrigger_render_ucschar() { - u32 targetInfoPtrPtr = currentMIPS->r[MIPS_REG_A2]; +static int Hook_soltrigger_render_ucschar(MIPSState *mips) { + u32 targetInfoPtrPtr = mips->r[MIPS_REG_A2]; u32 targetInfoPtr = Memory::IsValidRange(targetInfoPtrPtr, 4) ? Memory::ReadUnchecked_U32(targetInfoPtrPtr) : 0; if (Memory::IsValidRange(targetInfoPtr, 32)) { u32 targetPtr = Memory::ReadUnchecked_U32(targetInfoPtr + 8); @@ -1752,7 +1752,7 @@ static int Hook_soltrigger_render_ucschar() { return 0; } -static int Hook_gow_fps_hack() { +static int Hook_gow_fps_hack(MIPSState *mips) { if (PSP_CoreParameter().compat.flags().GoWFramerateHack60 || PSP_CoreParameter().compat.flags().FramerateHack30) { if (PSP_CoreParameter().compat.flags().FramerateHack30) { __DisplayWaitForVblanks("vblank start waited", 2); @@ -1763,35 +1763,35 @@ static int Hook_gow_fps_hack() { return 0; } -static int Hook_blitz_fps_hack() { +static int Hook_blitz_fps_hack(MIPSState *mips) { if (PSP_CoreParameter().compat.flags().FramerateHack30) { __DisplayWaitForVblanks("vblank start waited", 1); } return 0; } -static int Hook_brian_lara_fps_hack() { +static int Hook_brian_lara_fps_hack(MIPSState *mips) { if (PSP_CoreParameter().compat.flags().FramerateHack30) { __DisplayWaitForVblanks("vblank start waited", 1); } return 0; } -static int Hook_gow_vortex_hack() { +static int Hook_gow_vortex_hack(MIPSState *mips) { if (PSP_CoreParameter().compat.flags().GoWFramerateHack60) { // from my tests both ==0x3F800000 and !=0x3F800000 takes around 1:40-1:50, that seems to match correct behaviour - if (currentMIPS->r[MIPS_REG_S1] == 0 && currentMIPS->r[MIPS_REG_A0] == 0xC0 && currentMIPS->r[MIPS_REG_T4] != 0x3F800000) { - currentMIPS->r[MIPS_REG_S1] = 1; - currentMIPS->downcount = 0; + if (mips->r[MIPS_REG_S1] == 0 && mips->r[MIPS_REG_A0] == 0xC0 && mips->r[MIPS_REG_T4] != 0x3F800000) { + mips->r[MIPS_REG_S1] = 1; + mips->downcount = 0; } } return 0; } -static int Hook_ZZT3_select_hack() { +static int Hook_ZZT3_select_hack(MIPSState *mips) { if (PSP_CoreParameter().compat.flags().ZZT3SelectHack) { - if (currentMIPS->r[MIPS_REG_V0] == 0) { - currentMIPS->r[MIPS_REG_V0] = 1; + if (mips->r[MIPS_REG_V0] == 0) { + mips->r[MIPS_REG_V0] = 1; } } return 0; @@ -1804,9 +1804,9 @@ static int Hook_ZZT3_select_hack() { // ends by setting mNextDrawTick to now. If not, nothing is presented for those seconds while every frame // still draws into the same display list, which overruns its 128KB into the game's globals and crashes. // So, we do what the present would have, once loading has completed. -static int Hook_bejeweled2_draw_dirty_stuff() { - const u32 func = currentMIPS->pc; - const u32 app = currentMIPS->r[MIPS_REG_A0]; +static int Hook_bejeweled2_draw_dirty_stuff(MIPSState *mips) { + const u32 func = mips->pc; + const u32 app = mips->r[MIPS_REG_A0]; // The hash masks immediates, so check the fields are where we expect. if (Memory::Read_Instruction(func + 0x48).encoding != 0x90840411 || // lbu a0, 0x411(a0) - mLoadingThreadStarted Memory::Read_Instruction(func + 0x58).encoding != 0x90840412 || // lbu a0, 0x412(a0) - mLoadingThreadCompleted @@ -1832,25 +1832,25 @@ static int Hook_bejeweled2_draw_dirty_stuff() { // the ground. It happens on a PSP too, in light enough scenes. The plane control code clears the pedal // in a branch delay slot, which a hook can't follow, so we hook both instructions the branch leads to, // and set the pedal from the throttle at 0x78C. The fix is Parik27's, from the issue. -static int GTAVCSPlaneGasPedal(u32 hookOffset) { - const u32 func = currentMIPS->pc - hookOffset; +static int GTAVCSPlaneGasPedal(MIPSState *mips, u32 hookOffset) { + const u32 func = mips->pc - hookOffset; // The hash masks immediates, so check it's the store we expect. if (Memory::Read_Instruction(func + 0x61C).encoding != 0xE61C025C) { // swc1 f28, 0x25C(s0) return 0; } - const u32 vehicle = currentMIPS->r[MIPS_REG_S0]; + const u32 vehicle = mips->r[MIPS_REG_S0]; if (Memory::IsValid4AlignedRange(vehicle + 0x25C, 4) && Memory::IsValid4AlignedRange(vehicle + 0x78C, 4)) { Memory::WriteUnchecked_U32(Memory::ReadUnchecked_U32(vehicle + 0x78C), vehicle + 0x25C); } return 0; } -static int Hook_gtavcs_plane_control_1() { - return GTAVCSPlaneGasPedal(0x620); +static int Hook_gtavcs_plane_control_1(MIPSState *mips) { + return GTAVCSPlaneGasPedal(mips, 0x620); } -static int Hook_gtavcs_plane_control_2() { - return GTAVCSPlaneGasPedal(0x6AC); +static int Hook_gtavcs_plane_control_2(MIPSState *mips) { + return GTAVCSPlaneGasPedal(mips, 0x6AC); } #define JITFUNC(f) (&MIPSComp::MIPSFrontendInterface::f) diff --git a/Core/HLE/ReplaceTables.h b/Core/HLE/ReplaceTables.h index 2971c9684c..c305cc2b54 100644 --- a/Core/HLE/ReplaceTables.h +++ b/Core/HLE/ReplaceTables.h @@ -46,7 +46,7 @@ #include "Core/MemMap.h" #include "Core/MIPS/JitCommon/JitCommon.h" -typedef int (* ReplaceFunc)(); +typedef int (* ReplaceFunc)(MIPSState *mips); enum { // Used to keep things around but disable them. diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 66abbb1c96..96b5948401 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -943,7 +943,7 @@ void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelFormat, int sync) } // Some games (GTA) never call this during gameplay, so bad place to put a framerate counter. -int sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) { +int sceDisplaySetFramebuf(MIPSState *mips, u32 topaddr, int linesize, int pixelformat, int sync) { if (sync != PSP_DISPLAY_SETBUF_IMMEDIATE && sync != PSP_DISPLAY_SETBUF_NEXTFRAME) { return hleLogError(Log::sceDisplay, SCE_KERNEL_ERROR_INVALID_MODE, "invalid sync mode"); } @@ -984,7 +984,7 @@ int sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) // Otherwise it'll always be ahead if the game messes up even once. const s64 LEEWAY_CYCLES_PER_FLIP = usToCycles(10); - u64 now = CoreTiming::GetTicks(currentMIPS); + u64 now = CoreTiming::GetTicks(mips); s64 cyclesAhead = nextFlipCycles - now; if (cyclesAhead > FLIP_DELAY_CYCLES_MIN) { if (lastFlipsTooFrequent >= FLIP_DELAY_MIN_FLIPS) { @@ -1156,8 +1156,8 @@ static u32 sceDisplayGetMode(u32 modeAddr, u32 widthAddr, u32 heightAddr) { return hleLogDebug(Log::sceDisplay, 0); } -static u32 sceDisplayIsVsync() { - u64 now = CoreTiming::GetTicks(currentMIPS); +static u32 sceDisplayIsVsync(MIPSState *mips) { + u64 now = CoreTiming::GetTicks(mips); u64 start = DisplayFrameStartTicks() + msToCycles(vsyncStartMs); u64 end = DisplayFrameStartTicks() + msToCycles(vsyncEndMs); diff --git a/Core/HLE/sceDmac.cpp b/Core/HLE/sceDmac.cpp index 4a5f591856..a9353fb680 100644 --- a/Core/HLE/sceDmac.cpp +++ b/Core/HLE/sceDmac.cpp @@ -73,7 +73,7 @@ static int __DmacMemcpy(MIPSState *mips, u32 dst, u32 src, u32 size) { } } -static u32 sceDmacMemcpy(u32 dst, u32 src, u32 size) { +static u32 sceDmacMemcpy(MIPSState *mips, u32 dst, u32 src, u32 size) { if (size == 0) { // Some games seem to do this frequently. return hleLogDebug(Log::HLE, SCE_KERNEL_ERROR_INVALID_SIZE, "invalid size"); @@ -85,18 +85,18 @@ static u32 sceDmacMemcpy(u32 dst, u32 src, u32 size) { return hleLogError(Log::HLE, SCE_KERNEL_ERROR_PRIV_REQUIRED, "illegal size"); } - if (dmacMemcpyDeadline > CoreTiming::GetTicks(currentMIPS)) { + if (dmacMemcpyDeadline > CoreTiming::GetTicks(mips)) { WARN_LOG(Log::HLE, "sceDmacMemcpy(dest=%08x, src=%08x, size=%d): overlapping read", dst, src, size); // TODO: Should block, seems like copy doesn't start until previous finishes. // Might matter for overlapping copies. } - int delay = __DmacMemcpy(currentMIPS, dst, src, size); + int delay = __DmacMemcpy(mips, dst, src, size); int result = hleLogDebug(Log::HLE, 0); return delay ? hleDelayResult(result, "dmac-memcpy", delay) : delay; } -static u32 sceDmacTryMemcpy(u32 dst, u32 src, u32 size) { +static u32 sceDmacTryMemcpy(MIPSState *mips, u32 dst, u32 src, u32 size) { if (size == 0) { return hleLogError(Log::HLE, SCE_KERNEL_ERROR_INVALID_SIZE, "invalid size"); } @@ -107,11 +107,11 @@ static u32 sceDmacTryMemcpy(u32 dst, u32 src, u32 size) { return hleLogError(Log::HLE, SCE_KERNEL_ERROR_PRIV_REQUIRED, "illegal size"); } - if (dmacMemcpyDeadline > CoreTiming::GetTicks(currentMIPS)) { + if (dmacMemcpyDeadline > CoreTiming::GetTicks(mips)) { return hleLogDebug(Log::HLE, SCE_KERNEL_ERROR_BUSY, "busy"); } - int delay = __DmacMemcpy(currentMIPS, dst, src, size); + int delay = __DmacMemcpy(mips, dst, src, size); int result = hleLogDebug(Log::HLE, 0); return delay ? hleDelayResult(result, "dmac-memcpy", delay) : delay; } diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 7793dea642..38903f17a7 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -392,7 +392,7 @@ static int __GeSubIntrBase(int callbackId) { return callbackId * 2; } -u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) { +u32 sceGeListEnQueue(MIPSState *mips, u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) { auto optParam = PSPPointer::Create(optParamAddr); bool runList; @@ -410,14 +410,14 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optP hleCoreTimingForceCheck(); DEBUG_LOG(Log::sceGe, "%08x=sceGeListEnQueue(addr=%08x, stall=%08x, cbid=%08x, param=%08x) ticks=%lld", listID, - listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks(currentMIPS)); + listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks(mips)); return hleNoLog(listID); // We already logged above, logs get confusing if we use hleLogSuccess. } -u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) { +u32 sceGeListEnQueueHead(MIPSState *mips, u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr) { DEBUG_LOG(Log::sceGe, "sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x) ticks=%lld", - listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks(currentMIPS)); + listAddress, stallAddress, callbackId, optParamAddr, (long long)CoreTiming::GetTicks(mips)); auto optParam = PSPPointer::Create(optParamAddr); bool runList; diff --git a/Core/HLE/sceGe.h b/Core/HLE/sceGe.h index a6372abc12..324803a93f 100644 --- a/Core/HLE/sceGe.h +++ b/Core/HLE/sceGe.h @@ -20,6 +20,8 @@ #include "GPU/GPUDefinitions.h" #include "Core/MemMap.h" +class MIPSState; + #define SCE_GE_LIST_COMPLETED 0 #define SCE_GE_LIST_QUEUED 1 #define SCE_GE_LIST_DRAWING 2 @@ -59,5 +61,5 @@ void __GeWaitCurrentThread(GPUSyncType type, SceUID waitId, const char *reason); bool __GeTriggerWait(GPUSyncType type, SceUID waitId); // Export functions for use by Util/PPGe -u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr); -u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr); +u32 sceGeListEnQueue(MIPSState *mips, u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr); +u32 sceGeListEnQueueHead(MIPSState *mips, u32 listAddress, u32 stallAddress, int callbackId, u32 optParamAddr); diff --git a/Core/HLE/sceHttp.cpp b/Core/HLE/sceHttp.cpp index cf6dda49db..a0461c8792 100644 --- a/Core/HLE/sceHttp.cpp +++ b/Core/HLE/sceHttp.cpp @@ -321,8 +321,8 @@ int sceHttpSetResolveRetry(int id, int retryCount) { return hleLogDebug(Log::sceNet, 0); } -static int sceHttpInit(int poolSize) { - WARN_LOG(Log::sceNet, "UNTESTED sceHttpInit(%i) at %08x", poolSize, currentMIPS->pc); +static int sceHttpInit(MIPSState *mips, int poolSize) { + WARN_LOG(Log::sceNet, "UNTESTED sceHttpInit(%i) at %08x", poolSize, mips->pc); if (httpInited) return hleLogError(Log::sceNet, SCE_HTTP_ERROR_ALREADY_INITED, "http already inited"); @@ -675,8 +675,8 @@ static int sceHttpLoadSystemCookie() { } // PSP Browser seems to set userAgent to 0 and later set the User-Agent header using sceHttpAddExtraHeader -static int sceHttpCreateTemplate(const char *userAgent, int httpVer, int autoProxyConf) { - WARN_LOG(Log::sceNet, "UNTESTED sceHttpCreateTemplate(%s, %d, %d) at %08x", safe_string(userAgent), httpVer, autoProxyConf, currentMIPS->pc); +static int sceHttpCreateTemplate(MIPSState *mips, const char *userAgent, int httpVer, int autoProxyConf) { + WARN_LOG(Log::sceNet, "UNTESTED sceHttpCreateTemplate(%s, %d, %d) at %08x", safe_string(userAgent), httpVer, autoProxyConf, mips->pc); // Reporting to find more games to be tested WARN_LOG_REPORT_ONCE(sceHttpCreateTemplate, Log::sceNet, "UNTESTED sceHttpCreateTemplate(%s, %d, %d)", safe_string(userAgent), httpVer, autoProxyConf); std::lock_guard guard(httpLock); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 4ce8b4fa44..b7d8719efa 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2308,7 +2308,7 @@ static u32 sceIoSetAsyncCallback(int id, u32 clbckId, u32 clbckArg) { } } -static u32 sceIoOpenAsync(const char *filename, int flags, int mode) { +static u32 sceIoOpenAsync(MIPSState *mips, const char *filename, int flags, int mode) { hleEatCycles(18000); if (!filename) { // Not tested on the PSP. @@ -2648,12 +2648,12 @@ static void strcpy_limit(char *dest, const char *src, int limit) { dest[i] = 0; } -static u32 sceIoDread(int id, u32 dirent_addr) { +static u32 sceIoDread(MIPSState *mips, int id, u32 dirent_addr) { u32 error; DirListing *dir = kernelObjects.Get(id, error); if (dir) { if (!Memory::IsValidRange(dirent_addr, sizeof(SceIoDirEnt))) { - Core_MemoryException(dirent_addr, sizeof(SceIoDirEnt), currentMIPS->pc, MemoryExceptionType::WRITE_BLOCK, "sceIoDread"); + Core_MemoryException(dirent_addr, sizeof(SceIoDirEnt), mips->pc, MemoryExceptionType::WRITE_BLOCK, "sceIoDread"); return hleLogError(Log::sceIo, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid address"); } SceIoDirEnt *entry = (SceIoDirEnt*) Memory::GetPointerOrException(dirent_addr); @@ -3039,14 +3039,14 @@ static u32 sceKernelRegisterStdoutPipe(u32 msgPipeUID) { return 0; } -static int IoAsyncFinish(int id) { +static int IoAsyncFinish(MIPSState *mips, int id) { u32 error; FileNode *f = __IoGetFd(id, error); if (f) { // Reset this so the Io funcs don't reject the request. f->pendingAsyncResult = false; // Reset the PC back so we will run again on resume. - currentMIPS->pc = asyncThreads[id]->Entry(); + mips->pc = asyncThreads[id]->Entry(); auto ¶ms = asyncParams[id]; diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index aaf5214cf2..2b7eda22f7 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -424,9 +424,9 @@ int sceKernelDcacheInvalidateRange(u32 addr, int size) return hleNoLog(0); } -int sceKernelIcacheInvalidateRange(u32 addr, int size) { +int sceKernelIcacheInvalidateRange(MIPSState *mips, u32 addr, int size) { if (size != 0) { - currentMIPS->InvalidateICacheRangeDeferred(addr, size); + mips->InvalidateICacheRangeDeferred(addr, size); Core_ReenterDispatcher(); } return hleLogDebug(Log::CPU, 0); @@ -485,22 +485,22 @@ int sceKernelDcacheWritebackInvalidateAll() { return hleLogDebug(Log::CPU, 0, "Dcache invalidated"); } -u32 sceKernelIcacheInvalidateAll() { +u32 sceKernelIcacheInvalidateAll(MIPSState *mips) { #ifdef LOG_CACHE NOTICE_LOG(Log::CPU, "Icache invalidated - should clear JIT someday"); #endif // Note that this doesn't actually fully invalidate all with such a large range. - currentMIPS->InvalidateICacheRangeDeferred(0, 0x3FFFFFFF); + mips->InvalidateICacheRangeDeferred(0, 0x3FFFFFFF); Core_ReenterDispatcher(); return hleLogDebug(Log::CPU, 0, "Icache invalidated"); } -u32 sceKernelIcacheClearAll() { +u32 sceKernelIcacheClearAll(MIPSState *mips) { #ifdef LOG_CACHE NOTICE_LOG(Log::CPU, "Icache cleared - should clear JIT someday"); #endif // Note that this doesn't actually fully invalidate all with such a large range. - currentMIPS->InvalidateICacheRangeDeferred(0, 0x3FFFFFFF); + mips->InvalidateICacheRangeDeferred(0, 0x3FFFFFFF); Core_ReenterDispatcher(); return hleLogDebug(Log::CPU, 0, "Icache cleared"); } @@ -1043,14 +1043,14 @@ static int sceKernelExitVSH(u32 paramPtr) { // The VSH's own version of sceKernelLoadExec, used for pushing a game to run over USB/WLAN // (e.g. from a PC) rather than loading it from a file already on the memory stick/UMD. -static int sceKernelLoadExecBufferVSHUsbWlan(int bufferSize, u32 bufferAddr, u32 paramPtr) { +static int sceKernelLoadExecBufferVSHUsbWlan(MIPSState *mips, int bufferSize, u32 bufferAddr, u32 paramPtr) { if (!Memory::IsValidRange(bufferAddr, bufferSize)) { return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid buffer"); } const u8 *data = Memory::GetPointerUnchecked(bufferAddr); std::string error_string; - if (!__KernelLoadExecFromBuffer(currentMIPS, data, (size_t)bufferSize, paramPtr, &error_string)) { + if (!__KernelLoadExecFromBuffer(mips, data, (size_t)bufferSize, paramPtr, &error_string)) { Core_HLEError("sceKernelLoadExecBufferVSHUsbWlan failed: " + error_string); return hleLogError(Log::sceKernel, -1, "failed: %s", error_string.c_str()); } diff --git a/Core/HLE/sceKernel.h b/Core/HLE/sceKernel.h index 8db0c4ee4b..d14e63ffc6 100644 --- a/Core/HLE/sceKernel.h +++ b/Core/HLE/sceKernel.h @@ -25,6 +25,7 @@ #include "Common/Swap.h" class PointerWrap; +class MIPSState; // If you add to this, make sure to check KernelObjectPool::CreateByIDType(). enum TMIDType : int { @@ -115,7 +116,7 @@ std::string __KernelStateSummary(); // These HLE functions are declared here to be included in tables that are in other files. -int sceKernelLoadExec(const char *filename, u32 paramPtr); +int sceKernelLoadExec(MIPSState *mips, const char *filename, u32 paramPtr); void sceKernelExitGame(); void sceKernelExitGameWithStatus(); @@ -135,9 +136,9 @@ int sceKernelDcacheWritebackRange(u32 addr, int size); int sceKernelDcacheWritebackInvalidateRange(u32 addr, int size); int sceKernelDcacheWritebackInvalidateAll(); int sceKernelGetThreadStackFreeSize(SceUID threadID); -u32 sceKernelIcacheInvalidateAll(); -u32 sceKernelIcacheClearAll(); -int sceKernelIcacheInvalidateRange(u32 addr, int size); +u32 sceKernelIcacheInvalidateAll(MIPSState *mips); +u32 sceKernelIcacheClearAll(MIPSState *mips); +int sceKernelIcacheInvalidateRange(MIPSState *mips, u32 addr, int size); #define KERNELOBJECT_MAX_NAME_LENGTH 31 diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index f901223fb3..5bf75b07cd 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -451,9 +451,9 @@ int __CancelRaisedInterrupts(PSPInterrupt intno) { return count; } -void __KernelReturnFromInterrupt() +void __KernelReturnFromInterrupt(MIPSState *mips) { - VERBOSE_LOG(Log::sceIntc, "Left interrupt handler at %08x", currentMIPS->pc); + VERBOSE_LOG(Log::sceIntc, "Left interrupt handler at %08x", mips->pc); hleSkipDeadbeef(); @@ -469,7 +469,7 @@ void __KernelReturnFromInterrupt() moreOfThis = moreOfThis || other.intr == pend.intr; } if (!moreOfThis) { - currentMIPS->downcount -= intrHandlers[pend.intr]->exitCycles(); + mips->downcount -= intrHandlers[pend.intr]->exitCycles(); } } else { _assert_msg_(false, "Bad pend.intr: %d", pend.intr); @@ -854,9 +854,9 @@ static int sysclib_memcmp(u32 dst, u32 src, u32 size) { } } -static int sysclib_sprintf_impl(u32 dst, int limit, u32 fmt, int firstVarArg) { +static int sysclib_sprintf_impl(MIPSState *mips, u32 dst, int limit, u32 fmt, int firstVarArg) { std::string result; - if (!HLEFormatPrintf(fmt, firstVarArg, &result)) { + if (!HLEFormatPrintf(mips, fmt, firstVarArg, &result)) { return 0; } @@ -879,15 +879,15 @@ static int sysclib_sprintf_impl(u32 dst, int limit, u32 fmt, int firstVarArg) { return (int)retval; } -static int sysclib_sprintf(u32 dst, u32 fmt) { +static int sysclib_sprintf(MIPSState *mips, u32 dst, u32 fmt) { DEBUG_LOG(Log::sceKernel, "Not fully implemented: sysclib_sprintf(dst=%08x, fmt=%08x)", dst, fmt); // dst is a0 and fmt a1, so the varargs start at a2. - return hleLogDebug(Log::sceKernel, sysclib_sprintf_impl(dst, 0, fmt, 2)); + return hleLogDebug(Log::sceKernel, sysclib_sprintf_impl(mips, dst, 0, fmt, 2)); } -static int sysclib_snprintf(u32 dst, int size, u32 fmt) { +static int sysclib_snprintf(MIPSState *mips, u32 dst, int size, u32 fmt) { DEBUG_LOG(Log::sceKernel, "Not fully implemented: sysclib_snprintf(dst=%08x, fmt=%08x)", dst, fmt); - return hleLogDebug(Log::sceKernel, sysclib_sprintf_impl(dst, size, fmt, 3)); + return hleLogDebug(Log::sceKernel, sysclib_sprintf_impl(mips, dst, size, fmt, 3)); } static u32 sysclib_memset(u32 destAddr, int data, int size) { diff --git a/Core/HLE/sceKernelInterrupt.h b/Core/HLE/sceKernelInterrupt.h index 3a5dcd0df0..02c2c407be 100644 --- a/Core/HLE/sceKernelInterrupt.h +++ b/Core/HLE/sceKernelInterrupt.h @@ -20,6 +20,7 @@ #include class PointerWrap; +class MIPSState; enum PSPInterrupt { PSP_GPIO_INTR = 4, @@ -164,7 +165,7 @@ int __TriggerInterrupt(int type, PSPInterrupt intno, int subInterrupts = -1); // Forgets interrupts that have been raised but not taken, except for one that's being handled. Returns how many. int __CancelRaisedInterrupts(PSPInterrupt intno); bool __RunOnePendingInterrupt(); -void __KernelReturnFromInterrupt(); +void __KernelReturnFromInterrupt(MIPSState *mips); void __RegisterIntrHandler(u32 intrNumber, IntrHandler* handler); void __SetIntrHandlerCosts(PSPInterrupt intno, int entryCycles, int exitCycles); diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 3ae2e0c000..53d19a3433 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -921,7 +921,7 @@ u32 sceKernelGetBlockHeadAddr(SceUID id) { } } -static int sceKernelPrintf(const char *formatString) { +static int sceKernelPrintf(MIPSState *mips, const char *formatString) { if (!formatString) return -1; diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 2bdda32fe1..5506d0a0df 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2540,16 +2540,16 @@ bool __KernelLoadGEDump(MIPSState *mips, std::string_view base_filename, std::st return true; } -int __KernelGPUReplay() { +int __KernelGPUReplay(MIPSState *mips) { // Special ABI: s0 and s1 are the "args". Not null terminated. - const char *filenamep = Memory::GetCharPointer(currentMIPS->r[MIPS_REG_S1]); + const char *filenamep = Memory::GetCharPointer(mips->r[MIPS_REG_S1]); if (!filenamep) { ERROR_LOG(Log::G3D, "__KernelGPUReplay: Failed to load dump filename"); Core_Stop(); return 0; } - std::string filename(filenamep, currentMIPS->r[MIPS_REG_S0]); + std::string filename(filenamep, mips->r[MIPS_REG_S0]); GPURecord::ReplayResult result = GPURecord::RunMountedReplay(filename); if (result == GPURecord::ReplayResult::Error) { @@ -2571,7 +2571,7 @@ int __KernelGPUReplay() { return hleNoLog(result == GPURecord::ReplayResult::Break ? 1 : 0); } -int sceKernelLoadExec(const char *filename, u32 paramPtr) { +int sceKernelLoadExec(MIPSState *mips, const char *filename, u32 paramPtr) { std::string exec_filename = filename; PSPFileInfo info = pspFileSystem.GetFileInfo(exec_filename); @@ -2597,7 +2597,7 @@ int sceKernelLoadExec(const char *filename, u32 paramPtr) { DEBUG_LOG(Log::sceModule, "sceKernelLoadExec(name=%s,...): loading %s", filename, exec_filename.c_str()); std::string error_string; - if (!__KernelLoadExec(currentMIPS, exec_filename.c_str(), paramPtr, &error_string)) { + if (!__KernelLoadExec(mips, exec_filename.c_str(), paramPtr, &error_string)) { Core_HLEError("sceKernelLoadExec failed: " + error_string); return hleLogError(Log::sceModule, -1, "failed: %s", error_string.c_str());; } @@ -2694,7 +2694,7 @@ static u32 KernelLoadModuleFromData(const char *name, std::vector &file return module->GetUID(); } -u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) { +u32 sceKernelLoadModule(MIPSState *mips, const char *name, u32 flags, u32 optionAddr) { if (!name) { return hleLogError(Log::Loader, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "bad filename"); } @@ -2799,7 +2799,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) { if (gpu) { gpu->Reinitialize(); } - return __KernelLoadExec(currentMIPS, safeName.c_str(), 0, &error_string); + return __KernelLoadExec(mips, safeName.c_str(), 0, &error_string); } return hleDelayResult(hleNoLog(result), "module loaded", loadUs); } @@ -2827,10 +2827,10 @@ static void __KernelLoadModuleDone(u64 userdata, int cyclesLate) { __KernelReSchedule("module loaded"); } -static u32 sceKernelLoadModuleNpDrm(const char *name, u32 flags, u32 optionAddr) { +static u32 sceKernelLoadModuleNpDrm(MIPSState *mips, const char *name, u32 flags, u32 optionAddr) { // Just forward it, same parameters so the logging will make sense. The NPDRM EDAT wrapper these // modules carry is stepped over in there, since that's keyed off the file's own magic. - return sceKernelLoadModule(name, flags, optionAddr); + return sceKernelLoadModule(mips, name, flags, optionAddr); } // The only thread attributes a SceKernelSMOption may carry (VFPU, SCRATCH_SRAM and 0x00F00000). @@ -3189,10 +3189,10 @@ static u32 sceKernelStopUnloadSelfModuleWithStatus(u32 exitCode, u32 argSize, u3 return __KernelStopUnloadSelfModuleWithOrWithoutStatus(exitCode, argSize, argp, statusAddr, optionAddr, true); } -void __KernelReturnFromModuleFunc() { +void __KernelReturnFromModuleFunc(MIPSState *mips) { // Return from the thread as normal. hleSkipDeadbeef(); - __KernelReturnFromThread(); + __KernelReturnFromThread(mips); SceUID leftModuleID = __KernelGetCurThreadModuleId(); SceUID leftThreadID = __KernelGetCurThread(); @@ -3225,7 +3225,7 @@ void __KernelReturnFromModuleFunc() { { if (module->nm.status == MODULE_STATUS_UNLOADING) { // TODO: Maybe should maintain the exitCode? - hleCall(ThreadManForKernel, int, sceKernelTerminateDeleteThread, it->threadID); + hleCall(ThreadManForKernel, int, sceKernelTerminateDeleteThread, mips, it->threadID); } else { if (it->statusPtr != 0) Memory::WriteOrException_U32(exitStatus, it->statusPtr); @@ -3630,8 +3630,8 @@ bool DescribeModuleAddress(u32 address, char *buffer, size_t bufferSize) { } //fix for tiger x dragon -static u32 sceKernelLoadModuleForLoadExecVSHDisc(const char *name, u32 flags, u32 optionAddr) { - return sceKernelLoadModule(name, flags, optionAddr); +static u32 sceKernelLoadModuleForLoadExecVSHDisc(MIPSState *mips, const char *name, u32 flags, u32 optionAddr) { + return sceKernelLoadModule(mips, name, flags, optionAddr); } // How the VSH loads its own plugins - the XMB's UI lives in flash0:/vsh/module/*_plugin.prx and @@ -3642,8 +3642,8 @@ static u32 sceKernelLoadModuleForLoadExecVSHDisc(const char *name, u32 flags, u3 // // The apitype the name refers to only affects what the loaded module may itself do; loading is // otherwise the ordinary path, same as sceKernelLoadModuleForLoadExecVSHDisc above. -static u32 sceKernelLoadModuleVSH(const char *name, u32 flags, u32 optionAddr) { - return sceKernelLoadModule(name, flags, optionAddr); +static u32 sceKernelLoadModuleVSH(MIPSState *mips, const char *name, u32 flags, u32 optionAddr) { + return sceKernelLoadModule(mips, name, flags, optionAddr); } // Looks up an already-loaded module by the name in its module info, returning its uid. diff --git a/Core/HLE/sceKernelModule.h b/Core/HLE/sceKernelModule.h index 9df71ded49..758445be05 100644 --- a/Core/HLE/sceKernelModule.h +++ b/Core/HLE/sceKernelModule.h @@ -250,8 +250,8 @@ bool KernelFindImportByStubAddr(u32 stubAddr, std::string *importModuleName, u32 // Describes which loaded module (and section within it) an address falls in, e.g. "EBOOT.BIN.text+1234". // Returns an empty string if the address isn't inside any currently loaded module. bool DescribeModuleAddress(u32 address, char *buffer, size_t bufferSize); -int __KernelGPUReplay(); -void __KernelReturnFromModuleFunc(); +int __KernelGPUReplay(MIPSState *mips); +void __KernelReturnFromModuleFunc(MIPSState *mips); // fromTop puts the module at the top of the user partition instead of the bottom. Use it for // firmware modules we inject before the game loads - taking the bottom pushes the game's own ELF // up, which shifts every address in it and invalidates cheats and achievements, and outright @@ -276,5 +276,5 @@ void Register_ModuleMgrForKernel(); void Register_SystemCtrlForKernel(); // Expose for use by KUBridge. -u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr); +u32 sceKernelLoadModule(MIPSState *mips, const char *name, u32 flags, u32 optionAddr); u32 sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr); diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index fe2a5cbff2..9aca3fb130 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -241,7 +241,7 @@ void __KernelMutexEndCallback(SceUID threadID, SceUID prevCallbackId) DEBUG_LOG(Log::sceKernel, "sceKernelLockMutexCB: Resuming lock wait for callback"); } -int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr) { +int sceKernelCreateMutex(MIPSState *mips, const char *name, u32 attr, int initialCount, u32 optionsPtr) { if (!name) return hleLogWarning(Log::sceKernel, SCE_KERNEL_ERROR_ERROR, "invalid name"); if (attr & ~0xBFF) @@ -273,7 +273,7 @@ int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optio if (size > 4) WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateMutex(%s) unsupported options parameter, size = %d", name, size); } else { - Core_MemoryExceptionHLE(currentMIPS, optionsPtr, 4, MemoryExceptionType::HLE_READ); + Core_MemoryExceptionHLE(mips, optionsPtr, 4, MemoryExceptionType::HLE_READ); } } if ((attr & ~PSP_MUTEX_ATTR_KNOWN) != 0) @@ -595,7 +595,7 @@ int sceKernelReferMutexStatus(SceUID id, u32 infoAddr) { return hleLogDebug(Log::sceKernel, 0); } -int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr) { +int sceKernelCreateLwMutex(MIPSState *mips, u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr) { if (!name) { return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_ERROR, "invalid name"); } @@ -634,7 +634,7 @@ int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int init if (size > 4) WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateLwMutex(%s) unsupported options parameter, size = %d", name, size); } else { - Core_MemoryExceptionHLE(currentMIPS, optionsPtr, 4, MemoryExceptionType::HLE_READ); + Core_MemoryExceptionHLE(mips, optionsPtr, 4, MemoryExceptionType::HLE_READ); } } if ((attr & ~PSP_MUTEX_ATTR_KNOWN) != 0) diff --git a/Core/HLE/sceKernelMutex.h b/Core/HLE/sceKernelMutex.h index 12674b7b02..5d6f9c1210 100644 --- a/Core/HLE/sceKernelMutex.h +++ b/Core/HLE/sceKernelMutex.h @@ -58,7 +58,7 @@ struct PSPMutex : public KernelObject { }; int sceKernelCancelMutex(SceUID uid, int count, u32 numWaitThreadsPtr); -int sceKernelCreateMutex(const char *name, u32 attr, int initialCount, u32 optionsPtr); +int sceKernelCreateMutex(MIPSState *mips, const char *name, u32 attr, int initialCount, u32 optionsPtr); int sceKernelDeleteMutex(SceUID id); int sceKernelLockMutex(SceUID id, int count, u32 timeoutPtr); int sceKernelLockMutexCB(SceUID id, int count, u32 timeoutPtr); @@ -66,7 +66,7 @@ int sceKernelTryLockMutex(SceUID id, int count); int sceKernelUnlockMutex(SceUID id, int count); int sceKernelReferMutexStatus(SceUID id, u32 infoAddr); -int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr); +int sceKernelCreateLwMutex(MIPSState *mips, u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr); int sceKernelDeleteLwMutex(u32 workareaPtr); int sceKernelTryLockLwMutex(u32 workareaPtr, int count); int sceKernelTryLockLwMutex_600(u32 workareaPtr, int count); diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index cc0f0b0c84..fd2d2d2cf7 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1126,12 +1126,12 @@ bool __KernelSwitchToThread(SceUID threadID, const char *reason) return false; } -void __KernelIdle() +void __KernelIdle(MIPSState *mips) { // Don't skip 0xDEADBEEF here, this is called directly bypassing CallSyscall(). // That means the hle flag would stick around until the next call. - CoreTiming::Idle(currentMIPS); + CoreTiming::Idle(mips); // We Advance within __KernelReSchedule(), so anything that has now happened after idle // will be triggered properly upon reschedule. __KernelReSchedule("idle"); @@ -1226,7 +1226,7 @@ SceUID __KernelGetCurrentCallbackID(SceUID threadID, u32 &error) { } } -u32 sceKernelReferThreadStatus(u32 threadID, u32 statusPtr) { +u32 sceKernelReferThreadStatus(MIPSState *mips, u32 threadID, u32 statusPtr) { static const u32 THREADINFO_SIZE = 104; static const u32 THREADINFO_SIZE_AFTER_260 = 108; @@ -1242,7 +1242,7 @@ u32 sceKernelReferThreadStatus(u32 threadID, u32 statusPtr) { } if (!Memory::IsValid4AlignedAddress(statusPtr)) { - Core_MemoryExceptionHLE(currentMIPS, statusPtr, 0, MemoryExceptionType::HLE_READ); + Core_MemoryExceptionHLE(mips, statusPtr, 0, MemoryExceptionType::HLE_READ); return hleNoLog(0); } @@ -1714,7 +1714,7 @@ u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason) t->Cleanup(); // Before triggering, set v0. It'll be restored if one is called. - RETURN(error); + currentMIPS->r[MIPS_REG_V0] = error; t->nt.status = THREADSTATUS_DEAD; if (__KernelThreadTriggerEvent((t->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0, threadID, THREADEVENT_DELETE)) { @@ -1725,7 +1725,7 @@ u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason) return kernelObjects.Destroy(threadID); } } else { - RETURN(error); + currentMIPS->r[MIPS_REG_V0] = error; return error; } } @@ -1955,12 +1955,12 @@ void __KernelReSchedule(bool doCallbacks, const char *reason) } } -int sceKernelCheckThreadStack() +int sceKernelCheckThreadStack(MIPSState *mips) { u32 error; PSPThread *t = kernelObjects.Get(__KernelGetCurThread(), error); if (t) { - u32 diff = labs((long)((s64)currentMIPS->r[MIPS_REG_SP] - (s64)t->currentStack.start)); + u32 diff = labs((long)((s64)mips->r[MIPS_REG_SP] - (s64)t->currentStack.start)); DEBUG_LOG(Log::sceKernel, "%i=sceKernelCheckThreadStack()", diff); return diff; } else { @@ -2201,7 +2201,7 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 hleReSchedule("thread created"); // Before triggering, set v0, since we restore on return. - RETURN(id); + currentMIPS->r[MIPS_REG_V0] = id; const bool handled = __KernelThreadTriggerEvent((attr & PSP_THREAD_ATTR_KERNEL) != 0, id, THREADEVENT_CREATE); if (busyCyclesOut && !handled) { *busyCyclesOut = fillCycles; @@ -2294,7 +2294,7 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo // Need to write out v0 before triggering event. // TODO: Technically the wrong place. This should trigger when the thread actually starts (e.g. if suspended.) - RETURN(0); + currentMIPS->r[MIPS_REG_V0] = 0; __KernelThreadTriggerEvent((startThread->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0, threadToStartID, THREADEVENT_START); return 0; } @@ -2361,11 +2361,11 @@ int sceKernelGetThreadStackFreeSize(SceUID threadID) { // What a thread ending costs, besides the switch away from it. static const int THREAD_EXIT_CYCLES = 3300; -void __KernelReturnFromThread() +void __KernelReturnFromThread(MIPSState *mips) { hleSkipDeadbeef(); - int exitStatus = currentMIPS->r[MIPS_REG_V0]; + int exitStatus = mips->r[MIPS_REG_V0]; PSPThread *thread = __GetCurrentThread(); _dbg_assert_msg_(thread != NULL, "Returned from a NULL thread."); @@ -2541,7 +2541,7 @@ int sceKernelDeleteThread(int threadID) { } } -int sceKernelTerminateDeleteThread(int threadID) { +int sceKernelTerminateDeleteThread(MIPSState *mips, int threadID) { if (threadID == 0 || threadID == currentThread) { return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_THID, "cannot terminate current thread"); } @@ -2571,7 +2571,7 @@ int sceKernelTerminateDeleteThread(int threadID) { } } -int sceKernelTerminateThread(SceUID threadID) { +int sceKernelTerminateThread(MIPSState *mips, SceUID threadID) { if (__IsInInterrupt() && sceKernelGetCompiledSdkVersion() >= 0x03080000) { return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_CONTEXT, "in interrupt"); } @@ -3156,7 +3156,7 @@ int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) { } } -u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter) { +u32 sceKernelExtendThreadStack(MIPSState *mips, u32 size, u32 entryAddr, u32 entryParameter) { if (size < 512) { return hleReportError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_STACK_SIZE, "stack size too small"); } @@ -3171,23 +3171,23 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter) { // The stack has been changed now, so it's do or die time. // Push the old SP, RA, and PC onto the stack (so we can restore them later.) - Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_RA], thread->currentStack.end - 4); - Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8); - Memory::WriteOrException_U32(currentMIPS->pc, thread->currentStack.end - 12); + Memory::WriteOrException_U32(mips->r[MIPS_REG_RA], thread->currentStack.end - 4); + Memory::WriteOrException_U32(mips->r[MIPS_REG_SP], thread->currentStack.end - 8); + Memory::WriteOrException_U32(mips->pc, thread->currentStack.end - 12); KernelValidateThreadTarget(entryAddr); - currentMIPS->pc = entryAddr; - currentMIPS->r[MIPS_REG_A0] = entryParameter; - currentMIPS->r[MIPS_REG_RA] = extendReturnHackAddr; + mips->pc = entryAddr; + mips->r[MIPS_REG_A0] = entryParameter; + mips->r[MIPS_REG_RA] = extendReturnHackAddr; // Stack should stay aligned even though we saved only 3 regs. - currentMIPS->r[MIPS_REG_SP] = thread->currentStack.end - 0x10; + mips->r[MIPS_REG_SP] = thread->currentStack.end - 0x10; hleSkipDeadbeef(); return hleLogDebug(Log::sceKernel, 0); } -void __KernelReturnFromExtendStack() { +void __KernelReturnFromExtendStack(MIPSState *mips) { hleSkipDeadbeef(); PSPThread *thread = __GetCurrentThread(); @@ -3198,7 +3198,7 @@ void __KernelReturnFromExtendStack() { } if (!Memory::IsValid4AlignedRange(thread->currentStack.end - 12, 12)) { - Core_MemoryExceptionHLE(currentMIPS, thread->currentStack.end, 12, MemoryExceptionType::HLE_READ); + Core_MemoryExceptionHLE(mips, thread->currentStack.end, 12, MemoryExceptionType::HLE_READ); hleNoLogVoid(); return; } @@ -3216,9 +3216,9 @@ void __KernelReturnFromExtendStack() { KernelValidateThreadTarget(restorePC); DEBUG_LOG(Log::sceKernel, "__KernelReturnFromExtendStack()"); - currentMIPS->r[MIPS_REG_RA] = restoreRA; - currentMIPS->r[MIPS_REG_SP] = restoreSP; - currentMIPS->pc = restorePC; + mips->r[MIPS_REG_RA] = restoreRA; + mips->r[MIPS_REG_SP] = restoreSP; + mips->pc = restorePC; // We retain whatever is in v0/v1, it gets passed on to the caller of sceKernelExtendThreadStack(). hleNoLogVoid(); @@ -3586,7 +3586,7 @@ bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter) return true; } -void __KernelReturnFromMipsCall() { +void __KernelReturnFromMipsCall(MIPSState *mips) { hleSkipDeadbeef(); PSPThread *cur = __GetCurrentThread(); @@ -3603,7 +3603,7 @@ void __KernelReturnFromMipsCall() { } // Value returned by the callback function - u32 retVal = currentMIPS->r[MIPS_REG_V0]; + u32 retVal = mips->r[MIPS_REG_V0]; DEBUG_LOG(Log::sceKernel, "__KernelReturnFromMipsCall(), returned %08x", retVal); // TODO: Should also save/restore wait state here? @@ -3615,28 +3615,28 @@ void __KernelReturnFromMipsCall() { call->doAfter = nullptr; } - u32 sp = currentMIPS->r[MIPS_REG_SP]; + u32 sp = mips->r[MIPS_REG_SP]; if (!Memory::IsValid4AlignedRange(sp, 32 * 4)) { // We're really screwed. - Core_MemoryExceptionHLE(currentMIPS, sp, 4, MemoryExceptionType::HLE_READ); + Core_MemoryExceptionHLE(mips, sp, 4, MemoryExceptionType::HLE_READ); return hleNoLogVoid(); } for (int i = MIPS_REG_A0; i <= MIPS_REG_T7; ++i) { - currentMIPS->r[i] = Memory::ReadUnchecked_U32(sp + i * 4); + mips->r[i] = Memory::ReadUnchecked_U32(sp + i * 4); } - currentMIPS->r[MIPS_REG_T8] = Memory::ReadUnchecked_U32(sp + MIPS_REG_T8 * 4); - currentMIPS->r[MIPS_REG_T9] = Memory::ReadUnchecked_U32(sp + MIPS_REG_T9 * 4); - currentMIPS->r[MIPS_REG_RA] = Memory::ReadUnchecked_U32(sp + MIPS_REG_RA * 4); + mips->r[MIPS_REG_T8] = Memory::ReadUnchecked_U32(sp + MIPS_REG_T8 * 4); + mips->r[MIPS_REG_T9] = Memory::ReadUnchecked_U32(sp + MIPS_REG_T9 * 4); + mips->r[MIPS_REG_RA] = Memory::ReadUnchecked_U32(sp + MIPS_REG_RA * 4); // Increment SP. - currentMIPS->r[MIPS_REG_SP] += 32 * 4; + mips->r[MIPS_REG_SP] += 32 * 4; KernelValidateThreadTarget(call->savedPc); - currentMIPS->pc = call->savedPc; + mips->pc = call->savedPc; // This is how we set the return value. - currentMIPS->r[MIPS_REG_V0] = call->savedV0; - currentMIPS->r[MIPS_REG_V1] = call->savedV1; + mips->r[MIPS_REG_V0] = call->savedV0; + mips->r[MIPS_REG_V1] = call->savedV1; cur->currentMipscallId = call->savedId; if (cur->nt.waitType != WAITTYPE_NONE && (cur->nt.status & THREADSTATUS_WAIT) != 0 && call->cbId > 0) { @@ -3863,7 +3863,7 @@ bool __KernelForceCallbacks() { } // Not wrapped because it has special return logic. -void sceKernelCheckCallback() { +void sceKernelCheckCallback(MIPSState *mips) { // Unlike CB waits, this refuses to run callbacks from inside one. if (__KernelIsInCallbackOnThread(__GetCurrentThread())) { DEBUG_LOG(Log::sceKernel, "sceKernelCheckCallback() - in a callback, refused."); diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index a6cd9522da..5cf6b2d67c 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -68,26 +68,26 @@ u32 sceKernelResumeDispatchThread(u32 suspended); int sceKernelGetUserLevel(); int sceKernelIsUserModeThread(); int sceKernelWaitThreadEnd(SceUID threadID, u32 timeoutPtr); -u32 sceKernelReferThreadStatus(u32 uid, u32 statusPtr); +u32 sceKernelReferThreadStatus(MIPSState *mips, u32 uid, u32 statusPtr); u32 sceKernelReferThreadRunStatus(u32 uid, u32 statusPtr); int sceKernelReleaseWaitThread(SceUID threadID); int sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr); int sceKernelRotateThreadReadyQueue(int priority); int KernelRotateThreadReadyQueue(int priority); -int sceKernelCheckThreadStack(); +int sceKernelCheckThreadStack(MIPSState *mips); int sceKernelSuspendThread(SceUID threadID); int sceKernelResumeThread(SceUID threadID); int sceKernelWakeupThread(SceUID threadID); int sceKernelCancelWakeupThread(SceUID threadID); int sceKernelSleepThread(); int sceKernelSleepThreadCB(); -int sceKernelTerminateDeleteThread(int threadno); -int sceKernelTerminateThread(SceUID threadID); +int sceKernelTerminateDeleteThread(MIPSState *mips, int threadno); +int sceKernelTerminateThread(MIPSState *mips, SceUID threadID); int sceKernelWaitThreadEndCB(SceUID threadID, u32 timeoutPtr); int sceKernelGetThreadExitStatus(SceUID threadID); u32 sceKernelGetThreadmanIdType(u32); u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 idCountPtr); -u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter); +u32 sceKernelExtendThreadStack(MIPSState *mips, u32 size, u32 entryAddr, u32 entryParameter); void __KernelScheduleWakeup(SceUID threadID, s64 usFromNow); struct SceKernelSysClock { @@ -411,13 +411,13 @@ SceUID __KernelGetCurThread(); SceUID __KernelGetCurThreadModuleId(); SceUID __KernelSetupRootThread(SceUID moduleId, int args, const char *argp, int prio, int stacksize, int attr); //represents the real PSP elf loader, run before execution void __KernelStartIdleThreads(SceUID moduleId); -void __KernelReturnFromThread(); // Called as HLE function +void __KernelReturnFromThread(MIPSState *mips); // Called as HLE function u32 __KernelGetThreadPrio(SceUID id); bool __KernelThreadSortPriority(SceUID thread1, SceUID thread2); bool __KernelIsDispatchEnabled(); -void __KernelReturnFromExtendStack(); +void __KernelReturnFromExtendStack(MIPSState *mips); -void __KernelIdle(); +void __KernelIdle(MIPSState *mips); u32 HLEMipsCallReturnAddress(); u32 __KernelCallbackReturnAddress(); @@ -428,7 +428,7 @@ int sceKernelDeleteCallback(SceUID cbId); int sceKernelNotifyCallback(SceUID cbId, int notifyArg); int sceKernelCancelCallback(SceUID cbId); int sceKernelGetCallbackCount(SceUID cbId); -void sceKernelCheckCallback(); +void sceKernelCheckCallback(MIPSState *mips); int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr); class PSPAction; @@ -437,7 +437,7 @@ class PSPAction; // Takes ownership of afterAction. void __KernelDirectMipsCall(u32 entryPoint, PSPAction *afterAction, u32 args[], int numargs, bool reschedAfter); -void __KernelReturnFromMipsCall(); // Called as HLE function +void __KernelReturnFromMipsCall(MIPSState *mips); // Called as HLE function bool __KernelInCallback(); // Should be called by (nearly) all ...CB functions. diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 2b128ea220..c60525cea0 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -487,7 +487,7 @@ u32 sceKernelReferVTimerStatus(SceUID uid, u32 statusAddr) { } // Not sure why this is exposed... -void _sceKernelReturnFromTimerHandler() { +void _sceKernelReturnFromTimerHandler(MIPSState *mips) { ERROR_LOG_REPORT(Log::sceKernel,"_sceKernelReturnFromTimerHandler - should not be called!"); return hleNoLogVoid(); } diff --git a/Core/HLE/sceKernelVTimer.h b/Core/HLE/sceKernelVTimer.h index e31ff3f11d..e89d64967f 100644 --- a/Core/HLE/sceKernelVTimer.h +++ b/Core/HLE/sceKernelVTimer.h @@ -32,7 +32,7 @@ u64 sceKernelGetVTimerTimeWide(SceUID uid); u32 sceKernelSetVTimerTime(SceUID uid, u32 timeClockAddr); u64 sceKernelSetVTimerTimeWide(SceUID uid, u64 timeClock); -void _sceKernelReturnFromTimerHandler(); +void _sceKernelReturnFromTimerHandler(MIPSState *mips); void __KernelVTimerInit(); void __KernelVTimerDoState(PointerWrap &p); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 253ab3e7a5..ab5907482a 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -1002,7 +1002,7 @@ Parameters: netintrprio - Priority of the SceNetNetintr thread. netintrstack - Stack size of the SceNetNetintr thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed). */ -static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) { +static int sceNetInit(MIPSState *mips, u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) { // TODO: Create Network Threads using given priority & stack // TODO: The correct behavior is actually to allocate more and leak the other threads/pool. // But we reset here for historic reasons (GTA:VCS potentially triggers this.) @@ -1040,7 +1040,7 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini return hleLogError(Log::sceNet, SCE_KERNEL_ERROR_NO_MEMORY, "unable to allocate pool"); } - INFO_LOG(Log::sceNet, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, currentMIPS->pc); + INFO_LOG(Log::sceNet, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, mips->pc); netMallocStat.pool = poolSize - 0x20; // On Vantage Master Portable this is slightly (32 bytes) smaller than the poolSize arg when tested with JPCSP + prx files netMallocStat.maximum = 0x4050; // Dummy maximum foot print @@ -1107,8 +1107,8 @@ static u32 sceWlanGetSwitchState() { } // Probably a void function, but often returns a useful value. -static void sceNetEtherNtostr(u32 macPtr, u32 bufferPtr) { - DEBUG_LOG(Log::sceNet, "sceNetEtherNtostr(%08x, %08x) at %08x", macPtr, bufferPtr, currentMIPS->pc); +static void sceNetEtherNtostr(MIPSState *mips, u32 macPtr, u32 bufferPtr) { + DEBUG_LOG(Log::sceNet, "sceNetEtherNtostr(%08x, %08x) at %08x", macPtr, bufferPtr, mips->pc); if (Memory::IsValidAddress(bufferPtr) && Memory::IsValidAddress(macPtr)) { char *buffer = (char *)Memory::GetPointerWriteUnchecked(bufferPtr); @@ -1240,7 +1240,7 @@ void NetApctl_InitInfo(int confId) { truncate_cpy(netApctlInfo.subNetMask, sizeof(netApctlInfo.subNetMask), "255.255.255.0"); } -static int sceNetApctlInit(int stackSize, int initPriority) { +static int sceNetApctlInit(MIPSState *mips, int stackSize, int initPriority) { if (g_netApctlInited) { return hleLogError(Log::sceNet, SCE_NET_APCTL_ERROR_ALREADY_INITIALIZED); } @@ -1275,7 +1275,7 @@ static int sceNetApctlInit(int stackSize, int initPriority) { // Actually connect sceNetAdhocctl. TODO: Can we move this to sceNetApctlConnect? Would be good because a lot of games call Init but not Connect on startup. if (g_infraDNSConfig.connectAdHocForGrouping) { - hleCall(sceNetAdhocctl, int, sceNetAdhocctlInit, stackSize, initPriority, apctlProdCodeAddr); + hleCall(sceNetAdhocctl, int, sceNetAdhocctlInit, mips, stackSize, initPriority, apctlProdCodeAddr); } g_netApctlInited = true; @@ -1316,8 +1316,8 @@ static int sceNetApctlTerm() { return hleLogInfo(Log::sceNet, retval); } -static int sceNetApctlGetInfo(int code, u32 pInfoAddr) { - DEBUG_LOG(Log::sceNet, "sceNetApctlGetInfo(%i, %08x) at %08x", code, pInfoAddr, currentMIPS->pc); +static int sceNetApctlGetInfo(MIPSState *mips, int code, u32 pInfoAddr) { + DEBUG_LOG(Log::sceNet, "sceNetApctlGetInfo(%i, %08x) at %08x", code, pInfoAddr, mips->pc); switch (code) { case PSP_NET_APCTL_INFO_PROFILE_NAME: @@ -1509,7 +1509,7 @@ static int sceNetApctlDelHandler(u32 handlerID) { return NetApctl_DelHandler(handlerID); } -int sceNetApctlConnect(int confId) { +int sceNetApctlConnect(MIPSState *mips, int confId) { if (!g_Config.bEnableWlan) return hleLogError(Log::sceNet, SCE_NET_APCTL_ERROR_WLAN_SWITCH_OFF); @@ -1522,7 +1522,7 @@ int sceNetApctlConnect(int confId) { // Note: We're borrowing AdhocServer for Grouping purpose, so we can simulate Broadcast over the internet just like Adhoc's pro-online implementation int ret = 0; if (g_infraDNSConfig.connectAdHocForGrouping) { - ret = hleCall(sceNetAdhocctl, int, sceNetAdhocctlConnect, "INFRA"); + ret = hleCall(sceNetAdhocctl, int, sceNetAdhocctlConnect, mips, "INFRA"); } if (netApctlState == PSP_NET_APCTL_STATE_DISCONNECTED) { @@ -1722,8 +1722,8 @@ static int sceNetApctlGetBSSDescIDList2(u32 Arg1, u32 Arg2, u32 Arg3, u32 Arg4) * Arg2 = input field type within the entry desc (ie. PSP_NET_APCTL_DESC_SSID_NAME ?) * Arg3 = output buffer for retrieved entry data? (max size = 32 bytes? ie. APCTL_SSID_MAXLEN ? or similar to SceNetApctlInfoInternal union ?) ***************/ -static int sceNetApctlGetBSSDescEntry2(int entryId, int infoId, u32 resultAddr) { - WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %i, %08x) at %08x", __FUNCTION__, entryId, infoId, resultAddr, currentMIPS->pc); +static int sceNetApctlGetBSSDescEntry2(MIPSState *mips, int entryId, int infoId, u32 resultAddr) { + WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %i, %08x) at %08x", __FUNCTION__, entryId, infoId, resultAddr, mips->pc); return NetApctl_GetBSSDescEntryUser(entryId, infoId, resultAddr); } @@ -1757,10 +1757,10 @@ static int sceNetApctl_lib2_69745F0A(int handlerId) { return hleLogError(Log::sceNet, 0, "unimplemented"); } -static int sceNetApctl_lib2_4C19731F(int code, u32 pInfoAddr) { +static int sceNetApctl_lib2_4C19731F(MIPSState *mips, int code, u32 pInfoAddr) { ERROR_LOG(Log::sceNet, "UNIMPL %s(%i, %08x)", __FUNCTION__, code, pInfoAddr); // Simple forward, don't need to use hleCall - return sceNetApctlGetInfo(code, pInfoAddr); + return sceNetApctlGetInfo(mips, code, pInfoAddr); } static int sceNetApctlScan() { @@ -1777,10 +1777,10 @@ static int sceNetApctlGetBSSDescEntry(int entryId, int infoId, u32 resultAddr) { return sceNetApctlGetBSSDescEntryUser(entryId, infoId, resultAddr); } -static int sceNetApctl_lib2_C20A144C(int connIndex, u32 ps3MacAddressPtr) { +static int sceNetApctl_lib2_C20A144C(MIPSState *mips, int connIndex, u32 ps3MacAddressPtr) { ERROR_LOG(Log::sceNet, "UNIMPL %s(%i, %08x)", __FUNCTION__, connIndex, ps3MacAddressPtr); // Simple forward, don't need to use hleCall - return sceNetApctlConnect(connIndex); + return sceNetApctlConnect(mips, connIndex); } static int sceNetUpnpInit(int unknown1,int unknown2) { diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 2b5812afd8..cdaa07e057 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -116,7 +116,7 @@ int NetApctl_GetState(); bool __NetApctlConnected(); -int sceNetApctlConnect(int connIndex); +int sceNetApctlConnect(MIPSState *mips, int connIndex); int sceNetApctlDisconnect(); // Are we connected - for the purpose of disabling speed consoles and savestates etc. diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 0e21b8e807..8e5f94ef09 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -377,7 +377,7 @@ static void __GameModeNotify(u64 userdata, int cyclesLate) { if (buf) gameModeBuffer = buf; - if ((gameModeSocket = sceNetAdhocPdpCreate((const char*)&masterGameModeArea.mac, ADHOC_GAMEMODE_PORT, gameModeBuffSize, 0)) < 0) { + if ((gameModeSocket = sceNetAdhocPdpCreate(currentMIPS, (const char*)&masterGameModeArea.mac, ADHOC_GAMEMODE_PORT, gameModeBuffSize, 0)) < 0) { ERROR_LOG(Log::sceNet, "GameMode: Failed to create socket (Error %08x)", gameModeSocket); __KernelResumeThreadFromWait(threadID, gameModeSocket); return; @@ -410,7 +410,7 @@ static void __GameModeNotify(u64 userdata, int cyclesLate) { if (it != gameModePeerPorts.end()) port = it->second; - int sent = hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, gameModeSocket, (const char*)&gma.mac, port, masterGameModeArea.data, masterGameModeArea.size, 0, ADHOC_F_NONBLOCK); + int sent = hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, gameModeSocket, (const char*)&gma.mac, port, masterGameModeArea.data, masterGameModeArea.size, 0, ADHOC_F_NONBLOCK); if (sent != SCE_NET_ADHOC_ERROR_WOULD_BLOCK) { gma.dataSent = 1; DEBUG_LOG(Log::sceNet, "GameMode: Master data Sent %d bytes to Area #%d [%s]", masterGameModeArea.size, gma.id, mac2str(&gma.mac).c_str()); @@ -439,7 +439,7 @@ static void __GameModeNotify(u64 userdata, int cyclesLate) { if (it != gameModePeerPorts.end()) port = it->second; - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, gameModeSocket, (const char*)&gma.mac, port, masterGameModeArea.data, masterGameModeArea.size, 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, gameModeSocket, (const char*)&gma.mac, port, masterGameModeArea.data, masterGameModeArea.size, 0, ADHOC_F_NONBLOCK); } } } @@ -472,7 +472,7 @@ static void __GameModeNotify(u64 userdata, int cyclesLate) { SceNetEtherAddr sendermac; s32_le senderport = ADHOC_GAMEMODE_PORT; s32_le bufsz = gameModeBuffSize; - int ret = sceNetAdhocPdpRecv(gameModeSocket, &sendermac, &senderport, gameModeBuffer, &bufsz, 0, ADHOC_F_NONBLOCK); + int ret = sceNetAdhocPdpRecv(currentMIPS, gameModeSocket, &sendermac, &senderport, gameModeBuffer, &bufsz, 0, ADHOC_F_NONBLOCK); if (ret >= 0 && bufsz > 0) { // Shows a warning if the sender/source port is different than what it supposed to be. if (senderport != ADHOC_GAMEMODE_PORT && senderport != gameModePeerPorts[sendermac]) { @@ -2025,7 +2025,7 @@ void __NetAdhocInit() { } } -u32 sceNetAdhocInit() { +u32 sceNetAdhocInit(MIPSState *mips) { if (!netAdhocInited) { // Library initialized netAdhocInited = true; @@ -2045,14 +2045,14 @@ u32 sceNetAdhocInit() { } // Return Success - return hleLogInfo(Log::sceNet, 0, "at %08x", currentMIPS->pc); + return hleLogInfo(Log::sceNet, 0, "at %08x", mips->pc); } // Already initialized return hleLogWarning(Log::sceNet, SCE_NET_ADHOC_ERROR_ALREADY_INITIALIZED, "already initialized"); } -int sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { - INFO_LOG(Log::sceNet, "sceNetAdhocctlInit(%i, %i, %08x) at %08x", stackSize, prio, productAddr, currentMIPS->pc); +int sceNetAdhocctlInit(MIPSState *mips, int stackSize, int prio, u32 productAddr) { + INFO_LOG(Log::sceNet, "sceNetAdhocctlInit(%i, %i, %08x) at %08x", stackSize, prio, productAddr, mips->pc); // FIXME: Returning 0x8002013a (SCE_KERNEL_ERROR_LIBRARY_NOT_YET_LINKED) without adhoc module loaded first? // FIXME: Sometimes returning 0x80410601 (SCE_NET_ADHOC_ERROR_AUTH_ALREADY_INITIALIZED / Library module is already initialized ?) when AdhocctlTerm is not fully done? @@ -2169,8 +2169,8 @@ static int pdp_create_postoffice(const SceNetEtherAddr *saddr, int sport, int bu * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_INVALID_ADDR, ADHOC_PORT_NOT_AVAIL, ADHOC_INVALID_PORT, ADHOC_PORT_IN_USE, NET_NO_SPACE */ // When choosing AdHoc menu in Wipeout Pulse sometimes it's saying that "WLAN is turned off" on game screen and getting "kUnityCommandCode_MediaDisconnected" error in the Log Console when calling sceNetAdhocPdpCreate, probably it needed to wait something from the thread before calling this (ie. need to receives 7 bytes from adhoc server 1st?) -int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 flag) { - INFO_LOG(Log::sceNet, "sceNetAdhocPdpCreate(%s, %u, %u, %u) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), port, bufferSize, flag, currentMIPS->pc); +int sceNetAdhocPdpCreate(MIPSState *mips, const char *mac, int port, int bufferSize, u32 flag) { + INFO_LOG(Log::sceNet, "sceNetAdhocPdpCreate(%s, %u, %u, %u) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), port, bufferSize, flag, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN"); } @@ -2371,11 +2371,11 @@ static int sceNetAdhocctlGetParameter(u32 paramAddr) { * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_INVALID_DATALEN, ADHOC_SOCKET_ALERTED, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_WOULD_BLOCK, NET_NO_SPACE, NET_INTERNAL */ -int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int len, int timeout, int flag) { +int sceNetAdhocPdpSend(MIPSState *mips, int id, const char *mac, u32 port, void *data, int len, int timeout, int flag) { if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket - DEBUG_LOG(Log::sceNet, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac).c_str(), port, data, len, timeout, flag, currentMIPS->pc); + DEBUG_LOG(Log::sceNet, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac).c_str(), port, data, len, timeout, flag, mips->pc); } else { - VERBOSE_LOG(Log::sceNet, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac).c_str(), port, data, len, timeout, flag, currentMIPS->pc); + VERBOSE_LOG(Log::sceNet, "sceNetAdhocPdpSend(%i, %s, %i, %p, %i, %i, %i) at %08x", id, mac2str((SceNetEtherAddr*)mac).c_str(), port, data, len, timeout, flag, mips->pc); } if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1); @@ -2621,11 +2621,11 @@ int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int len, i * @param flag Nonblocking Flag * @return 0 (or Number of bytes received?) on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_ENOUGH_SPACE, ADHOC_THREAD_ABORTED, NET_INTERNAL */ -int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void *dataLength, u32 timeout, int flag) { +int sceNetAdhocPdpRecv(MIPSState *mips, int id, void *addr, void * port, void *buf, void *dataLength, u32 timeout, int flag) { if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket - DEBUG_LOG(Log::sceNet, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, currentMIPS->pc); + DEBUG_LOG(Log::sceNet, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, mips->pc); } else { - VERBOSE_LOG(Log::sceNet, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, currentMIPS->pc); + VERBOSE_LOG(Log::sceNet, "sceNetAdhocPdpRecv(%i, %p, %p, %p, %p, %i, %i) at %08x", id, addr, port, buf, dataLength, timeout, flag, mips->pc); } if (!g_Config.bEnableWlan) { @@ -2873,8 +2873,8 @@ int NetAdhoc_SetSocketAlert(int id, s32_le flag) { } // Flags seems to be bitmasks of ADHOC_F_ALERT... (need more games to test this) -int sceNetAdhocSetSocketAlert(int id, int flag) { - WARN_LOG_REPORT_ONCE(sceNetAdhocSetSocketAlert, Log::sceNet, "UNTESTED sceNetAdhocSetSocketAlert(%d, %08x) at %08x", id, flag, currentMIPS->pc); +int sceNetAdhocSetSocketAlert(MIPSState *mips, int id, int flag) { + WARN_LOG_REPORT_ONCE(sceNetAdhocSetSocketAlert, Log::sceNet, "UNTESTED sceNetAdhocSetSocketAlert(%d, %08x) at %08x", id, flag, mips->pc); int retval = NetAdhoc_SetSocketAlert(id, flag); return hleDelayResult(hleLogDebug(Log::sceNet, retval), "set socket alert delay", 1000); @@ -3073,8 +3073,8 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock return affectedsockets; } -int sceNetAdhocPollSocket(u32 socketStructAddr, int count, int timeout, int nonblock) { // timeout in microseconds - DEBUG_LOG_REPORT_ONCE(sceNetAdhocPollSocket, Log::sceNet, "UNTESTED sceNetAdhocPollSocket(%08x, %i, %i, %i) at %08x", socketStructAddr, count, timeout, nonblock, currentMIPS->pc); +int sceNetAdhocPollSocket(MIPSState *mips, u32 socketStructAddr, int count, int timeout, int nonblock) { // timeout in microseconds + DEBUG_LOG_REPORT_ONCE(sceNetAdhocPollSocket, Log::sceNet, "UNTESTED sceNetAdhocPollSocket(%08x, %i, %i, %i) at %08x", socketStructAddr, count, timeout, nonblock, mips->pc); // Library is initialized if (netAdhocInited) { @@ -3209,9 +3209,9 @@ int NetAdhocPdp_Delete(int id, int unknown) { * @param flag Bitflags (Unused) * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID */ -static int sceNetAdhocPdpDelete(int id, int unknown) { +static int sceNetAdhocPdpDelete(MIPSState *mips, int id, int unknown) { // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? - INFO_LOG(Log::sceNet, "sceNetAdhocPdpDelete(%d, %d) at %08x", id, unknown, currentMIPS->pc); + INFO_LOG(Log::sceNet, "sceNetAdhocPdpDelete(%d, %d) at %08x", id, unknown, mips->pc); /* if (!g_Config.bEnableWlan) { return 0; @@ -3221,8 +3221,8 @@ static int sceNetAdhocPdpDelete(int id, int unknown) { return NetAdhocPdp_Delete(id, unknown); } -static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { - INFO_LOG(Log::sceNet, "sceNetAdhocctlGetAdhocId(%08x) at %08x", productStructAddr, currentMIPS->pc); +static int sceNetAdhocctlGetAdhocId(MIPSState *mips, u32 productStructAddr) { + INFO_LOG(Log::sceNet, "sceNetAdhocctlGetAdhocId(%08x) at %08x", productStructAddr, mips->pc); if (!netAdhocctlInited) return hleLogDebug(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); @@ -3238,8 +3238,8 @@ static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { } // FIXME: Scan probably not a blocking function since there is ADHOCCTL_STATE_SCANNING state that can be polled by the game, right? But apparently it need to be delayed for Naruto Shippuden Ultimate Ninja Heroes 3 -int sceNetAdhocctlScan() { - INFO_LOG(Log::sceNet, "sceNetAdhocctlScan() at %08x", currentMIPS->pc); +int sceNetAdhocctlScan(MIPSState *mips) { + INFO_LOG(Log::sceNet, "sceNetAdhocctlScan() at %08x", mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -3292,7 +3292,7 @@ int sceNetAdhocctlScan() { return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); } -int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { +int sceNetAdhocctlGetScanInfo(MIPSState *mips, u32 sizeAddr, u32 bufAddr) { s32_le *buflen = NULL; if (Memory::IsValidAddress(sizeAddr)) { buflen = (s32_le *)Memory::GetPointerOrException(sizeAddr); @@ -3302,7 +3302,7 @@ int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) { buf = (SceNetAdhocctlScanInfoEmu *)Memory::GetPointerOrException(bufAddr); } - INFO_LOG(Log::sceNet, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x) at %08x", sizeAddr, Memory::ReadUnchecked_U32(sizeAddr), bufAddr, currentMIPS->pc); + INFO_LOG(Log::sceNet, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x) at %08x", sizeAddr, Memory::ReadUnchecked_U32(sizeAddr), bufAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogWarning(Log::sceNet, 0, "WLAN off"); } @@ -3603,8 +3603,8 @@ int sceNetAdhocctlTerm() { return hleLogInfo(Log::sceNet, retval); } -static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { - DEBUG_LOG(Log::sceNet, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), nameAddr, currentMIPS->pc); +static int sceNetAdhocctlGetNameByAddr(MIPSState *mips, const char *mac, u32 nameAddr) { + DEBUG_LOG(Log::sceNet, "UNTESTED sceNetAdhocctlGetNameByAddr(%s, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), nameAddr, mips->pc); // Library initialized if (netAdhocctlInited) @@ -3669,8 +3669,8 @@ static int sceNetAdhocctlGetNameByAddr(const char *mac, u32 nameAddr) { return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED); } -int sceNetAdhocctlGetPeerInfo(const char *mac, int size, u32 peerInfoAddr) { - VERBOSE_LOG(Log::sceNet, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), size, peerInfoAddr, currentMIPS->pc); +int sceNetAdhocctlGetPeerInfo(MIPSState *mips, const char *mac, int size, u32 peerInfoAddr) { + VERBOSE_LOG(Log::sceNet, "sceNetAdhocctlGetPeerInfo(%s, %i, %08x) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), size, peerInfoAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1); } @@ -3808,11 +3808,11 @@ int NetAdhocctl_Create(const char *groupName) { * @param group_name Virtual Network Name * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY */ -int sceNetAdhocctlCreate(const char *groupName) { +int sceNetAdhocctlCreate(MIPSState *mips, const char *groupName) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (groupName) strncpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - INFO_LOG(Log::sceNet, "sceNetAdhocctlCreate(%s) at %08x", grpName, currentMIPS->pc); + INFO_LOG(Log::sceNet, "sceNetAdhocctlCreate(%s) at %08x", grpName, mips->pc); if (!g_Config.bEnableWlan) { ERROR_LOG(Log::sceNet, "sceNetAdhocctlCreate(%s) failed: WLAN off", grpName); return -1; // Not sure about the correct error code here. @@ -3823,11 +3823,11 @@ int sceNetAdhocctlCreate(const char *groupName) { return NetAdhocctl_Create(groupName); } -int sceNetAdhocctlConnect(const char* groupName) { +int sceNetAdhocctlConnect(MIPSState *mips, const char* groupName) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (groupName) strncpy(grpName, groupName, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - INFO_LOG(Log::sceNet, "sceNetAdhocctlConnect(%s) at %08x", grpName, currentMIPS->pc); + INFO_LOG(Log::sceNet, "sceNetAdhocctlConnect(%s) at %08x", grpName, mips->pc); if (!g_Config.bEnableWlan) { ERROR_LOG(Log::sceNet, "sceNetAdhocctlConnect(%s) failed: WLAN off", grpName); return -1; // Not sure about the correct error code here. @@ -3838,8 +3838,8 @@ int sceNetAdhocctlConnect(const char* groupName) { return NetAdhocctl_Create(groupName); } -int sceNetAdhocctlJoin(u32 scanInfoAddr) { - INFO_LOG(Log::sceNet, "sceNetAdhocctlJoin(%08x) at %08x", scanInfoAddr, currentMIPS->pc); +int sceNetAdhocctlJoin(MIPSState *mips, u32 scanInfoAddr) { + INFO_LOG(Log::sceNet, "sceNetAdhocctlJoin(%08x) at %08x", scanInfoAddr, mips->pc); if (!g_Config.bEnableWlan) { return -1; } @@ -3922,11 +3922,11 @@ int NetAdhocctl_CreateEnterGameMode(const char* group_name, int game_type, int n * * @return 0 on success, < 0 on error. */ -static int sceNetAdhocctlCreateEnterGameMode(const char * group_name, int game_type, int num_members, u32 membersAddr, int timeout, int flag) { +static int sceNetAdhocctlCreateEnterGameMode(MIPSState *mips, const char * group_name, int game_type, int num_members, u32 membersAddr, int timeout, int flag) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - WARN_LOG_REPORT_ONCE(sceNetAdhocctlCreateEnterGameMode, Log::sceNet, "UNTESTED sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlCreateEnterGameMode, Log::sceNet, "UNTESTED sceNetAdhocctlCreateEnterGameMode(%s, %i, %i, %08x, %i, %i) at %08x", grpName, game_type, num_members, membersAddr, timeout, flag, mips->pc); return hleLogDebug(Log::sceNet, NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag)); } @@ -3941,11 +3941,11 @@ static int sceNetAdhocctlCreateEnterGameMode(const char * group_name, int game_t * * @return 0 on success, < 0 on error. */ -static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char *hostMac, int timeout, int flag) { +static int sceNetAdhocctlJoinEnterGameMode(MIPSState *mips, const char * group_name, const char *hostMac, int timeout, int flag) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - WARN_LOG_REPORT_ONCE(sceNetAdhocctlJoinEnterGameMode, Log::sceNet, "UNTESTED sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)hostMac).c_str(), timeout, flag, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlJoinEnterGameMode, Log::sceNet, "UNTESTED sceNetAdhocctlJoinEnterGameMode(%s, %s, %i, %i) at %08x", grpName, mac2str((SceNetEtherAddr*)hostMac).c_str(), timeout, flag, mips->pc); if (!netAdhocctlInited) return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); @@ -3983,11 +3983,11 @@ static int sceNetAdhocctlJoinEnterGameMode(const char * group_name, const char * * @param flag Unused Bitflags * @return 0 on success or... ADHOCCTL_NOT_INITIALIZED, ADHOCCTL_INVALID_ARG, ADHOCCTL_BUSY, ADHOCCTL_CHANNEL_NOT_AVAILABLE */ -int sceNetAdhocctlCreateEnterGameModeMin(const char *group_name, int game_type, int min_members, int num_members, u32 membersAddr, u32 timeout, int flag) { +int sceNetAdhocctlCreateEnterGameModeMin(MIPSState *mips, const char *group_name, int game_type, int min_members, int num_members, u32 membersAddr, u32 timeout, int flag) { char grpName[ADHOCCTL_GROUPNAME_LEN + 1] = { 0 }; if (group_name) memcpy(grpName, group_name, ADHOCCTL_GROUPNAME_LEN); // For logging purpose, must not be truncated - WARN_LOG_REPORT_ONCE(sceNetAdhocctlCreateEnterGameModeMin, Log::sceNet, "UNTESTED sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlCreateEnterGameModeMin, Log::sceNet, "UNTESTED sceNetAdhocctlCreateEnterGameModeMin(%s, %i, %i, %i, %08x, %d, %i) at %08x", grpName, game_type, min_members, num_members, membersAddr, timeout, flag, mips->pc); // We don't really need the Minimum User Check return hleLogDebug(Log::sceNet, NetAdhocctl_CreateEnterGameMode(group_name, game_type, num_members, membersAddr, timeout, flag)); } @@ -4031,8 +4031,8 @@ int sceNetAdhocTerm() { return hleLogInfo(Log::sceNet, retval); } -static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { - VERBOSE_LOG(Log::sceNet, "sceNetAdhocGetPdpStat(%08x, %08x) at %08x", structSize, structAddr, currentMIPS->pc); +static int sceNetAdhocGetPdpStat(MIPSState *mips, u32 structSize, u32 structAddr) { + VERBOSE_LOG(Log::sceNet, "sceNetAdhocGetPdpStat(%08x, %08x) at %08x", structSize, structAddr, mips->pc); // Library is initialized if (netAdhocInited) @@ -4125,11 +4125,11 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { } // Invalid Arguments - return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_ARG, "invalid arg, at %08x", currentMIPS->pc); + return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_ARG, "invalid arg, at %08x", mips->pc); } // Library is uninitialized - return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_NOT_INITIALIZED, "not initialized, at %08x", currentMIPS->pc); + return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_NOT_INITIALIZED, "not initialized, at %08x", mips->pc); } @@ -4139,9 +4139,9 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { * @param buf PTP Socket List Buffer (can be NULL if you wish to receive Required Length) * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED */ -static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { +static int sceNetAdhocGetPtpStat(MIPSState *mips, u32 structSize, u32 structAddr) { // Spams a lot - VERBOSE_LOG(Log::sceNet,"sceNetAdhocGetPtpStat(%08x, %08x) at %08x",structSize,structAddr,currentMIPS->pc); + VERBOSE_LOG(Log::sceNet,"sceNetAdhocGetPtpStat(%08x, %08x) at %08x",structSize,structAddr,mips->pc); s32_le *buflen = NULL; if (Memory::IsValidAddress(structSize)) buflen = (s32_le *)Memory::GetPointerOrException(structSize); @@ -4248,11 +4248,11 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { } // Invalid Arguments - return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_ARG, "invalid arg, at %08x", currentMIPS->pc); + return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_ARG, "invalid arg, at %08x", mips->pc); } // Library is uninitialized - return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_NOT_INITIALIZED, "not initialized, at %08x", currentMIPS->pc); + return hleLogVerbose(Log::sceNet, SCE_NET_ADHOC_ERROR_NOT_INITIALIZED, "not initialized, at %08x", mips->pc); } @@ -4427,8 +4427,8 @@ static int ptp_open_postoffice(const SceNetEtherAddr *saddr, uint16_t sport, con * @param flag Bitflags (Unused) * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT */ -static int sceNetAdhocPtpOpen(const char *srcmac, int sport, const char *dstmac, int dport, int bufsize, int rexmt_int, int rexmt_cnt, int flag) { - INFO_LOG(Log::sceNet, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac).c_str(), sport, mac2str((SceNetEtherAddr*)dstmac).c_str(),dport,bufsize, rexmt_int, rexmt_cnt, flag, currentMIPS->pc); +static int sceNetAdhocPtpOpen(MIPSState *mips, const char *srcmac, int sport, const char *dstmac, int dport, int bufsize, int rexmt_int, int rexmt_cnt, int flag) { + INFO_LOG(Log::sceNet, "sceNetAdhocPtpOpen(%s, %d, %s, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac).c_str(), sport, mac2str((SceNetEtherAddr*)dstmac).c_str(),dport,bufsize, rexmt_int, rexmt_cnt, flag, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -4724,7 +4724,7 @@ int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEther * @param flag Nonblocking Flag * @return Socket ID >= 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_LISTENED, ADHOC_THREAD_ABORTED, NET_INTERNAL */ -static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int timeout, int flag) { +static int sceNetAdhocPtpAccept(MIPSState *mips, int id, u32 peerMacAddrPtr, u32 peerPortPtr, int timeout, int flag) { SceNetEtherAddr * addr = NULL; if (Memory::IsValidAddress(peerMacAddrPtr)) { @@ -4735,9 +4735,9 @@ static int sceNetAdhocPtpAccept(int id, u32 peerMacAddrPtr, u32 peerPortPtr, int port = (uint16_t *)Memory::GetPointerOrException(peerPortPtr); } if (flag == 0) { // Prevent spamming Debug Log with retries of non-bocking socket - DEBUG_LOG(Log::sceNet, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr).c_str(), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + DEBUG_LOG(Log::sceNet, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr).c_str(), peerPortPtr, port ? *port : -1, timeout, flag, mips->pc); } else { - VERBOSE_LOG(Log::sceNet, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr).c_str(), peerPortPtr, port ? *port : -1, timeout, flag, currentMIPS->pc); + VERBOSE_LOG(Log::sceNet, "sceNetAdhocPtpAccept(%d, [%08x]=%s, [%08x]=%u, %d, %u) at %08x", id, peerMacAddrPtr, mac2str(addr).c_str(), peerPortPtr, port ? *port : -1, timeout, flag, mips->pc); } if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); @@ -4970,8 +4970,8 @@ int NetAdhocPtp_Connect(int id, int timeout, int flag, bool allowForcedConnect) * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_CONNECTION_REFUSED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_OPENED, ADHOC_THREAD_ABORTED, NET_INTERNAL */ -static int sceNetAdhocPtpConnect(int id, int timeout, int flag) { - INFO_LOG(Log::sceNet, "sceNetAdhocPtpConnect(%i, %i, %i) at %08x", id, timeout, flag, currentMIPS->pc); +static int sceNetAdhocPtpConnect(MIPSState *mips, int id, int timeout, int flag) { + INFO_LOG(Log::sceNet, "sceNetAdhocPtpConnect(%i, %i, %i) at %08x", id, timeout, flag, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -5050,8 +5050,8 @@ int NetAdhocPtp_Close(int id, int unknown) { * @param flag Bitflags (Unused) * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED */ -static int sceNetAdhocPtpClose(int id, int unknown) { - INFO_LOG(Log::sceNet,"sceNetAdhocPtpClose(%d,%d) at %08x",id,unknown,currentMIPS->pc); +static int sceNetAdhocPtpClose(MIPSState *mips, int id, int unknown) { + INFO_LOG(Log::sceNet,"sceNetAdhocPtpClose(%d,%d) at %08x",id,unknown,mips->pc); /*if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); }*/ @@ -5117,8 +5117,8 @@ static int ptp_listen_postoffice(const SceNetEtherAddr *saddr, uint16_t sport, u * @param flag Bitflags (Unused) * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_PORT_NOT_AVAIL, ADHOC_PORT_IN_USE, NET_NO_SPACE */ -static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int rexmt_int, int rexmt_cnt, int backlog, int flag) { - INFO_LOG(Log::sceNet, "sceNetAdhocPtpListen(%s, %d, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac).c_str(), sport,bufsize,rexmt_int,rexmt_cnt,backlog,flag, currentMIPS->pc); +static int sceNetAdhocPtpListen(MIPSState *mips, const char *srcmac, int sport, int bufsize, int rexmt_int, int rexmt_cnt, int backlog, int flag) { + INFO_LOG(Log::sceNet, "sceNetAdhocPtpListen(%s, %d, %d, %d, %d, %d, %d) at %08x", mac2str((SceNetEtherAddr*)srcmac).c_str(), sport,bufsize,rexmt_int,rexmt_cnt,backlog,flag, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -5303,8 +5303,8 @@ static int sceNetAdhocPtpListen(const char *srcmac, int sport, int bufsize, int * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_NOT_CONNECTED, ADHOC_THREAD_ABORTED, ADHOC_INVALID_DATALEN, ADHOC_DISCONNECTED, NET_INTERNAL, NET_NO_SPACE */ -static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeout, int flag) { - DEBUG_LOG(Log::sceNet, "sceNetAdhocPtpSend(%d,%08x,%08x,%d,%d) at %08x", id, dataAddr, dataSizeAddr, timeout, flag, currentMIPS->pc); +static int sceNetAdhocPtpSend(MIPSState *mips, int id, u32 dataAddr, u32 dataSizeAddr, int timeout, int flag) { + DEBUG_LOG(Log::sceNet, "sceNetAdhocPtpSend(%d,%08x,%08x,%d,%d) at %08x", id, dataAddr, dataSizeAddr, timeout, flag, mips->pc); int * len = (int *)Memory::GetPointerOrException(dataSizeAddr); const char * data = Memory::GetCharPointer(dataAddr); @@ -5423,8 +5423,8 @@ static int sceNetAdhocPtpSend(int id, u32 dataAddr, u32 dataSizeAddr, int timeou * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_DISCONNECTED, NET_INTERNAL */ -static int sceNetAdhocPtpRecv(int id, u32 dataAddr, u32 dataSizeAddr, int timeout, int flag) { - DEBUG_LOG(Log::sceNet, "sceNetAdhocPtpRecv(%d,%08x,%08x,%d,%d) at %08x", id, dataAddr, dataSizeAddr, timeout, flag, currentMIPS->pc); +static int sceNetAdhocPtpRecv(MIPSState *mips, int id, u32 dataAddr, u32 dataSizeAddr, int timeout, int flag) { + DEBUG_LOG(Log::sceNet, "sceNetAdhocPtpRecv(%d,%08x,%08x,%d,%d) at %08x", id, dataAddr, dataSizeAddr, timeout, flag, mips->pc); void * buf = (void *)Memory::GetPointerOrException(dataAddr); int * len = (int *)Memory::GetPointerOrException(dataSizeAddr); @@ -5578,8 +5578,8 @@ int FlushPtpSocket(int socketId) { * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_DISCONNECTED, ADHOC_NOT_CONNECTED, NET_INTERNAL */ -static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { - DEBUG_LOG(Log::sceNet,"sceNetAdhocPtpFlush(%d,%d,%d) at %08x", id, timeout, nonblock, currentMIPS->pc); +static int sceNetAdhocPtpFlush(MIPSState *mips, int id, int timeout, int nonblock) { + DEBUG_LOG(Log::sceNet,"sceNetAdhocPtpFlush(%d,%d,%d) at %08x", id, timeout, nonblock, mips->pc); // Library initialized if (netAdhocInited) { @@ -5638,8 +5638,8 @@ static int sceNetAdhocPtpFlush(int id, int timeout, int nonblock) { * * @return 0 on success, < 0 on error. */ -static int sceNetAdhocGameModeCreateMaster(u32 dataAddr, int size) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeCreateMaster(%08x, %i) at %08x", dataAddr, size, currentMIPS->pc); +static int sceNetAdhocGameModeCreateMaster(MIPSState *mips, u32 dataAddr, int size) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeCreateMaster(%08x, %i) at %08x", dataAddr, size, mips->pc); if (!netAdhocctlInited) return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); @@ -5691,8 +5691,8 @@ static int sceNetAdhocGameModeCreateMaster(u32 dataAddr, int size) { * * @return The id of the replica on success, < 0 on error. */ -static int sceNetAdhocGameModeCreateReplica(const char *mac, u32 dataAddr, int size) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), dataAddr, size, currentMIPS->pc); +static int sceNetAdhocGameModeCreateReplica(MIPSState *mips, const char *mac, u32 dataAddr, int size) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeCreateReplica(%s, %08x, %i) at %08x", mac2str((SceNetEtherAddr*)mac).c_str(), dataAddr, size, mips->pc); if (!netAdhocctlInited) return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); @@ -5745,8 +5745,8 @@ static int sceNetAdhocGameModeCreateReplica(const char *mac, u32 dataAddr, int s return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_NOT_CREATED, "not created"); } -static int sceNetAdhocGameModeUpdateMaster() { - DEBUG_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeUpdateMaster() at %08x", currentMIPS->pc); +static int sceNetAdhocGameModeUpdateMaster(MIPSState *mips) { + DEBUG_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeUpdateMaster() at %08x", mips->pc); if (!netAdhocctlInited) return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); @@ -5791,16 +5791,16 @@ int NetAdhocGameMode_DeleteMaster() { return 0; } -static int sceNetAdhocGameModeDeleteMaster() { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeDeleteMaster() at %08x", currentMIPS->pc); +static int sceNetAdhocGameModeDeleteMaster(MIPSState *mips) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeDeleteMaster() at %08x", mips->pc); if (isZeroMAC(&masterGameModeArea.mac)) return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_NOT_CREATED, "not created"); return NetAdhocGameMode_DeleteMaster(); } -static int sceNetAdhocGameModeUpdateReplica(int id, u32 infoAddr) { - DEBUG_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeUpdateReplica(%i, %08x) at %08x", id, infoAddr, currentMIPS->pc); +static int sceNetAdhocGameModeUpdateReplica(MIPSState *mips, int id, u32 infoAddr) { + DEBUG_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeUpdateReplica(%i, %08x) at %08x", id, infoAddr, mips->pc); if (!netAdhocctlInited) return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); @@ -5848,8 +5848,8 @@ static int sceNetAdhocGameModeUpdateReplica(int id, u32 infoAddr) { return hleLogDebug(Log::sceNet, 0); } -static int sceNetAdhocGameModeDeleteReplica(int id) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeDeleteReplica(%i) at %08x", id, currentMIPS->pc); +static int sceNetAdhocGameModeDeleteReplica(MIPSState *mips, int id) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocGameModeDeleteReplica(%i) at %08x", id, mips->pc); auto it = std::find_if(replicaGameModeAreas.begin(), replicaGameModeAreas.end(), [id](GameModeArea const& e) { return e.id == id; @@ -5874,8 +5874,8 @@ static int sceNetAdhocGameModeDeleteReplica(int id) { return hleLogDebug(Log::sceNet, 0); } -int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) { - WARN_LOG_REPORT_ONCE(sceNetAdhocGetSocketAlert, Log::sceNet, "UNTESTED sceNetAdhocGetSocketAlert(%i, %08x) at %08x", id, flagPtr, currentMIPS->pc); +int sceNetAdhocGetSocketAlert(MIPSState *mips, int id, u32 flagPtr) { + WARN_LOG_REPORT_ONCE(sceNetAdhocGetSocketAlert, Log::sceNet, "UNTESTED sceNetAdhocGetSocketAlert(%i, %08x) at %08x", id, flagPtr, mips->pc); if (!Memory::IsValidAddress(flagPtr)) return hleLogDebug(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_ARG, "invalid arg"); @@ -6024,8 +6024,8 @@ int NetAdhocctl_ExitGameMode() { return NetAdhocctl_Disconnect(); } -static int sceNetAdhocctlExitGameMode() { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocctlExitGameMode() at %08x", currentMIPS->pc); +static int sceNetAdhocctlExitGameMode(MIPSState *mips) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocctlExitGameMode() at %08x", mips->pc); return NetAdhocctl_ExitGameMode(); } @@ -6053,7 +6053,7 @@ static int sceNetAdhocctlGetGameModeInfo(u32 infoAddr) { return 0; } -static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { +static int sceNetAdhocctlGetPeerList(MIPSState *mips, u32 sizeAddr, u32 bufAddr) { s32_le *buflen = NULL; if (Memory::IsValidAddress(sizeAddr)) { buflen = (s32_le *)Memory::GetPointerOrException(sizeAddr); @@ -6063,7 +6063,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { buf = (SceNetAdhocctlPeerInfoEmu *)Memory::GetPointerOrException(bufAddr); } - DEBUG_LOG(Log::sceNet, "sceNetAdhocctlGetPeerList([%08x]=%i, %08x) at %08x", sizeAddr, /*buflen ? *buflen : -1*/Memory::ReadUnchecked_U32(sizeAddr), bufAddr, currentMIPS->pc); + DEBUG_LOG(Log::sceNet, "sceNetAdhocctlGetPeerList([%08x]=%i, %08x) at %08x", sizeAddr, /*buflen ? *buflen : -1*/Memory::ReadUnchecked_U32(sizeAddr), bufAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -6151,7 +6151,7 @@ static int sceNetAdhocctlGetPeerList(u32 sizeAddr, u32 bufAddr) { return hleLogDebug(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_INITIALIZED, "not initialized"); } -static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 bufAddr) { +static int sceNetAdhocctlGetAddrByName(MIPSState *mips, const char *nickName, u32 sizeAddr, u32 bufAddr) { s32_le *buflen = NULL; //int32_t if (Memory::IsValidAddress(sizeAddr)) buflen = (s32_le *)Memory::GetPointerOrException(sizeAddr); @@ -6163,7 +6163,7 @@ static int sceNetAdhocctlGetAddrByName(const char *nickName, u32 sizeAddr, u32 b memcpy(nckName, nickName, ADHOCCTL_NICKNAME_LEN); // Copied to null-terminated var to prevent unexpected behaviour on Logs nckName[ADHOCCTL_NICKNAME_LEN - 1] = 0; - WARN_LOG_REPORT_ONCE(sceNetAdhocctlGetAddrByName, Log::sceNet, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%d/%zu, %08x) at %08x", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr, currentMIPS->pc); + WARN_LOG_REPORT_ONCE(sceNetAdhocctlGetAddrByName, Log::sceNet, "UNTESTED sceNetAdhocctlGetAddrByName(%s, [%08x]=%d/%zu, %08x) at %08x", nckName, sizeAddr, buflen ? *buflen : -1, sizeof(SceNetAdhocctlPeerInfoEmu), bufAddr, mips->pc); // Library initialized if (netAdhocctlInited) @@ -6296,10 +6296,10 @@ const HLEFunction sceNetAdhocctl[] = { }; // Return value: 0/0x80410005/0x80411301/error returned from sceNetAdhocctl_lib_F8BABD85[/error returned from sceUtilityGetSystemParamInt?] -int sceNetAdhocDiscoverInitStart(u32 paramAddr) { - WARN_LOG_REPORT_ONCE(sceNetAdhocDiscoverInitStart, Log::sceNet, "UNIMPL sceNetAdhocDiscoverInitStart(%08x) at %08x", paramAddr, currentMIPS->pc); +int sceNetAdhocDiscoverInitStart(MIPSState *mips, u32 paramAddr) { + WARN_LOG_REPORT_ONCE(sceNetAdhocDiscoverInitStart, Log::sceNet, "UNIMPL sceNetAdhocDiscoverInitStart(%08x) at %08x", paramAddr, mips->pc); // FIXME: Most AdhocDiscover syscalls will return 0x80410005 if (sceKernelCheckThreadStack_user() < 0x00000FE0), AdhocDiscover seems to be storing some data in the stack, while we use global variables for these - if (sceKernelCheckThreadStack() < 0x00000FE0) + if (sceKernelCheckThreadStack(mips) < 0x00000FE0) return 0x80410005; // TODO: Allocate internal buffer/struct (on the stack?) to be returned on sceNetAdhocDiscoverUpdate (the struct may contains WLAN channel from sceUtilityGetSystemParamInt at offset 0xA0 ?), setup adhocctl state callback handler to detects state change (using sceNetAdhocctl_lib_F8BABD85(stateCallbackFunction=0x09F436F8, adhocctlStateCallbackArg=0x0) on JPCSP+prx) u32 bufSize = 256; // dummy size, not sure how large it supposed to be, may be at least 0x3c bytes like in param->unknown2 ? @@ -6363,9 +6363,9 @@ int sceNetAdhocDiscoverInitStart(u32 paramAddr) { // Note1: When canceling the progress, Legend Of The Dragon will use DiscoverStop -> AdhocctlDisconnect -> DiscoverTerm (when status changed to 2) // Note2: When result = NO_PEER_FOUND or PEER_FOUND the progress can no longer be canceled on Legend Of The Dragon -int sceNetAdhocDiscoverStop() { +int sceNetAdhocDiscoverStop(MIPSState *mips) { WARN_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverStop()"); - if (sceKernelCheckThreadStack() < 0x00000FF0) + if (sceKernelCheckThreadStack(mips) < 0x00000FF0) return 0x80410005; if (Memory::IsValid4AlignedRange(netAdhocDiscoverBufAddr, 256)) { @@ -6381,10 +6381,10 @@ int sceNetAdhocDiscoverStop() { return 0; } -int sceNetAdhocDiscoverTerm() { - WARN_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverTerm() at %08x", currentMIPS->pc); +int sceNetAdhocDiscoverTerm(MIPSState *mips) { + WARN_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverTerm() at %08x", mips->pc); - // if (sceKernelCheckThreadStack() < 0x00000FF0) + // if (sceKernelCheckThreadStack(mips) < 0x00000FF0) // return 0x80410005; // // if (!(Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) > 0 && (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) ^ 0x13) > 0)) @@ -6408,9 +6408,9 @@ int sceNetAdhocDiscoverTerm() { return 0; } -int sceNetAdhocDiscoverGetStatus() { - DEBUG_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverGetStatus() at %08x", currentMIPS->pc); - if (sceKernelCheckThreadStack() < 0x00000FF0) +int sceNetAdhocDiscoverGetStatus(MIPSState *mips) { + DEBUG_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverGetStatus() at %08x", mips->pc); + if (sceKernelCheckThreadStack(mips) < 0x00000FF0) return 0x80410005; // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) <= 0) // return 0; @@ -6421,11 +6421,11 @@ int sceNetAdhocDiscoverGetStatus() { return hleLogDebug(Log::sceNet, netAdhocDiscoverStatus); // Returning 2 will trigger Legend Of The Dragon to call sceNetAdhocctlGetPeerList (only happened if it was the first sceNetAdhocDiscoverGetStatus after sceNetAdhocDiscoverInitStart) } -int sceNetAdhocDiscoverRequestSuspend() +int sceNetAdhocDiscoverRequestSuspend(MIPSState *mips) { - ERROR_LOG_REPORT_ONCE(sceNetAdhocDiscoverRequestSuspend, Log::sceNet, "UNIMPL sceNetAdhocDiscoverRequestSuspend() at %08x", currentMIPS->pc); + ERROR_LOG_REPORT_ONCE(sceNetAdhocDiscoverRequestSuspend, Log::sceNet, "UNIMPL sceNetAdhocDiscoverRequestSuspend() at %08x", mips->pc); // FIXME: Not sure what is this syscall used for, may be related to Sleep Mode and can be triggered by using Power/Hold Switch? (based on what's written on Dissidia 012) - if (sceKernelCheckThreadStack() < 0x00000FF0) + if (sceKernelCheckThreadStack(mips) < 0x00000FF0) return 0x80410005; // if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0xA4) == 0) // return 0x80411303; // Already Suspended? @@ -6440,9 +6440,9 @@ int sceNetAdhocDiscoverRequestSuspend() return hleLogError(Log::sceNet, 0); } -int sceNetAdhocDiscoverUpdate() { - DEBUG_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverUpdate() at %08x", currentMIPS->pc); - if (sceKernelCheckThreadStack() < 0x00000FF0) +int sceNetAdhocDiscoverUpdate(MIPSState *mips) { + DEBUG_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverUpdate() at %08x", mips->pc); + if (sceKernelCheckThreadStack(mips) < 0x00000FF0) return 0x80410005; // TODO: Use switch case for each Step diff --git a/Core/HLE/sceNetAdhoc.h b/Core/HLE/sceNetAdhoc.h index ed627206a7..0cac5e236c 100644 --- a/Core/HLE/sceNetAdhoc.h +++ b/Core/HLE/sceNetAdhoc.h @@ -149,13 +149,13 @@ bool __NetAdhocConnected(); // Called from netdialog (and from sceNetApctl) // NOTE: use hleCall for sceNet* ones! int sceNetAdhocctlGetState(u32 ptrToStatus); -int sceNetAdhocctlCreate(const char * groupName); -int sceNetAdhocctlConnect(const char* groupName); -int sceNetAdhocctlJoin(u32 scanInfoAddr); -int sceNetAdhocctlScan(); -int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr); +int sceNetAdhocctlCreate(MIPSState *mips, const char * groupName); +int sceNetAdhocctlConnect(MIPSState *mips, const char* groupName); +int sceNetAdhocctlJoin(MIPSState *mips, u32 scanInfoAddr); +int sceNetAdhocctlScan(MIPSState *mips); +int sceNetAdhocctlGetScanInfo(MIPSState *mips, u32 sizeAddr, u32 bufAddr); int sceNetAdhocctlDisconnect(); -int sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr); +int sceNetAdhocctlInit(MIPSState *mips, int stackSize, int prio, u32 productAddr); int sceNetAdhocctlTerm(); int NetAdhocctl_Term(); @@ -173,9 +173,9 @@ extern s32 netAdhocDiscoverStatus; // TODO: maybe move to sceNetAdhocDiscover? // Exposing those for the matching routines // NOTE: use hleCall for sceNet* ones! -int sceNetAdhocPdpSend(int id, const char* mac, u32 port, void* data, int len, int timeout, int flag); -int sceNetAdhocPdpRecv(int id, void* addr, void* port, void* buf, void* dataLength, u32 timeout, int flag); -int sceNetAdhocPdpCreate(const char* mac, int port, int bufferSize, u32 flag); +int sceNetAdhocPdpSend(MIPSState *mips, int id, const char* mac, u32 port, void* data, int len, int timeout, int flag); +int sceNetAdhocPdpRecv(MIPSState *mips, int id, void* addr, void* port, void* buf, void* dataLength, u32 timeout, int flag); +int sceNetAdhocPdpCreate(MIPSState *mips, const char* mac, int port, int bufferSize, u32 flag); int NetAdhoc_SetSocketAlert(int id, s32_le flag); int NetAdhocPdp_Delete(int id, int unknown); diff --git a/Core/HLE/sceNetAdhocMatching.cpp b/Core/HLE/sceNetAdhocMatching.cpp index b28bad96d3..94801d55ae 100644 --- a/Core/HLE/sceNetAdhocMatching.cpp +++ b/Core/HLE/sceNetAdhocMatching.cpp @@ -142,7 +142,7 @@ void broadcastPingMessage(SceNetAdhocMatchingContext * context) { port = it->second; context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)&peer->mac_addr, port, &ping, (u32)sizeof(ping), 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)&peer->mac_addr, port, &ping, (u32)sizeof(ping), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } } @@ -200,7 +200,7 @@ void broadcastHelloMessage(SceNetAdhocMatchingContext * context) { port = it->second; context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)&peer->mac_addr, port, hello, 5 + context->hellolen, 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)&peer->mac_addr, port, hello, 5 + context->hellolen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } peerlock.unlock(); @@ -278,7 +278,7 @@ void sendAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma // Send Data context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)mac, (*context->peerPort)[*mac], accept, 9 + optlen + siblingbuflen, 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)mac, (*context->peerPort)[*mac], accept, 9 + optlen + siblingbuflen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); // Free Memory @@ -326,7 +326,7 @@ void sendJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, // Send Data context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)mac, (*context->peerPort)[*mac], join, 5 + optlen, 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)mac, (*context->peerPort)[*mac], join, 5 + optlen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); // Free Memory @@ -360,7 +360,7 @@ void sendCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * ma // Send Data context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)mac, (*context->peerPort)[*mac], cancel, 5 + optlen, 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)mac, (*context->peerPort)[*mac], cancel, 5 + optlen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); // Free Memory @@ -429,7 +429,7 @@ void sendBulkDataPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * // Send Data context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)mac, (*context->peerPort)[*mac], send, 5 + datalen, 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)mac, (*context->peerPort)[*mac], send, 5 + datalen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); // Free Memory @@ -481,7 +481,7 @@ void sendBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac // Send Packet context->socketlock->lock(); - int sent = hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, (u32)sizeof(packet), 0, ADHOC_F_NONBLOCK); + int sent = hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, (u32)sizeof(packet), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); // Log Send Success @@ -525,7 +525,7 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac // Send Bye Packet context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, (u32)sizeof(packet[0]), 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, (u32)sizeof(packet[0]), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } else { @@ -536,7 +536,7 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac // Send Death Packet context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, (u32)sizeof(packet), 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], packet, (u32)sizeof(packet), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } } @@ -564,7 +564,7 @@ void sendByePacket(SceNetAdhocMatchingContext * context) { // Send Bye Packet context->socketlock->lock(); - hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], &opcode, (u32)sizeof(opcode), 0, ADHOC_F_NONBLOCK); + hleCall(sceNetAdhoc, int, sceNetAdhocPdpSend, currentMIPS, context->socket, (const char*)&peer->mac, (*context->peerPort)[peer->mac], &opcode, (u32)sizeof(opcode), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } } @@ -1395,7 +1395,7 @@ int matchingInputThread(int matchingId) { // TODO: The MatchingInput thread is u // Lock the peer first before locking the socket to avoid race condiion peerlock.lock(); context->socketlock->lock(); - int recvresult = sceNetAdhocPdpRecv(context->socket, &sendermac, &senderport, context->rxbuf, &rxbuflen, 0, ADHOC_F_NONBLOCK); + int recvresult = sceNetAdhocPdpRecv(currentMIPS, context->socket, &sendermac, &senderport, context->rxbuf, &rxbuflen, 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); peerlock.unlock(); @@ -1607,8 +1607,8 @@ int NetAdhocMatching_Stop(int matchingId) { return 0; } -int sceNetAdhocMatchingStop(int matchingId) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingStop(%i) at %08x", matchingId, currentMIPS->pc); +int sceNetAdhocMatchingStop(MIPSState *mips, int matchingId) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingStop(%i) at %08x", matchingId, mips->pc); return NetAdhocMatching_Stop(matchingId); } @@ -1678,20 +1678,20 @@ int NetAdhocMatching_Delete(int matchingId) { return 0; } -int sceNetAdhocMatchingDelete(int matchingId) { +int sceNetAdhocMatchingDelete(MIPSState *mips, int matchingId) { // WLAN might be disabled in the middle of successfull multiplayer, but we still need to cleanup right? NetAdhocMatching_Delete(matchingId); - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingDelete(%i) at %08x", matchingId, currentMIPS->pc); + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingDelete(%i) at %08x", matchingId, mips->pc); // Give a little time to make sure everything are cleaned up before the following AdhocMatchingCreate, Not too long tho, otherwise Naruto Ultimate Ninja Heroes 3 will have an issue //hleDelayResult(0, "give time to init/cleanup", adhocExtraPollDelayMS * 1000); return 0; } -int sceNetAdhocMatchingInit(u32 memsize) { - WARN_LOG_REPORT_ONCE(sceNetAdhocMatchingInit, Log::sceNet, "sceNetAdhocMatchingInit(%d) at %08x", memsize, currentMIPS->pc); +int sceNetAdhocMatchingInit(MIPSState *mips, u32 memsize) { + WARN_LOG_REPORT_ONCE(sceNetAdhocMatchingInit, Log::sceNet, "sceNetAdhocMatchingInit(%d) at %08x", memsize, mips->pc); // Uninitialized Library if (netAdhocMatchingInited) @@ -1726,8 +1726,8 @@ int NetAdhocMatching_Term() { return 0; } -int sceNetAdhocMatchingTerm() { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingTerm() at %08x", currentMIPS->pc); +int sceNetAdhocMatchingTerm(MIPSState *mips) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingTerm() at %08x", mips->pc); // Should we cleanup all created matching contexts first? just in case there are games that doesn't delete them before calling this NetAdhocMatching_Term(); @@ -1737,8 +1737,8 @@ int sceNetAdhocMatchingTerm() { // Presumably returns a "matchingId". -static int sceNetAdhocMatchingCreate(int mode, int maxnum, int port, int rxbuflen, int hello_int, int keepalive_int, int init_count, int rexmt_int, u32 callbackAddr) { - WARN_LOG(Log::sceNet, "sceNetAdhocMatchingCreate(mode=%i, maxnum=%i, port=%i, rxbuflen=%i, hello=%i, keepalive=%i, initcount=%i, rexmt=%i, callbackAddr=%08x) at %08x", mode, maxnum, port, rxbuflen, hello_int, keepalive_int, init_count, rexmt_int, callbackAddr, currentMIPS->pc); +static int sceNetAdhocMatchingCreate(MIPSState *mips, int mode, int maxnum, int port, int rxbuflen, int hello_int, int keepalive_int, int init_count, int rexmt_int, u32 callbackAddr) { + WARN_LOG(Log::sceNet, "sceNetAdhocMatchingCreate(mode=%i, maxnum=%i, port=%i, rxbuflen=%i, hello=%i, keepalive=%i, initcount=%i, rexmt=%i, callbackAddr=%08x) at %08x", mode, maxnum, port, rxbuflen, hello_int, keepalive_int, init_count, rexmt_int, callbackAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -1875,7 +1875,7 @@ int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int //else return SCE_NET_ADHOC_MATCHING_ERROR_INVALID_ARG; // SCE_NET_ADHOC_MATCHING_ERROR_INVALID_OPTLEN; // Returning Not Success will cause GTA:VC stuck unable to choose host/join menu // Create PDP Socket - int sock = hleCall(sceNetAdhoc, int, sceNetAdhocPdpCreate, (const char*)&item->mac, static_cast(item->port), item->rxbuflen, 0); + int sock = hleCall(sceNetAdhoc, int, sceNetAdhocPdpCreate, currentMIPS, (const char*)&item->mac, static_cast(item->port), item->rxbuflen, 0); item->socket = sock; if (sock < 1) { return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_PORT_IN_USE, "adhoc matching port in use"); @@ -1909,8 +1909,8 @@ int NetAdhocMatching_Start(int matchingId, int evthPri, int evthPartitionId, int // This should be similar with sceNetAdhocMatchingStart2 but using USER_PARTITION_ID (2) for PartitionId params // (KERNEL_PARTITION_ID/USER_PARTITION_ID/VSHELL_PARTITION_ID come from Core/HLE/sceKernelMemory.h) -static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, int inthPri, int inthStack, int optLen, u32 optDataAddr) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingStart(%i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthStack, inthPri, inthStack, optLen, optDataAddr, currentMIPS->pc); +static int sceNetAdhocMatchingStart(MIPSState *mips, int matchingId, int evthPri, int evthStack, int inthPri, int inthStack, int optLen, u32 optDataAddr) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingStart(%i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthStack, inthPri, inthStack, optLen, optDataAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -1922,8 +1922,8 @@ static int sceNetAdhocMatchingStart(int matchingId, int evthPri, int evthStack, } // With params for Partition ID for the event & input handler stack -static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartitionId, int evthStack, int inthPri, int inthPartitionId, int inthStack, int optLen, u32 optDataAddr) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingStart2(%i, %i, %i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthPartitionId, evthStack, inthPri, inthPartitionId, inthStack, optLen, optDataAddr, currentMIPS->pc); +static int sceNetAdhocMatchingStart2(MIPSState *mips, int matchingId, int evthPri, int evthPartitionId, int evthStack, int inthPri, int inthPartitionId, int inthStack, int optLen, u32 optDataAddr) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingStart2(%i, %i, %i, %i, %i, %i, %i, %i, %08x) at %08x", matchingId, evthPri, evthPartitionId, evthStack, inthPri, inthPartitionId, inthStack, optLen, optDataAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -1934,8 +1934,8 @@ static int sceNetAdhocMatchingStart2(int matchingId, int evthPri, int evthPartit return retval; } -static int sceNetAdhocMatchingSelectTarget(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, currentMIPS->pc); +static int sceNetAdhocMatchingSelectTarget(MIPSState *mips, int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingSelectTarget(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -2141,8 +2141,8 @@ int NetAdhocMatching_CancelTargetWithOpt(int matchingId, const char* macAddress, return hleLogDebug(Log::sceNet, 0); } -int sceNetAdhocMatchingCancelTargetWithOpt(int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingCancelTargetWithOpt(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, currentMIPS->pc); +int sceNetAdhocMatchingCancelTargetWithOpt(MIPSState *mips, int matchingId, const char *macAddress, int optLen, u32 optDataPtr) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingCancelTargetWithOpt(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)macAddress).c_str(), optLen, optDataPtr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } @@ -2455,8 +2455,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) } // Gran Turismo may replace the 1st bit of the 1st byte of MAC address's OUI with 0 (unicast bit), or replace the whole 6-bytes of MAC address with all 00 (invalid mac) for unknown reason -int sceNetAdhocMatchingSendData(int matchingId, const char *mac, int dataLen, u32 dataAddr) { - WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)mac).c_str(), dataLen, dataAddr, currentMIPS->pc); +int sceNetAdhocMatchingSendData(MIPSState *mips, int matchingId, const char *mac, int dataLen, u32 dataAddr) { + WARN_LOG(Log::sceNet, "UNTESTED sceNetAdhocMatchingSendData(%i, %s, %i, %08x) at %08x", matchingId, mac2str((SceNetEtherAddr*)mac).c_str(), dataLen, dataAddr, mips->pc); if (!g_Config.bEnableWlan) { return hleLogError(Log::sceNet, -1, "WLAN off"); } diff --git a/Core/HLE/sceNetInet.cpp b/Core/HLE/sceNetInet.cpp index 6cfe232621..3018ba868f 100644 --- a/Core/HLE/sceNetInet.cpp +++ b/Core/HLE/sceNetInet.cpp @@ -82,23 +82,23 @@ static int sceNetInetTerm() { return hleLogDebug(Log::sceNet, 0); } -static int sceNetInetGetErrno() { +static int sceNetInetGetErrno(MIPSState *mips) { int threadID = __KernelGetCurThread(); const int lastErrno = g_inetLastErrno[threadID]; if (lastErrno == ERROR_INET_EAGAIN) { - return hleLogVerbose(Log::sceNet, lastErrno, "returning %s at %08x", convertInetErrno2str(lastErrno), currentMIPS->pc); + return hleLogVerbose(Log::sceNet, lastErrno, "returning %s at %08x", convertInetErrno2str(lastErrno), mips->pc); } else { - return hleLogDebug(Log::sceNet, lastErrno, "returning %s at %08x", convertInetErrno2str(lastErrno), currentMIPS->pc); + return hleLogDebug(Log::sceNet, lastErrno, "returning %s at %08x", convertInetErrno2str(lastErrno), mips->pc); } } -static int sceNetInetGetPspError() { +static int sceNetInetGetPspError(MIPSState *mips) { int threadID = __KernelGetCurThread(); const int lastErrno = g_inetLastErrno[threadID]; uint32_t error = convertInetErrno2PSPError(lastErrno); - return hleLogInfo(Log::sceNet, error, "returning %s converted to %08x at %08x", convertInetErrno2str(lastErrno), error, currentMIPS->pc); + return hleLogInfo(Log::sceNet, error, "returning %s converted to %08x at %08x", convertInetErrno2str(lastErrno), error, mips->pc); } static int sceNetInetInetPton(int af, const char* hostname, u32 inAddrPtr) { @@ -353,8 +353,8 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr return hleDelayResult(hleLogDebug(Log::sceNet, retval), "workaround until blocking-socket", 500); // Using hleDelayResult as a workaround for games that need blocking-socket to be implemented (ie. Coded Arms Contagion) } -int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout) { // timeout in miliseconds just like posix poll? or in microseconds as other PSP timeout? - DEBUG_LOG(Log::sceNet, "UNTESTED sceNetInetPoll(%08x, %d, %i) at %08x", fdsPtr, nfds, timeout, currentMIPS->pc); +int sceNetInetPoll(MIPSState *mips, u32 fdsPtr, u32 nfds, int timeout) { // timeout in miliseconds just like posix poll? or in microseconds as other PSP timeout? + DEBUG_LOG(Log::sceNet, "UNTESTED sceNetInetPoll(%08x, %d, %i) at %08x", fdsPtr, nfds, timeout, mips->pc); int retval = -1; int maxHostFd = 0; SceNetInetPollfd *fdarray = (SceNetInetPollfd*)Memory::GetPointerOrException(fdsPtr); // SceNetInetPollfd/pollfd, sceNetInetPoll() have similarity to BSD poll() but pollfd have different size on 64bit @@ -456,9 +456,9 @@ static int sceNetInetSend(int socket, u32 bufPtr, u32 bufLen, u32 flags) { return hleLogInfo(Log::sceNet, retval); } -static int sceNetInetSocket(int domain, int type, int protocol) { +static int sceNetInetSocket(MIPSState *mips, int domain, int type, int protocol) { INFO_LOG(Log::sceNet, "sceNetInetSocket(%d, %d, %d) at %08x - Socket: Domain = %s, Type = %s, Protocol = %s", - domain, type, protocol, currentMIPS->pc, inetSocketDomain2str(domain).c_str(), inetSocketType2str(type).c_str(), inetSocketProto2str(protocol).c_str()); + domain, type, protocol, mips->pc, inetSocketDomain2str(domain).c_str(), inetSocketType2str(type).c_str(), inetSocketProto2str(protocol).c_str()); int socket; int hostErrno = 0; @@ -479,7 +479,7 @@ static int sceNetInetSocket(int domain, int type, int protocol) { return hleLogDebug(Log::sceNet, socket); } -static int sceNetInetSetsockopt(int socket, int level, int optname, u32 optvalPtr, int optlen) { +static int sceNetInetSetsockopt(MIPSState *mips, int socket, int level, int optname, u32 optvalPtr, int optlen) { InetSocket *inetSock; if (!g_socketManager.GetInetSocket(socket, &inetSock)) { return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket); @@ -487,7 +487,7 @@ static int sceNetInetSetsockopt(int socket, int level, int optname, u32 optvalPt const u32 optval = Memory::IsValid4AlignedAddress(optvalPtr) ? Memory::ReadUnchecked_U32(optvalPtr) : 0; INFO_LOG(Log::sceNet, "sceNetInetSetsockopt(%i, %i, %i, %08x, %i) at %08x: Level = %s, OptName = %s, OptValue = %d", - socket, level, optname, optvalPtr, optlen, currentMIPS->pc, + socket, level, optname, optvalPtr, optlen, mips->pc, inetSockoptLevel2str(level).c_str(), inetSockoptName2str(optname, level).c_str(), optval); timeval tval{}; @@ -553,8 +553,8 @@ static int sceNetInetSetsockopt(int socket, int level, int optname, u32 optvalPt return hleLogDebug(Log::sceNet, retval); } -static int sceNetInetGetsockopt(int socket, int level, int optname, u32 optvalPtr, u32 optlenPtr) { - WARN_LOG(Log::sceNet, "sceNetInetGetsockopt(%i, %i, %i, %08x, %08x) at %08x", socket, level, optname, optvalPtr, optlenPtr, currentMIPS->pc); +static int sceNetInetGetsockopt(MIPSState *mips, int socket, int level, int optname, u32 optvalPtr, u32 optlenPtr) { + WARN_LOG(Log::sceNet, "sceNetInetGetsockopt(%i, %i, %i, %08x, %08x) at %08x", socket, level, optname, optvalPtr, optlenPtr, mips->pc); InetSocket *inetSock; if (!g_socketManager.GetInetSocket(socket, &inetSock)) { @@ -618,8 +618,8 @@ static int sceNetInetGetsockopt(int socket, int level, int optname, u32 optvalPt return hleLogDebug(Log::sceNet, retval); } -static int sceNetInetBind(int socket, u32 namePtr, int namelen) { - INFO_LOG(Log::sceNet, "sceNetInetBind(%i, %08x, %i) at %08x", socket, namePtr, namelen, currentMIPS->pc); +static int sceNetInetBind(MIPSState *mips, int socket, u32 namePtr, int namelen) { + INFO_LOG(Log::sceNet, "sceNetInetBind(%i, %08x, %i) at %08x", socket, namePtr, namelen, mips->pc); InetSocket *inetSock; if (!g_socketManager.GetInetSocket(socket, &inetSock)) { @@ -1162,8 +1162,8 @@ static int sceNetInetSendmsg(int socket, u32 msghdrPtr, int flags) { // Similar to POSIX's recvmsg or Mswsock's WSARecvMsg? Are their packets compatible one another? // Games using this: World of Poker -static int sceNetInetRecvmsg(int socket, u32 msghdrPtr, int flags) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%i, %08x, %08x) at %08x", __FUNCTION__, socket, msghdrPtr, flags, currentMIPS->pc); +static int sceNetInetRecvmsg(MIPSState *mips, int socket, u32 msghdrPtr, int flags) { + ERROR_LOG(Log::sceNet, "UNIMPL %s(%i, %08x, %08x) at %08x", __FUNCTION__, socket, msghdrPtr, flags, mips->pc); InetSocket *inetSock; if (!g_socketManager.GetInetSocket(socket, &inetSock)) { diff --git a/Core/HLE/sceNetInet.h b/Core/HLE/sceNetInet.h index f565776887..a00d36fa51 100644 --- a/Core/HLE/sceNetInet.h +++ b/Core/HLE/sceNetInet.h @@ -129,6 +129,6 @@ void __NetInetShutdown(); int NetApctl_GetState(); -int sceNetApctlConnect(int connIndex); -int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout); +int sceNetApctlConnect(MIPSState *mips, int connIndex); +int sceNetInetPoll(MIPSState *mips, u32 fdsPtr, u32 nfds, int timeout); int sceNetApctlDisconnect(); diff --git a/Core/HLE/sceNp2.cpp b/Core/HLE/sceNp2.cpp index 48cc7d851e..b6059cbaea 100644 --- a/Core/HLE/sceNp2.cpp +++ b/Core/HLE/sceNp2.cpp @@ -80,9 +80,9 @@ bool NpMatching2ProcessEvents() { return true; } -static int sceNpMatching2Init(int poolSize, int threadPriority, int cpuAffinityMask, int threadStackSize) +static int sceNpMatching2Init(MIPSState *mips, int poolSize, int threadPriority, int cpuAffinityMask, int threadStackSize) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%d, %d, %d, %d) at %08x", __FUNCTION__, poolSize, threadPriority, cpuAffinityMask, threadStackSize, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%d, %d, %d, %d) at %08x", __FUNCTION__, poolSize, threadPriority, cpuAffinityMask, threadStackSize, mips->pc); //if (npMatching2Inited) // return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_ALREADY_INITIALIZED); @@ -96,9 +96,9 @@ static int sceNpMatching2Init(int poolSize, int threadPriority, int cpuAffinityM return 0; } -static int sceNpMatching2Term() +static int sceNpMatching2Term(MIPSState *mips) { - ERROR_LOG(Log::sceNet, "UNIMPL %s() at %08x", __FUNCTION__, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s() at %08x", __FUNCTION__, mips->pc); npMatching2Inited = false; npMatching2Handlers.clear(); npMatching2Events.clear(); @@ -141,9 +141,9 @@ static int sceNpMatching2CreateContext(u32 communicationIdPtr, u32 passPhrasePtr return hleLogError(Log::sceNet, 0, "UNIMPL"); } -static int sceNpMatching2ContextStart(int ctxId) +static int sceNpMatching2ContextStart(MIPSState *mips, int ctxId) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%d) at %08x", __FUNCTION__, ctxId, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%d) at %08x", __FUNCTION__, ctxId, mips->pc); if (!npMatching2Inited) return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); @@ -261,9 +261,9 @@ static int sceNpMatching2ContextStart(int ctxId) return 0; } -static int sceNpMatching2ContextStop(int ctxId) +static int sceNpMatching2ContextStop(MIPSState *mips, int ctxId) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%d) at %08x", __FUNCTION__, ctxId, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%d) at %08x", __FUNCTION__, ctxId, mips->pc); if (!npMatching2Inited) return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); @@ -279,9 +279,9 @@ static int sceNpMatching2ContextStop(int ctxId) return 0; } -static int sceNpMatching2DestroyContext(int ctxId) +static int sceNpMatching2DestroyContext(MIPSState *mips, int ctxId) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%d) at %08x", __FUNCTION__, ctxId, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%d) at %08x", __FUNCTION__, ctxId, mips->pc); if (!npMatching2Inited) return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); @@ -301,9 +301,9 @@ static int sceNpMatching2DestroyContext(int ctxId) return 0; } -static int sceNpMatching2GetMemoryStat(u32 memStatPtr) +static int sceNpMatching2GetMemoryStat(MIPSState *mips, u32 memStatPtr) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%08x) at %08x", __FUNCTION__, memStatPtr, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%08x) at %08x", __FUNCTION__, memStatPtr, mips->pc); if (!npMatching2Inited) return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); @@ -317,9 +317,9 @@ static int sceNpMatching2GetMemoryStat(u32 memStatPtr) return 0; } -static int sceNpMatching2RegisterSignalingCallback(int ctxId, u32 callbackFunctionAddr, u32 callbackArgument) +static int sceNpMatching2RegisterSignalingCallback(MIPSState *mips, int ctxId, u32 callbackFunctionAddr, u32 callbackArgument) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%d, %08x, %08x) at %08x", __FUNCTION__, ctxId, callbackFunctionAddr, callbackArgument, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%d, %08x, %08x) at %08x", __FUNCTION__, ctxId, callbackFunctionAddr, callbackArgument, mips->pc); if (!npMatching2Inited) return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); @@ -361,9 +361,9 @@ static int sceNpMatching2RegisterSignalingCallback(int ctxId, u32 callbackFuncti return 0; } -static int sceNpMatching2GetServerIdListLocal(int ctxId, u32 serverIdsPtr, int maxServerIds) +static int sceNpMatching2GetServerIdListLocal(MIPSState *mips, int ctxId, u32 serverIdsPtr, int maxServerIds) { - ERROR_LOG(Log::sceNet, "UNIMPL %s(%d, %08x, %d) at %08x", __FUNCTION__, ctxId, serverIdsPtr, maxServerIds, currentMIPS->pc); + ERROR_LOG(Log::sceNet, "UNIMPL %s(%d, %08x, %d) at %08x", __FUNCTION__, ctxId, serverIdsPtr, maxServerIds, mips->pc); if (!npMatching2Inited) return hleLogError(Log::sceNet, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); diff --git a/Core/HLE/sceParseHttp.cpp b/Core/HLE/sceParseHttp.cpp index 20847015e4..4bc7bd1cfd 100644 --- a/Core/HLE/sceParseHttp.cpp +++ b/Core/HLE/sceParseHttp.cpp @@ -103,8 +103,8 @@ static int sceParseHttpResponseHeader(u32 headerAddr, int headerLength, const ch return hleLogDebug(Log::sceNet, len); } -static int sceParseHttpStatusLine(u32 headerAddr, u32 headerLength, u32 httpVersionMajorAddr, u32 httpVersionMinorAddr, u32 httpStatusCodeAddr, u32 httpStatusCommentAddr, u32 httpStatusCommentLengthAddr) { - WARN_LOG(Log::sceNet, "UNTESTED sceParseHttpStatusLine(%x, %d, %x, %x, %x, %x, %x) at %08x", headerAddr, headerLength, httpVersionMajorAddr, httpVersionMinorAddr, httpStatusCodeAddr, httpStatusCommentAddr, httpStatusCommentLengthAddr, currentMIPS->pc); +static int sceParseHttpStatusLine(MIPSState *mips, u32 headerAddr, u32 headerLength, u32 httpVersionMajorAddr, u32 httpVersionMinorAddr, u32 httpStatusCodeAddr, u32 httpStatusCommentAddr, u32 httpStatusCommentLengthAddr) { + WARN_LOG(Log::sceNet, "UNTESTED sceParseHttpStatusLine(%x, %d, %x, %x, %x, %x, %x) at %08x", headerAddr, headerLength, httpVersionMajorAddr, httpVersionMinorAddr, httpStatusCodeAddr, httpStatusCommentAddr, httpStatusCommentLengthAddr, mips->pc); if (!Memory::IsValidRange(headerAddr, headerLength)) return hleLogError(Log::sceNet, -1, "invalid arg"); diff --git a/Core/HLE/sceParseUri.cpp b/Core/HLE/sceParseUri.cpp index 6642d90773..3e73291c34 100644 --- a/Core/HLE/sceParseUri.cpp +++ b/Core/HLE/sceParseUri.cpp @@ -39,8 +39,8 @@ int workAreaAddString(u32 workAreaAddr, int workAreaSize, int offset, const char } // FIXME: parsedUriArea, workArea can be 0/null? LittelBigPlanet seems to set workAreaSizeAddr to 0 -static int sceUriParse(u32 parsedUriAreaAddr, const char* url, u32 workAreaAddr, u32 workAreaSizeAddr, int workAreaSize) { - WARN_LOG(Log::sceNet, "UNTESTED sceUriParse(%x, %s, %x, %x, %d) at %08x", parsedUriAreaAddr, safe_string(url), workAreaAddr, workAreaSizeAddr, workAreaSize, currentMIPS->pc); +static int sceUriParse(MIPSState *mips, u32 parsedUriAreaAddr, const char* url, u32 workAreaAddr, u32 workAreaSizeAddr, int workAreaSize) { + WARN_LOG(Log::sceNet, "UNTESTED sceUriParse(%x, %s, %x, %x, %d) at %08x", parsedUriAreaAddr, safe_string(url), workAreaAddr, workAreaSizeAddr, workAreaSize, mips->pc); if (url == nullptr) return hleLogError(Log::sceNet, -1, "invalid arg"); @@ -156,8 +156,8 @@ static int sceUriParse(u32 parsedUriAreaAddr, const char* url, u32 workAreaAddr, return 0; } -static int sceUriBuild(u32 workAreaAddr, u32 workAreaSizeAddr, int workAreaSize, u32 parsedUriAddr, int flags) { - WARN_LOG(Log::sceNet, "UNTESTED sceUriBuild(%x, %x, %d, %x, %d) at %08x", workAreaAddr, workAreaSizeAddr, workAreaSize, parsedUriAddr, flags, currentMIPS->pc); +static int sceUriBuild(MIPSState *mips, u32 workAreaAddr, u32 workAreaSizeAddr, int workAreaSize, u32 parsedUriAddr, int flags) { + WARN_LOG(Log::sceNet, "UNTESTED sceUriBuild(%x, %x, %d, %x, %d) at %08x", workAreaAddr, workAreaSizeAddr, workAreaSize, parsedUriAddr, flags, mips->pc); auto workAreaSz = PSPPointer::Create(workAreaSizeAddr); @@ -261,8 +261,8 @@ static int sceUriBuild(u32 workAreaAddr, u32 workAreaSizeAddr, int workAreaSize, return hleLogDebug(Log::sceNet, 0, "built URI: %s", uri.c_str()); } -static int sceUriEscape(u32 escapedAddr, u32 escapedLengthAddr, int escapedBufferLength, const char* source) { - WARN_LOG(Log::sceNet, "UNTESTED sceUriEscape(%x, %x, %d, %s) at %08x", escapedAddr, escapedLengthAddr, escapedBufferLength, safe_string(source), currentMIPS->pc); +static int sceUriEscape(MIPSState *mips, u32 escapedAddr, u32 escapedLengthAddr, int escapedBufferLength, const char* source) { + WARN_LOG(Log::sceNet, "UNTESTED sceUriEscape(%x, %x, %d, %s) at %08x", escapedAddr, escapedLengthAddr, escapedBufferLength, safe_string(source), mips->pc); if (source == nullptr) { return hleLogError(Log::sceNet, -1, "invalid source"); diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 3ebce4666f..c0fca1d799 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -975,7 +975,7 @@ static u32 scePsmfGetPsmfVersion(u32 psmfStruct) return hleLogDebug(Log::ME, psmf->version); } -static u32 scePsmfVerifyPsmf(u32 psmfAddr) +static u32 scePsmfVerifyPsmf(MIPSState *mips, u32 psmfAddr) { if (!Memory::IsValid4AlignedRange(psmfAddr, 12)) { return hleLogError(Log::ME, SCE_PSMF_ERROR_NOT_FOUND, "bad address"); @@ -990,7 +990,7 @@ static u32 scePsmfVerifyPsmf(u32 psmfAddr) } // Kurohyou 2 (at least the demo) uses an uninitialized value that happens to be zero on the PSP. // It appears to be written by scePsmfVerifyPsmf(), so we write some bytes into the stack here. - Memory::Memset(currentMIPS->r[MIPS_REG_SP] - 0x20, 0, 0x20, "PsmfStack"); + Memory::Memset(mips->r[MIPS_REG_SP] - 0x20, 0, 0x20, "PsmfStack"); return hleLogDebug(Log::ME, 0); } diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 538c811a43..9a080eaf64 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -1604,7 +1604,7 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) { return hleLogInfo(Log::sceUtility, 0, "(%s): %08x", SystemParamToString(id), param); } -static u32 sceUtilityLoadNetModule(u32 module) { +static u32 sceUtilityLoadNetModule(MIPSState *mips, u32 module) { // Driver 76 actually checks using sceKernelGetModuleIdList, so we load the HLE module here for checking std::vector mod_list; @@ -1622,7 +1622,7 @@ static u32 sceUtilityLoadNetModule(u32 module) { } for (const char *mod_path : mod_list) { - int modid = (int)hleCall(ModuleMgrForUser, u32, sceKernelLoadModule, mod_path, 0, 0); + int modid = (int)hleCall(ModuleMgrForUser, u32, sceKernelLoadModule, mips, mod_path, 0, 0); if (modid >= 0) { hleCall(ModuleMgrForUser, u32, sceKernelStartModule, modid, 0, 0, 0, 0); } diff --git a/Core/MIPS/ARM/ArmIRCompSystem.cpp b/Core/MIPS/ARM/ArmIRCompSystem.cpp index 41296dd08e..0ccd4ab8f1 100644 --- a/Core/MIPS/ARM/ArmIRCompSystem.cpp +++ b/Core/MIPS/ARM/ArmIRCompSystem.cpp @@ -190,7 +190,8 @@ void ArmJitBackend::CompIR_System(IRInst inst) { WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); #ifdef USE_PROFILER // When profiling, we can't skip CallSyscall, since it times syscalls. - MOVI2R(R0, inst.constant); + MOVP2R(R0, mips_); + MOVI2R(R1, inst.constant); QuickCallFunction(R12, &CallSyscall); #else // Skip the CallSyscall where possible. @@ -200,15 +201,18 @@ void ArmJitBackend::CompIR_System(IRInst inst) { if (func) { void *quickFunc = GetQuickSyscallFunc(func, op); if (quickFunc) { - MOVP2R(R0, func); + MOVP2R(R0, mips_); + MOVP2R(R1, func); QuickCallFunction(R12, (const u8 *)quickFunc); } else { - MOVI2R(R0, inst.constant); + MOVP2R(R0, mips_); + MOVI2R(R1, inst.constant); QuickCallFunction(R12, &CallSyscall); } } else { // Shouldn't get here. - MOVI2R(R0, 0); + MOVP2R(R0, mips_); + MOVI2R(R1, 0); QuickCallFunction(R12, &CallSyscallUnresolvedAtPC); } } @@ -223,7 +227,8 @@ void ArmJitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); - MOVI2R(R0, inst.constant); + MOVP2R(R0, mips_); + MOVI2R(R1, inst.constant); QuickCallFunction(R12, &CallSyscallUnresolvedAtPC); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -233,6 +238,7 @@ void ArmJitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::REPLACEMENT); + MOVP2R(R0, mips_); QuickCallFunction(R12, GetReplacementFunc(inst.constant)->replaceFunc); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/ARM64/Arm64IRCompSystem.cpp b/Core/MIPS/ARM64/Arm64IRCompSystem.cpp index 7847725d76..2e3386a50b 100644 --- a/Core/MIPS/ARM64/Arm64IRCompSystem.cpp +++ b/Core/MIPS/ARM64/Arm64IRCompSystem.cpp @@ -215,7 +215,8 @@ void Arm64JitBackend::CompIR_System(IRInst inst) { WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); #ifdef USE_PROFILER // When profiling, we can't skip CallSyscall, since it times syscalls. - MOVI2R(W0, inst.constant); + MOVP2R(X0, mips_); + MOVI2R(W1, inst.constant); QuickCallFunction(SCRATCH2_64, &CallSyscall); #else // Skip the CallSyscall where possible. @@ -225,15 +226,18 @@ void Arm64JitBackend::CompIR_System(IRInst inst) { if (func) { void *quickFunc = GetQuickSyscallFunc(func, op); if (quickFunc) { - MOVP2R(X0, func); + MOVP2R(X0, mips_); + MOVP2R(X1, func); QuickCallFunction(SCRATCH2_64, (const u8 *)quickFunc); } else { - MOVI2R(W0, inst.constant); + MOVP2R(X0, mips_); + MOVI2R(W1, inst.constant); QuickCallFunction(SCRATCH2_64, &CallSyscall); } } else { // Shouldn't get here. - MOVI2R(W0, 0); + MOVP2R(X0, mips_); + MOVI2R(W1, 0); QuickCallFunction(SCRATCH2_64, &CallSyscallUnresolvedAtPC); } } @@ -248,7 +252,8 @@ void Arm64JitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); - MOVI2R(W0, inst.constant); + MOVP2R(X0, mips_); + MOVI2R(W1, inst.constant); QuickCallFunction(SCRATCH2_64, &CallSyscallUnresolvedAtPC); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -258,6 +263,7 @@ void Arm64JitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::REPLACEMENT); + MOVP2R(X0, mips_); QuickCallFunction(SCRATCH2_64, GetReplacementFunc(inst.constant)->replaceFunc); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index 39d8b9f612..ec38896f3d 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -1429,7 +1429,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const IRInst *chainArena) { MIPSOpcode op(inst->constant); // HLE runs in the host's normal mode, see ApplyHostRoundingMode. RestoreHostRoundingMode(); - CallSyscall(op); + CallSyscall(mips, op); ApplyHostRoundingMode(mips); if (coreState != CORE_RUNNING_CPU) { CoreTiming::ForceCheck(mips); @@ -1442,7 +1442,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const IRInst *chainArena) { // If we get here, the syscall is invalid. u32 pc = inst->constant; RestoreHostRoundingMode(); - CallSyscallUnresolvedAtPC(pc); + CallSyscallUnresolvedAtPC(mips, pc); ApplyHostRoundingMode(mips); if (coreState != CORE_RUNNING_CPU) { // hm, what's this for? @@ -1466,7 +1466,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const IRInst *chainArena) { int funcIndex = inst->constant; const ReplacementTableEntry *f = GetReplacementFunc(funcIndex); RestoreHostRoundingMode(); - int cycles = f->replaceFunc(); + int cycles = f->replaceFunc(mips); ApplyHostRoundingMode(mips); mips->r[inst->dest] = cycles < 0 ? -1 : 0; mips->downcount -= cycles < 0 ? -cycles : cycles; diff --git a/Core/MIPS/Interpreter.cpp b/Core/MIPS/Interpreter.cpp index 495550b364..657f1095dd 100644 --- a/Core/MIPS/Interpreter.cpp +++ b/Core/MIPS/Interpreter.cpp @@ -191,7 +191,7 @@ namespace MIPSInt { mips->inDelaySlot = false; // HLE code is host code - it must not run under the guest's rounding mode. RestoreHostRoundingMode(); - CallSyscallWithPC(op, syscallPC); + CallSyscallWithPC(mips, op, syscallPC); ApplyHostRoundingMode(mips); } @@ -1269,7 +1269,7 @@ namespace MIPSInt { if (entry && entry->replaceFunc && (entry->flags & REPFLAG_DISABLED) == 0) { // Like a syscall, a replacement function is host code - see Int_Syscall. RestoreHostRoundingMode(); - int cycles = entry->replaceFunc(); + int cycles = entry->replaceFunc(mips); ApplyHostRoundingMode(mips); if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) { diff --git a/Core/MIPS/LoongArch64/LoongArch64CompSystem.cpp b/Core/MIPS/LoongArch64/LoongArch64CompSystem.cpp index 104acba387..9f9a60051f 100644 --- a/Core/MIPS/LoongArch64/LoongArch64CompSystem.cpp +++ b/Core/MIPS/LoongArch64/LoongArch64CompSystem.cpp @@ -179,7 +179,8 @@ void LoongArch64JitBackend::CompIR_System(IRInst inst) { WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); #ifdef USE_PROFILER // When profiling, we can't skip CallSyscall, since it times syscalls. - LI(R4, (int32_t)inst.constant); + LI(R4, (uintptr_t)mips_); + LI(R5, (int32_t)inst.constant); QuickCallFunction(&CallSyscall, SCRATCH2); #else // Skip the CallSyscall where possible. @@ -189,15 +190,18 @@ void LoongArch64JitBackend::CompIR_System(IRInst inst) { if (func) { void *quickFunc = GetQuickSyscallFunc(func, op); if (quickFunc) { - LI(R4, func); + LI(R4, (uintptr_t)mips_); + LI(R5, func); QuickCallFunction((const u8 *)quickFunc, SCRATCH2); } else { - LI(R4, (int32_t)inst.constant); + LI(R4, (uintptr_t)mips_); + LI(R5, (int32_t)inst.constant); QuickCallFunction(&CallSyscall, SCRATCH2); } } else { // Shouldn't get here. - LI(R4, 0); + LI(R4, (uintptr_t)mips_); + LI(R5, 0); QuickCallFunction(&CallSyscallUnresolvedAtPC, SCRATCH2); } } @@ -211,7 +215,8 @@ void LoongArch64JitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); - LI(R4, inst.constant); + LI(R4, (uintptr_t)mips_); + LI(R5, inst.constant); QuickCallFunction(&CallSyscallUnresolvedAtPC, SCRATCH2); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -221,6 +226,7 @@ void LoongArch64JitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::REPLACEMENT); + LI(R4, (uintptr_t)mips_); QuickCallFunction(GetReplacementFunc(inst.constant)->replaceFunc, SCRATCH2); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/RiscV/RiscVCompSystem.cpp b/Core/MIPS/RiscV/RiscVCompSystem.cpp index ec7b3c01d0..fdfe23a31d 100644 --- a/Core/MIPS/RiscV/RiscVCompSystem.cpp +++ b/Core/MIPS/RiscV/RiscVCompSystem.cpp @@ -187,8 +187,9 @@ void RiscVJitBackend::CompIR_System(IRInst inst) { WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); #ifdef USE_PROFILER // When profiling, we can't skip CallSyscall, since it times syscalls. - LI(X10, (int32_t)inst.constant); - QuickCallFunction(&CallSyscall, SCRATCH2); + LI(X10, (uintptr_t)mips_); + LI(X11, (int32_t)inst.constant); + QuickCallFunction(&CallSyscall); #else // Skip the CallSyscall where possible. { @@ -197,16 +198,19 @@ void RiscVJitBackend::CompIR_System(IRInst inst) { if (func) { void *quickFunc = GetQuickSyscallFunc(func, op); if (quickFunc) { - LI(X10, (uintptr_t)func); - QuickCallFunction((const u8 *)quickFunc, SCRATCH2); + LI(X10, (uintptr_t)mips_); + LI(X11, (uintptr_t)func); + QuickCallFunction((const u8 *)quickFunc); } else { - LI(X10, (int32_t)inst.constant); - QuickCallFunction(&CallSyscall, SCRATCH2); + LI(X10, (uintptr_t)mips_); + LI(X11, (int32_t)inst.constant); + QuickCallFunction(&CallSyscall); } } else { // Shouldn't get here. - LI(X10, 0); - QuickCallFunction(&CallSyscallUnresolvedAtPC, SCRATCH2); + LI(X10, (uintptr_t)mips_); + LI(X11, 0); + QuickCallFunction(&CallSyscallUnresolvedAtPC); } } #endif @@ -220,8 +224,9 @@ void RiscVJitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); - LI(X10, (int32_t)inst.constant); - QuickCallFunction(&CallSyscallUnresolvedAtPC, SCRATCH2); + LI(X10, (uintptr_t)mips_); + LI(X11, (int32_t)inst.constant); + QuickCallFunction(&CallSyscallUnresolvedAtPC); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); break; @@ -230,6 +235,7 @@ void RiscVJitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::REPLACEMENT); + LI(X10, (uintptr_t)mips_); QuickCallFunction(GetReplacementFunc(inst.constant)->replaceFunc, SCRATCH2); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/x86/X64IRCompSystem.cpp b/Core/MIPS/x86/X64IRCompSystem.cpp index ff0db60f3e..09931e4179 100644 --- a/Core/MIPS/x86/X64IRCompSystem.cpp +++ b/Core/MIPS/x86/X64IRCompSystem.cpp @@ -206,7 +206,7 @@ void X64JitBackend::CompIR_System(IRInst inst) { WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); #ifdef USE_PROFILER // When profiling, we can't skip CallSyscall, since it times syscalls. - ABI_CallFunctionC((const u8 *)&CallSyscall, inst.constant); + ABI_CallFunctionPA((const u8 *)&CallSyscall, mips_, Imm32(inst.constant)); #else // Skip the CallSyscall where possible. { @@ -215,14 +215,14 @@ void X64JitBackend::CompIR_System(IRInst inst) { if (func) { void *quickFunc = GetQuickSyscallFunc(func, op); if (quickFunc) { - ABI_CallFunctionP((const u8 *)quickFunc, (void *)func); + ABI_CallFunctionPP((const u8 *)quickFunc, mips_, (void *)func); } else { - ABI_CallFunctionC((const u8 *)&CallSyscall, inst.constant); + ABI_CallFunctionPA((const u8 *)&CallSyscall, mips_, Imm32(inst.constant)); } } else { _dbg_assert_(false); // Shouldn't get here, this should be resolved during ->IR compilation. - ABI_CallFunctionC((const u8 *)&CallSyscallUnresolvedAtPC, 0); + ABI_CallFunctionPA((const u8 *)&CallSyscallUnresolvedAtPC, mips_, Imm32(0)); } } #endif @@ -236,7 +236,7 @@ void X64JitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::SYSCALL); - ABI_CallFunctionC((const u8 *)&CallSyscallUnresolvedAtPC, inst.constant); + ABI_CallFunctionPA((const u8 *)&CallSyscallUnresolvedAtPC, mips_, Imm32(inst.constant)); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); break; @@ -245,7 +245,7 @@ void X64JitBackend::CompIR_System(IRInst inst) { FlushAll(); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::REPLACEMENT); - ABI_CallFunction(GetReplacementFunc(inst.constant)->replaceFunc); + ABI_CallFunctionP(GetReplacementFunc(inst.constant)->replaceFunc, mips_); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 625cbd977b..bdac917e2d 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -474,7 +474,7 @@ void PPGeEnd() // We actually drew something gpu->EnableInterrupts(false); NotifyMemInfo(MemBlockFlags::WRITE, dlPtr, dlWritePtr - dlPtr, "PPGe ListCmds"); - u32 list = hleCall(sceGe_user, u32, sceGeListEnQueue, dlPtr, dlWritePtr, -1, listArgs.ptr); + u32 list = hleCall(sceGe_user, u32, sceGeListEnQueue, currentMIPS, dlPtr, dlWritePtr, -1, listArgs.ptr); DEBUG_LOG(Log::sceGe, "PPGe enqueued display list %i", list); gpu->EnableInterrupts(true); } diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 0beabbaad6..b0b4a46ec6 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -555,7 +555,7 @@ void DrawThreadView(ImConfig &cfg, ImControl &control) { } if (ImGui::MenuItem("Kill thread")) { // Dangerous! - sceKernelTerminateThread(thread.id); + sceKernelTerminateThread(&mipsr4k, thread.id); } if (thread.status == THREADSTATUS_WAIT) { if (ImGui::MenuItem("Force run now")) { diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index c31b0874cd..38754b9823 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -163,7 +163,7 @@ void CtrlThreadList::showMenu(int itemIndex, const POINT &pt) case ID_DISASM_THREAD_KILL: { SceUID threadID = threadInfo.id; - Core_RunOnCPUThread([&] { sceKernelTerminateThread(threadID); }); + Core_RunOnCPUThread([&] { sceKernelTerminateThread(&mipsr4k, threadID); }); } reloadThreads(); break; diff --git a/docs/HLEModules.md b/docs/HLEModules.md index a3ee089693..297fba8497 100644 --- a/docs/HLEModules.md +++ b/docs/HLEModules.md @@ -10,6 +10,9 @@ small examples to copy from). A module is a `const HLEFunction []` table o - `FunctionWrappers.h` has generic `WrapX_YYY` templates for common signatures (return type X, args YYY) - add new wrappers there if you need a new signature. +- A function that needs the CPU (registers beyond its arguments, the PC for a log line, `PARAM()`/`RETURN()`) takes + `MIPSState *mips` as an extra first parameter, and the wrapper passes in the state the syscall runs on. Use that + rather than `currentMIPS`. Calling such a function directly, or through `hleCall`, means passing a state yourself. - Format string legend for the `retmask`/argmask chars: `x` = u32 (shown as hex), `i` = int/s32, `f` = float, `X` = u64, `I` = s64, `v` = void. - For functions of genuinely unknown purpose (only known by NID), name them `_` and stub them with diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 55c04c4f03..55d3087ebb 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -58,8 +58,8 @@ // The clock as the terminating syscall sees it, so the cores can be compared on cycles too. static u64 g_terminatorTicks; -void UnitTestTerminator() { - g_terminatorTicks = CoreTiming::GetTicks(currentMIPS); +void UnitTestTerminator(MIPSState *mips) { + g_terminatorTicks = CoreTiming::GetTicks(mips); // Bails out of jit so we can time things. coreState = CORE_POWERDOWN; hleSkipDeadbeef(); @@ -69,7 +69,7 @@ void UnitTestTerminator() { // (0x00400000 unless flushed to zero). HLE must always see the host's own mode. static std::vector g_roundingProbes; -void UnitTestRoundingProbe() { +void UnitTestRoundingProbe(MIPSState *mips) { volatile float one = 1.0f, three = 3.0f, fltMin = FLT_MIN, half = 0.5f; float third = one / three; float denormal = fltMin * half;