From 1ea34bb6e83a3470995614fdb02a95280c9321b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 30 Dec 2012 21:30:33 +0100 Subject: [PATCH] Stub out all of VTimer. --- Core/HLE/FunctionWrappers.h | 20 ++++ Core/HLE/sceKernel.cpp | 30 ++--- Core/HLE/sceKernelThread.cpp | 7 +- Core/HLE/sceKernelThread.h | 46 ++++---- Core/HLE/sceKernelVTimer.cpp | 215 +++++++++++++++++++++++++++++------ Core/HLE/sceKernelVTimer.h | 17 ++- 6 files changed, 257 insertions(+), 78 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index 4de18203a4..6459ba6ab0 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -29,6 +29,12 @@ template void WrapU64_V() { currentMIPS->r[3] = (retval >> 32) & 0xFFFFFFFF; } +template void WrapU64_U() { + u64 retval = func(PARAM(0)); + currentMIPS->r[2] = retval & 0xFFFFFFFF; + currentMIPS->r[3] = (retval >> 32) & 0xFFFFFFFF; +} + template void WrapI_UU64() { u64 param_one = currentMIPS->r[6]; param_one |= (u64)(currentMIPS->r[7]) << 32; @@ -36,6 +42,13 @@ template void WrapI_UU64() { RETURN(retval); } +template void WrapU_UU64() { + u64 param_one = currentMIPS->r[6]; + param_one |= (u64)(currentMIPS->r[7]) << 32; + u32 retval = func(PARAM(0), param_one); + RETURN(retval); +} + template void WrapI_UUU64() { u64 param_two = currentMIPS->r[6]; param_two |= (u64)(currentMIPS->r[7]) << 32; @@ -50,6 +63,13 @@ template void WrapU_II64I() { RETURN(retval); } +template void WrapU_UU64UU() { + u64 param_one = currentMIPS->r[6]; + param_one |= (u64)(currentMIPS->r[7]) << 32; + u32 retval = func(PARAM(0), param_one, PARAM(4), PARAM(5)); + RETURN(retval); +} + template void WrapI64_II64I() { s64 param_one = currentMIPS->r[6]; param_one |= (s64)(currentMIPS->r[7]) << 32; diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 01df21da5d..ad62a01ae7 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -527,21 +527,6 @@ const HLEFunction ThreadManForUser[] = {0x94416130,WrapU_UUUU,"sceKernelGetThreadmanIdList"}, {0x57CF62DD,WrapU_U,"sceKernelGetThreadmanIdType"}, - {0x20fff560,sceKernelCreateVTimer,"sceKernelCreateVTimer"}, - {0x328F9E52,0,"sceKernelDeleteVTimer"}, - {0xc68d9437,sceKernelStartVTimer,"sceKernelStartVTimer"}, - {0xD0AEEE87,0,"sceKernelStopVTimer"}, - {0xD2D615EF,0,"sceKernelCancelVTimerHandler"}, - {0xB3A59970,0,"sceKernelGetVTimerBase"}, - {0xB7C18B77,0,"sceKernelGetVTimerBaseWide"}, - {0x034A921F,0,"sceKernelGetVTimerTime"}, - {0xC0B3FFD2,0,"sceKernelGetVTimerTimeWide"}, - {0x5F32BEAA,0,"sceKernelReferVTimerStatus"}, - {0x542AD630,0,"sceKernelSetVTimerTime"}, - {0xFB6425C3,0,"sceKernelSetVTimerTimeWide"}, - {0xd8b299ae,sceKernelSetVTimerHandler,"sceKernelSetVTimerHandler"}, - {0x53B00E9A,0,"sceKernelSetVTimerHandlerWide"}, - {0x82BC5777,sceKernelGetSystemTimeWide,"sceKernelGetSystemTimeWide"}, {0xdb738f35,sceKernelGetSystemTime,"sceKernelGetSystemTime"}, {0x369ed59d,sceKernelGetSystemTimeLow,"sceKernelGetSystemTimeLow"}, @@ -615,6 +600,21 @@ const HLEFunction ThreadManForUser[] = {0xA8AA591F,sceKernelCancelFpl,"sceKernelCancelFpl"}, {0xD8199E4C,sceKernelReferFplStatus,"sceKernelReferFplStatus"}, + {0x20fff560,WrapU_CU,"sceKernelCreateVTimer"}, + {0x328F9E52,WrapU_U,"sceKernelDeleteVTimer"}, + {0xc68d9437,WrapU_U,"sceKernelStartVTimer"}, + {0xD0AEEE87,WrapU_U,"sceKernelStopVTimer"}, + {0xD2D615EF,WrapU_U,"sceKernelCancelVTimerHandler"}, + {0xB3A59970,WrapU_UU,"sceKernelGetVTimerBase"}, + {0xB7C18B77,WrapU64_U,"sceKernelGetVTimerBaseWide"}, + {0x034A921F,WrapU_UU,"sceKernelGetVTimerTime"}, + {0xC0B3FFD2,WrapU64_U,"sceKernelGetVTimerTimeWide"}, + {0x5F32BEAA,WrapU_UU,"sceKernelReferVTimerStatus"}, + {0x542AD630,WrapU_UU,"sceKernelSetVTimerTime"}, + {0xFB6425C3,WrapU_UU64,"sceKernelSetVTimerTimeWide"}, + {0xd8b299ae,WrapU_UUUU,"sceKernelSetVTimerHandler"}, + {0x53B00E9A,WrapU_UU64UU,"sceKernelSetVTimerHandlerWide"}, + // Not sure if these should be hooked up. See below. {0x0E927AED, _sceKernelReturnFromTimerHandler, "_sceKernelReturnFromTimerHandler"}, {0x532A522E, _sceKernelExitThread,"_sceKernelExitThread"}, diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index e791219d2b..70b86778b0 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -75,11 +75,6 @@ const char *waitTypeStrings[] = { "Ctrl", }; -struct SceKernelSysClock { - u32 low; - u32 hi; -}; - struct NativeCallback { SceUInt size; @@ -1225,7 +1220,7 @@ Thread *__KernelCreateThread(SceUID &id, SceUID moduleId, const char *name, u32 t->nt.numInterruptPreempts = 0; t->nt.numReleases = 0; t->nt.numThreadPreempts = 0; - t->nt.runForClocks.low = 0; + t->nt.runForClocks.lo = 0; t->nt.runForClocks.hi = 0; t->nt.wakeupCount = 0; if (moduleId) diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index b63fe58312..b3ca3cddb2 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -54,6 +54,11 @@ void sceKernelGetThreadExitStatus(); u32 sceKernelGetThreadmanIdType(u32); u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 idCountPtr); +struct SceKernelSysClock { + u32 lo; + u32 hi; +}; + enum WaitType //probably not the real values { @@ -79,19 +84,19 @@ enum WaitType //probably not the real values struct ThreadContext { - void reset(); - u32 r[32]; - float f[32]; - float v[128]; - u32 vfpuCtrl[16]; + void reset(); + u32 r[32]; + float f[32]; + float v[128]; + u32 vfpuCtrl[16]; - u32 hi; - u32 lo; - u32 pc; - u32 fpcond; + u32 hi; + u32 lo; + u32 pc; + u32 fpcond; - u32 fcr0; - u32 fcr31; + u32 fcr0; + u32 fcr31; }; // Internal API, used by implementations of kernel functions @@ -126,15 +131,15 @@ void __KernelReSchedule(bool doCallbacks, const char *reason); // Registered callback types enum RegisteredCallbackType { - THREAD_CALLBACK_UMD = 0, - THREAD_CALLBACK_IO = 1, - THREAD_CALLBACK_MEMORYSTICK = 2, - THREAD_CALLBACK_MEMORYSTICK_FAT = 3, - THREAD_CALLBACK_POWER = 4, - THREAD_CALLBACK_EXIT = 5, - THREAD_CALLBACK_USER_DEFINED = 6, - THREAD_CALLBACK_SIZE = 7, - THREAD_CALLBACK_NUM_TYPES = 8, + THREAD_CALLBACK_UMD = 0, + THREAD_CALLBACK_IO = 1, + THREAD_CALLBACK_MEMORYSTICK = 2, + THREAD_CALLBACK_MEMORYSTICK_FAT = 3, + THREAD_CALLBACK_POWER = 4, + THREAD_CALLBACK_EXIT = 5, + THREAD_CALLBACK_USER_DEFINED = 6, + THREAD_CALLBACK_SIZE = 7, + THREAD_CALLBACK_NUM_TYPES = 8, }; // These operate on the current thread @@ -208,6 +213,7 @@ struct MipsCall { void DoState(PointerWrap &p); }; + enum ThreadStatus { THREADSTATUS_RUNNING = 1, diff --git a/Core/HLE/sceKernelVTimer.cpp b/Core/HLE/sceKernelVTimer.cpp index 1d6fb67f89..740735d060 100644 --- a/Core/HLE/sceKernelVTimer.cpp +++ b/Core/HLE/sceKernelVTimer.cpp @@ -16,33 +16,31 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "sceKernel.h" +#include "sceKernelThread.h" #include "sceKernelVTimer.h" #include "HLE.h" -////////////////////////////////////////////////////////////////////////// -// VTIMER -////////////////////////////////////////////////////////////////////////// +// Using INFO_LOG liberally when this is in development. When done, +// should be changed to DEBUG_LOG wherever applicable. -struct NativeVTimer -{ - SceSize size; - char name[KERNELOBJECT_MAX_NAME_LENGTH+1]; - u64 startTime; - bool running; - u32 handler; - u64 handlerTime; +struct NativeVTimer { + SceSize size; + char name[KERNELOBJECT_MAX_NAME_LENGTH+1]; + int running; + SceKernelSysClock basetime; + SceKernelSysClock curtime; + SceKernelSysClock scheduletime; + u32 handlerAddr; u32 argument; }; -struct VTimer : public KernelObject -{ +struct VTimer : public KernelObject { const char *GetName() {return nvt.name;} const char *GetTypeName() {return "VTimer";} static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_VTID; } int GetIDType() const { return SCE_KERNEL_TMID_VTimer; } - virtual void DoState(PointerWrap &p) - { + virtual void DoState(PointerWrap &p) { p.Do(nvt); p.DoMarker("VTimer"); } @@ -50,42 +48,191 @@ struct VTimer : public KernelObject NativeVTimer nvt; }; -KernelObject *__KernelVTimerObject() -{ +KernelObject *__KernelVTimerObject() { return new VTimer; } -void sceKernelCreateVTimer() -{ - DEBUG_LOG(HLE,"sceKernelCreateVTimer"); - const char *name = Memory::GetCharPointer(PARAM(0)); +u32 sceKernelCreateVTimer(const char *name, u32 optParamAddr) { + INFO_LOG(HLE,"sceKernelCreateVTimer(%s, %08x)", name, optParamAddr); VTimer *vt = new VTimer(); SceUID uid = kernelObjects.Create(vt); + memset(&vt->nvt, 0, sizeof(vt->nvt)); strncpy(vt->nvt.name, name, 32); - vt->nvt.running = true; - vt->nvt.startTime = 0; //TODO fix - RETURN(uid); //TODO: return timer ID + vt->nvt.running = 1; + return uid; //TODO: return timer ID } -void sceKernelStartVTimer() -{ - int timerID = PARAM(0); - DEBUG_LOG(HLE,"sceKernelStartVTimer(%i)", timerID); +u32 sceKernelDeleteVTimer(u32 uid) { + INFO_LOG(HLE,"sceKernelDeleteVTimer(%i)", uid); - RETURN(0); //ok; 1=alreadyrunning + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO: Deschedule events here. Might share code with Stop. + + return kernelObjects.Destroy(uid); } -void sceKernelSetVTimerHandler() -{ - DEBUG_LOG(HLE,"sceKernelSetVTimerHandler"); +u32 sceKernelStartVTimer(u32 uid) { + WARN_LOG(HLE,"FAKE sceKernelStartVTimer(%i)", uid); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + if (vt->nvt.running) { + // Already running + return 1; + } else { + vt->nvt.running = 1; + // TODO: Schedule events etc. + return 0; + } +} + +u32 sceKernelStopVTimer(u32 uid) { + WARN_LOG(HLE,"FAKE sceKernelStartVTimer(%i)", uid); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + if (vt->nvt.running) { + // Already running + return 0; + } else { + vt->nvt.running = 0; + // TODO: Deschedule events etc. + return 1; + } +} + +u32 sceKernelSetVTimerHandler(u32 uid, u32 scheduleAddr, u32 handlerFuncAddr, u32 commonAddr) { + ERROR_LOG(HLE,"UNIMPL sceKernelSetVTimerHandler(%i, %08x, %08x, %08x)", + uid, scheduleAddr, handlerFuncAddr, commonAddr); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO + return 0; +} + +u32 sceKernelSetVTimerHandlerWide(u32 uid, u64 schedule, u32 handlerFuncAddr, u32 commonAddr) { + ERROR_LOG(HLE,"UNIMPL sceKernelSetVTimerHandlerWide(%i, %llu, %08x, %08x)", + uid, schedule, handlerFuncAddr, commonAddr); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO + return 0; +} + +u32 sceKernelCancelVTimerHandler(u32 uid) { + ERROR_LOG(HLE,"UNIMPL sceKernelCancelVTimerHandler(%i)", uid); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO + return 0; +} + +u32 sceKernelReferVTimerStatus(u32 uid, u32 statusAddr) { + INFO_LOG(HLE,"sceKernelReferVTimerStatus(%i, %08x)", uid, statusAddr); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO: possibly update time values here? + Memory::WriteStruct(statusAddr, &vt->nvt); + return 0; +} + +u32 sceKernelGetVTimerBase(u32 uid, u32 baseClockAddr) { + INFO_LOG(HLE,"sceKernelGetVTimerBase(%i, %08x)", uid, baseClockAddr); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + Memory::WriteStruct(baseClockAddr, &vt->nvt.basetime); + return 0; +} + +u64 sceKernelGetVTimerBaseWide(u32 uid) { + INFO_LOG(HLE,"sceKernelGetVTimerWide(%i)", uid); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO: probably update the timer somehow? + u64 t = vt->nvt.curtime.lo; + t |= (u64)(vt->nvt.curtime.hi) << 32; + return t; +} + +u32 sceKernelGetVTimerTime(u32 uid, u32 timeClockAddr) { + INFO_LOG(HLE,"sceKernelGetVTimerTime(%i, %08x)", uid, timeClockAddr); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO: probably update the timer somehow? + Memory::WriteStruct(timeClockAddr, &vt->nvt.curtime); + return 0; +} + +u64 sceKernelGetVTimerTimeWide(u32 uid) { + INFO_LOG(HLE,"sceKernelGetVTimerTimeWide(%i)", uid); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + // TODO: probably update the timer somehow? + u64 t = vt->nvt.curtime.lo; + t |= (u64)(vt->nvt.curtime.hi) << 32; + return t; +} + +u32 sceKernelSetVTimerTime(u32 uid, u32 timeClockAddr) { + INFO_LOG(HLE,"sceKernelSetVTimerTime(%i, %08x)", uid, timeClockAddr); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + Memory::ReadStruct(timeClockAddr, &vt->nvt.curtime); + return 0; +} + +u32 sceKernelSetVTimerTimeWide(u32 uid, u64 timeClock) { + INFO_LOG(HLE,"sceKernelSetVTimerTime(%i, %llu)", uid, timeClock); + u32 error; + VTimer *vt = kernelObjects.Get(uid, error); + if (!vt) { + return error; + } + vt->nvt.curtime.lo = timeClock & 0xFFFFFFFF; + vt->nvt.curtime.hi = timeClock >> 32; + return 0; } // Not sure why this is exposed... void _sceKernelReturnFromTimerHandler() { - DEBUG_LOG(HLE,"_sceKernelReturnFromTimerHandler"); - + ERROR_LOG(HLE,"_sceKernelReturnFromTimerHandler - should not be called!"); } diff --git a/Core/HLE/sceKernelVTimer.h b/Core/HLE/sceKernelVTimer.h index 3597dfeb18..9cde7913e5 100644 --- a/Core/HLE/sceKernelVTimer.h +++ b/Core/HLE/sceKernelVTimer.h @@ -17,9 +17,20 @@ #pragma once -void sceKernelCreateVTimer(); -void sceKernelStartVTimer(); -void sceKernelSetVTimerHandler(); +u32 sceKernelCreateVTimer(const char *name, u32 optParamAddr); +u32 sceKernelDeleteVTimer(u32 uid); +u32 sceKernelStartVTimer(u32 uid); +u32 sceKernelStopVTimer(u32 uid); +u32 sceKernelSetVTimerHandler(u32 uid, u32 scheduleAddr, u32 handlerFuncAddr, u32 commonAddr); +u32 sceKernelSetVTimerHandlerWide(u32 uid, u64 schedule, u32 handlerFuncAddr, u32 commonAddr); +u32 sceKernelCancelVTimerHandler(u32 uid); +u32 sceKernelReferVTimerStatus(u32 uid, u32 statusAddr); +u32 sceKernelGetVTimerBase(u32 uid, u32 baseClockAddr); //SceKernelSysClock +u64 sceKernelGetVTimerBaseWide(u32 uid); +u32 sceKernelGetVTimerTime(u32 uid, u32 timeClockAddr); +u64 sceKernelGetVTimerTimeWide(u32 uid); +u32 sceKernelSetVTimerTime(u32 uid, u32 timeClockAddr); +u32 sceKernelSetVTimerTimeWide(u32 uid, u64 timeClock); // TODO void _sceKernelReturnFromTimerHandler();