From efd71e24449d5d6a87826a8a9803360bd2d49ae8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Apr 2013 23:45:46 -0700 Subject: [PATCH] Make sceKernelNotifyCallback() error if invalid cb. Which makes Numblast clearly happy. --- Core/HLE/sceKernel.cpp | 14 ++--- Core/HLE/sceKernelThread.cpp | 109 +++++++++++++++++------------------ Core/HLE/sceKernelThread.h | 13 ++--- 3 files changed, 65 insertions(+), 71 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 4c05537e17..55a9a75dee 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -709,13 +709,13 @@ const HLEFunction ThreadManForUser[] = {0x72F3C145,0,"sceKernelReleaseThreadEventHandler"}, {0x369EEB6B,0,"sceKernelReferThreadEventHandlerStatus"}, - {0x349d6d6c,sceKernelCheckCallback,"sceKernelCheckCallback"}, - {0xE81CAF8F,sceKernelCreateCallback,"sceKernelCreateCallback"}, - {0xEDBA5844,sceKernelDeleteCallback,"sceKernelDeleteCallback"}, - {0xC11BA8C4,sceKernelNotifyCallback,"sceKernelNotifyCallback"}, - {0xBA4051D6,sceKernelCancelCallback,"sceKernelCancelCallback"}, - {0x2A3D44FF,sceKernelGetCallbackCount,"sceKernelGetCallbackCount"}, - {0x730ED8BC,sceKernelReferCallbackStatus,"sceKernelReferCallbackStatus"}, + {0x349d6d6c,sceKernelCheckCallback, "sceKernelCheckCallback"}, + {0xE81CAF8F,WrapI_CUU, "sceKernelCreateCallback"}, + {0xEDBA5844,WrapI_I, "sceKernelDeleteCallback"}, + {0xC11BA8C4,WrapI_II, "sceKernelNotifyCallback"}, + {0xBA4051D6,WrapI_I, "sceKernelCancelCallback"}, + {0x2A3D44FF,WrapI_I, "sceKernelGetCallbackCount"}, + {0x730ED8BC,WrapI_IU, "sceKernelReferCallbackStatus"}, {0x8125221D,&WrapI_CUU,"sceKernelCreateMbx"}, {0x86255ADA,&WrapI_I,"sceKernelDeleteMbx"}, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index c64a99196f..430ed3888e 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2428,68 +2428,80 @@ u32 __KernelCreateCallback(const char *name, u32 entrypoint, u32 commonArg) return id; } -void sceKernelCreateCallback() +SceUID sceKernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg) { - u32 entrypoint = PARAM(1); - u32 callbackArg = PARAM(2); + SceUID id = __KernelCreateCallback(name, entrypoint, signalArg); + DEBUG_LOG(HLE, "%i=sceKernelCreateCallback(name=%s, entry=%08x, callbackArg=%08x)", id, name, entrypoint, signalArg); - const char *name = Memory::GetCharPointer(PARAM(0)); - - u32 id = __KernelCreateCallback(name, entrypoint, callbackArg); - - DEBUG_LOG(HLE,"%i=sceKernelCreateCallback(name=%s,entry= %08x, callbackArg = %08x)", id, name, entrypoint, callbackArg); - - RETURN(id); + return id; } -void sceKernelDeleteCallback() +int sceKernelDeleteCallback(SceUID cbId) { - SceUID id = PARAM(0); - DEBUG_LOG(HLE,"sceKernelDeleteCallback(%i)", id); + DEBUG_LOG(HLE, "sceKernelDeleteCallback(%i)", cbId); // TODO: Make sure it's gone from all threads first! - RETURN(kernelObjects.Destroy(id)); + return kernelObjects.Destroy(cbId); } -// Rarely used -void sceKernelNotifyCallback() +// Generally very rarely used, but Numblast uses it like candy. +int sceKernelNotifyCallback(SceUID cbId, int notifyArg) { - SceUID cbId = PARAM(0); - u32 arg = PARAM(1); - DEBUG_LOG(HLE,"sceKernelNotifyCallback(%i, %i)", cbId, arg); - - __KernelNotifyCallback(THREAD_CALLBACK_USER_DEFINED, cbId, arg); - RETURN(0); -} - -void sceKernelCancelCallback() -{ - SceUID cbId = PARAM(0); - ERROR_LOG(HLE,"sceKernelCancelCallback(%i)", cbId); + DEBUG_LOG(HLE,"sceKernelNotifyCallback(%i, %i)", cbId, notifyArg); u32 error; Callback *cb = kernelObjects.Get(cbId, error); if (cb) { - // This is what JPCSP does. Huh? - cb->nc.notifyArg = 0; - RETURN(0); + // TODO: Should this notify other existing callbacks too? + __KernelNotifyCallback(THREAD_CALLBACK_USER_DEFINED, cbId, notifyArg); + return 0; } else { - ERROR_LOG(HLE,"sceKernelCancelCallback(%i) - bad cbId", cbId); - RETURN(error); + ERROR_LOG(HLE, "sceKernelCancelCallback(%i) - bad cbId", cbId); + return error; } - RETURN(0); } -void sceKernelGetCallbackCount() +int sceKernelCancelCallback(SceUID cbId) { - SceUID cbId = PARAM(0); + DEBUG_LOG(HLE, "sceKernelCancelCallback(%i)", cbId); u32 error; Callback *cb = kernelObjects.Get(cbId, error); if (cb) { - RETURN(cb->nc.notifyCount); + // This just resets the notify count. + cb->nc.notifyArg = 0; + return 0; } else { - ERROR_LOG(HLE,"sceKernelGetCallbackCount(%i) - bad cbId", cbId); - RETURN(error); + ERROR_LOG(HLE, "sceKernelCancelCallback(%i) - bad cbId", cbId); + return error; + } +} + +int sceKernelGetCallbackCount(SceUID cbId) +{ + u32 error; + Callback *cb = kernelObjects.Get(cbId, error); + if (cb) { + return cb->nc.notifyCount; + } else { + ERROR_LOG(HLE, "sceKernelGetCallbackCount(%i) - bad cbId", cbId); + return error; + } +} + +int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) +{ + u32 error; + Callback *c = kernelObjects.Get(cbId, error); + if (c) { + DEBUG_LOG(HLE, "sceKernelReferCallbackStatus(%i, %08x)", cbId, statusAddr); + // TODO: Maybe check size parameter? + if (Memory::IsValidAddress(statusAddr)) { + Memory::WriteStruct(statusAddr, &c->nc); + } // else TODO + return 0; + } else { + ERROR_LOG(HLE, "sceKernelReferCallbackStatus(%i, %08x) - bad cbId", cbId, statusAddr); + return error; } } @@ -2499,24 +2511,6 @@ u32 sceKernelExtendThreadStack(u32 cpu, u32 size, u32 entryAddr, u32 entryParame return 0; } -void sceKernelReferCallbackStatus() -{ - SceUID cbId = PARAM(0); - u32 statusAddr = PARAM(1); - u32 error; - Callback *c = kernelObjects.Get(cbId, error); - if (c) { - DEBUG_LOG(HLE,"sceKernelReferCallbackStatus(%i, %08x)", cbId, statusAddr); - if (Memory::IsValidAddress(statusAddr)) { - Memory::WriteStruct(statusAddr, &c->nc); - } // else TODO - RETURN(0); - } else { - ERROR_LOG(HLE,"sceKernelReferCallbackStatus(%i, %08x) - bad cbId", cbId, statusAddr); - RETURN(error); - } -} - void ActionAfterMipsCall::run(MipsCall &call) { u32 error; Thread *thread = kernelObjects.Get(threadID, error); @@ -3075,6 +3069,7 @@ bool __KernelForceCallbacks() return callbacksProcessed; } +// Not wrapped because it has special return logic. void sceKernelCheckCallback() { // Start with yes. diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index b695910138..02da05cf95 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -199,14 +199,13 @@ u32 __KernelInterruptReturnAddress(); // TODO: remove // Internal access - used by sceSetGeCallback u32 __KernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg); -void sceKernelCreateCallback(); -void sceKernelDeleteCallback(); -void sceKernelNotifyCallback(); -void sceKernelCancelCallback(); -void sceKernelGetCallbackCount(); +SceUID sceKernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg); +int sceKernelDeleteCallback(SceUID cbId); +int sceKernelNotifyCallback(SceUID cbId, int notifyArg); +int sceKernelCancelCallback(SceUID cbId); +int sceKernelGetCallbackCount(SceUID cbId); void sceKernelCheckCallback(); -void sceKernelGetCallbackCount(); -void sceKernelReferCallbackStatus(); +int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr); class Action;