From 449eceadbab3b065c50a558fd65f8a7eb3db6d16 Mon Sep 17 00:00:00 2001 From: Arthur Blot Date: Thu, 8 Nov 2012 14:21:55 +0100 Subject: [PATCH 1/4] Fix reading ISO pathes with 2 following slashes --- Core/FileSystems/ISOFileSystem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index ad52a963a6..cf5261d0db 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -260,6 +260,8 @@ ISOFileSystem::TreeEntry *ISOFileSystem::GetFromPath(std::string path) if (path.length() == 0 || (path.length()==1 && path[0] == '/')) return e; path.erase(0, 1); + while (path[0] == '/') + path.erase(0, 1); } else { From 4fedfc72f62e04d9a960a0b1f656e992cfb2b8ad Mon Sep 17 00:00:00 2001 From: Arthur Blot Date: Thu, 8 Nov 2012 14:23:55 +0100 Subject: [PATCH 2/4] Implemented the EN vcmp instruction --- Core/MIPS/MIPSIntVFPU.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index d2423d6c18..ece6463551 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -1124,8 +1124,9 @@ namespace MIPSInt case VC_GE: c = s[i] >= t[i]; break; case VC_NZ: c = s[i] != 0; break; case VC_ES: c = (s[i] != s[i]) || (s[i] == std::numeric_limits::infinity()); break; // Tekken Dark Resurrection + case VC_EN: c = isnan(s[i]); break; default: - _dbg_assert_msg_(CPU,0,"Unsupported vcmp condition code"); //, cond); + _dbg_assert_msg_(CPU,0,"Unsupported vcmp condition code %d", cond); return; } cc |= (c< Date: Thu, 8 Nov 2012 14:24:51 +0100 Subject: [PATCH 3/4] Implemented MBXes --- Core/HLE/FunctionWrappers.h | 25 +++ Core/HLE/sceKernel.cpp | 16 +- Core/HLE/sceKernelMbx.cpp | 309 +++++++++++++++++++++++++---------- Core/HLE/sceKernelMbx.h | 34 +++- Core/HLE/sceKernelMemory.cpp | 2 +- Core/HLE/sceKernelThread.cpp | 9 + Core/HLE/sceKernelThread.h | 1 + Globals.h | 1 + 8 files changed, 291 insertions(+), 106 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index e0a43585cf..a93eebf8ac 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -38,6 +38,16 @@ template void WrapU_U() { RETURN(retval); } +template void WrapI_U() { + int retval = func(PARAM(0)); + RETURN(retval); +} + +template void WrapI_I() { + int retval = func(PARAM(0)); + RETURN(retval); +} + template void WrapV_U() { func(PARAM(0)); } @@ -51,6 +61,11 @@ template void WrapU_UU() { RETURN(retval); } +template void WrapI_IU() { + int retval = func(PARAM(0), PARAM(1)); + RETURN(retval); +} + template void WrapI_CU() { int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); RETURN(retval); @@ -71,6 +86,11 @@ template void WrapU_UUU() { RETURN(retval); } +template void WrapI_IUU() { + int retval = func(PARAM(0), PARAM(1), PARAM(2)); + RETURN(retval); +} + template void WrapV_UUU() { func(PARAM(0), PARAM(1), PARAM(2)); } @@ -89,6 +109,11 @@ template void WrapU_UUUUU() { RETURN(retval); } +template void WrapU_CIUIU() { + int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4)); + RETURN(retval); +} + template void WrapU_UUUUUU() { u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index a91ba5816e..6ccf4fabb6 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -387,14 +387,14 @@ const HLEFunction ThreadManForUser[] = {0x2A3D44FF,sceKernelGetCallbackCount,"sceKernelGetCallbackCount"}, {0x730ED8BC,sceKernelReferCallbackStatus,"sceKernelReferCallbackStatus"}, - {0x8125221D,sceKernelCreateMbx,"sceKernelCreateMbx"}, - {0x86255ADA,sceKernelDeleteMbx,"sceKernelDeleteMbx"}, - {0xE9B3061E,sceKernelSendMbx,"sceKernelSendMbx"}, - {0x18260574,sceKernelReceiveMbx,"sceKernelReceiveMbx"}, - {0xF3986382,sceKernelReceiveMbxCB,"sceKernelReceiveMbxCB"}, - {0x0D81716A,sceKernelPollMbx,"sceKernelPollMbx"}, - {0x87D4DD36,sceKernelCancelReceiveMbx,"sceKernelCancelReceiveMbx"}, - {0xA8E8C846,sceKernelReferMbxStatus,"sceKernelReferMbxStatus"}, + {0x8125221D,&WrapU_CIUIU,"sceKernelCreateMbx"}, + {0x86255ADA,&WrapI_I,"sceKernelDeleteMbx"}, + {0xE9B3061E,&WrapI_IU,"sceKernelSendMbx"}, + {0x18260574,&WrapI_IUU,"sceKernelReceiveMbx"}, + {0xF3986382,&WrapI_IUU,"sceKernelReceiveMbxCB"}, + {0x0D81716A,&WrapI_IU,"sceKernelPollMbx"}, + {0x87D4DD36,&WrapI_IU,"sceKernelCancelReceiveMbx"}, + {0xA8E8C846,&WrapI_IU,"sceKernelReferMbxStatus"}, {0x7C0DC2A0,sceKernelCreateMsgPipe,"sceKernelCreateMsgPipe"}, {0xF0B7DA1C,sceKernelDeleteMsgPipe,"sceKernelDeleteMsgPipe"}, diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index 6504282152..db1462ba8c 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -20,14 +20,10 @@ #include "sceKernelMbx.h" #include "HLE.h" -struct NativeMbxPacket -{ - u32 next; - u8 priority; - u8 padding[3]; +#define SCE_KERNEL_MBA_THPRI 0x100 +#define SCE_KERNEL_MBA_MSPRI 0x400 - // data follows -}; +// TODO: when a thread is being resumed (message received or cancellation), sceKernelReceiveMbx() always returns 0 struct NativeMbx { @@ -46,20 +42,34 @@ struct Mbx : public KernelObject static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_MBXID; } int GetIDType() const { return SCE_KERNEL_TMID_Mbox; } + void AddWaitingThread(SceUID id, u32 addr) + { + if (nmb.attr & SCE_KERNEL_MBA_THPRI) + { + for (std::vector>::iterator it = waitingThreads.begin(); it != waitingThreads.end(); it++) + { + if (__KernelGetThreadPrio(id) >= __KernelGetThreadPrio((*it).first)) + { + waitingThreads.insert(it, std::make_pair(id, addr)); + break; + } + } + } + else + { + waitingThreads.push_back(std::make_pair(id, addr)); + } + } + NativeMbx nmb; - std::vector receiveWaitingThreads; + std::vector> waitingThreads; + std::vector messageQueue; }; -void sceKernelCreateMbx() +SceUID sceKernelCreateMbx(const char *name, int memoryPartition, SceUInt attr, int size, u32 optAddr) { - const char *name = Memory::GetCharPointer(PARAM(0)); - int memoryPartition = PARAM(1); - SceUInt attr = PARAM(2); - int size = PARAM(3); - int opt = PARAM(4); - - ERROR_LOG(HLE, "sceKernelCreateMbx(%s, %i, %08x, %i, %08x)", name, memoryPartition, attr, size, opt); + DEBUG_LOG(HLE, "sceKernelCreateMbx(%s, %i, %08x, %i, %08x)", name, memoryPartition, attr, size, optAddr); Mbx *m = new Mbx(); SceUID id = kernelObjects.Create(m); @@ -71,89 +81,210 @@ void sceKernelCreateMbx() m->nmb.numMessages = 0; m->nmb.packetListHead = 0; - RETURN(id); + return id; } -void sceKernelDeleteMbx() +int sceKernelDeleteMbx(SceUID id) { - SceUInt uid = PARAM(0); - ERROR_LOG(HLE, "sceKernelDeleteMbx(%i)", uid); - RETURN(kernelObjects.Destroy(uid)); + DEBUG_LOG(HLE, "sceKernelDeleteMbx(%i)", id); + return kernelObjects.Destroy(id); } -void sceKernelSendMbx() +int sceKernelSendMbx(SceUID id, u32 packetAddr) { - SceUInt uid = PARAM(0); - u32 packetAddr = PARAM(1); - - ERROR_LOG(HLE, "UNIMPL sceKernelSendMbx(%i, %08x)", uid, packetAddr); - RETURN(0); -} - -void sceKernelReceiveMbx() -{ - SceUInt uid = PARAM(0); - u32 packetAddrPtr = PARAM(1); - u32 timeoutPtr = PARAM(2); - - ERROR_LOG(HLE, "UNIMPL sceKernelReceiveMbx(%i, %08x, %08x)", uid, packetAddrPtr, timeoutPtr); - RETURN(SCE_KERNEL_ERROR_MBOX_NOMSG); -} - -void sceKernelReceiveMbxCB() -{ - SceUInt uid = PARAM(0); - u32 packetAddrPtr = PARAM(1); - u32 timeoutPtr = PARAM(2); - __KernelCheckCallbacks(); - - ERROR_LOG(HLE, "UNIMPL sceKernelReceiveMbxCB(%i, %08x, %08x)", uid, packetAddrPtr, timeoutPtr); - RETURN(SCE_KERNEL_ERROR_MBOX_NOMSG); -} - -void sceKernelPollMbx() -{ - SceUInt uid = PARAM(0); - u32 packetAddrPtr = PARAM(1); - - ERROR_LOG(HLE, "UNIMPL sceKernelPollMbx(%i, %08x)", uid, packetAddrPtr); - RETURN(SCE_KERNEL_ERROR_MBOX_NOMSG); -} - -void sceKernelCancelReceiveMbx() -{ - SceUInt uid = PARAM(0); - int numWaitingThreadsAddr = PARAM(1); - - ERROR_LOG(HLE, "UNIMPL sceKernelCancelReceiveMbx(%i, %i)", uid, numWaitingThreadsAddr); - RETURN(0); -} - -void sceKernelCancelMbx() -{ - SceUInt uid = PARAM(0); - u32 numSendThreads = PARAM(1); - u32 numReceiveThreads = PARAM(2); - - ERROR_LOG(HLE, "UNIMPL sceKernelCancelMbx(%i, %i, %i)", uid, numSendThreads, numReceiveThreads); - RETURN(0); -} - -void sceKernelReferMbxStatus() -{ - SceUInt uid = PARAM(0); - u32 mbxStatusAddr = PARAM(1); - - ERROR_LOG(HLE, "sceKernelReferMbxStatus(%i, %08x)", uid, mbxStatusAddr); u32 error; - Mbx *mp = kernelObjects.Get(uid, error); - if (mp) + Mbx *m = kernelObjects.Get(id, error); + NativeMbxPacket *addPacket = (NativeMbxPacket*)Memory::GetPointer(packetAddr); + if (addPacket == 0) { - Memory::WriteStruct(mbxStatusAddr, &mp->nmb); - RETURN(0); + ERROR_LOG(HLE, "sceKernelSendMbx(%i, %08x): invalid packet address", id, packetAddr); + return -1; + } + + if (!m) + { + ERROR_LOG(HLE, "sceKernelSendMbx(%i, %08x): invalid mbx id", id, packetAddr); + return error; + } + + if (m->waitingThreads.empty()) + { + DEBUG_LOG(HLE, "sceKernelSendMbx(%i, %08x): no threads currently waiting, adding message to queue", id, packetAddr); + if (m->nmb.attr & SCE_KERNEL_MBA_MSPRI) + { + for (std::vector::iterator it = m->messageQueue.begin(); it != m->messageQueue.end(); it++) + { + NativeMbxPacket *p = (NativeMbxPacket*)Memory::GetPointer(*it); + if (addPacket->priority >= p->priority) + { + m->messageQueue.insert(it, packetAddr); + break; + } + } + } + else + { + m->messageQueue.push_back(packetAddr); + } + } + else if (m->messageQueue.empty()) + { + Memory::Write_U32(packetAddr, m->waitingThreads.front().second); + __KernelResumeThreadFromWait(m->waitingThreads.front().first); + DEBUG_LOG(HLE, "sceKernelSendMbx(%i, %08x): threads waiting, resuming %d", id, packetAddr, m->waitingThreads.front().first); + m->waitingThreads.erase(m->waitingThreads.begin()); + __KernelReSchedule(); } else { - RETURN(error); + ERROR_LOG(HLE, "sceKernelSendMbx(%i, %08x): WTF!? thread waiting while there is a message in the queue?", id, packetAddr); + } + return 0; +} + +int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) +{ + u32 error; + Mbx *m = kernelObjects.Get(id, error); + + if (!m) + { + ERROR_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): invalid mbx id", id, packetAddrPtr, timeoutPtr); + return error; + } + + if (!m->messageQueue.empty()) + { + DEBUG_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): sending first queue message", id, packetAddrPtr, timeoutPtr); + Memory::Write_U32(m->messageQueue.front(), packetAddrPtr); + m->messageQueue.erase(m->messageQueue.begin()); + } + else + { + DEBUG_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): no message in queue, waiting", id, packetAddrPtr, timeoutPtr); + m->AddWaitingThread(__KernelGetCurThread(), packetAddrPtr); + __KernelWaitCurThread(WAITTYPE_MBX, 0, 0, 0, false); // ? + } + + return 0; +} + +int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) +{ + u32 error; + Mbx *m = kernelObjects.Get(id, error); + __KernelCheckCallbacks(); + + if (!m) + { + ERROR_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): invalid mbx id", id, packetAddrPtr, timeoutPtr); + return error; + } + + if (!m->messageQueue.empty()) + { + DEBUG_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): sending first queue message", id, packetAddrPtr, timeoutPtr); + Memory::Write_U32(m->messageQueue.front(), packetAddrPtr); + m->messageQueue.erase(m->messageQueue.begin()); + } + else + { + DEBUG_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): no message in queue, waiting", id, packetAddrPtr, timeoutPtr); + m->AddWaitingThread(id, packetAddrPtr); + __KernelWaitCurThread(WAITTYPE_MBX, 0, 0, 0, true); // ? + } + + return 0; +} + +int sceKernelPollMbx(SceUID id, u32 packetAddrPtr) +{ + u32 error; + Mbx *m = kernelObjects.Get(id, error); + + if (!m) + { + ERROR_LOG(HLE, "sceKernelPollMbx(%i, %08x): invalid mbx id", id, packetAddrPtr); + return error; + } + + if (!m->messageQueue.empty()) + { + DEBUG_LOG(HLE, "sceKernelPollMbx(%i, %08x): sending first queue message", id, packetAddrPtr); + Memory::Write_U32(m->messageQueue.front(), packetAddrPtr); + m->messageQueue.erase(m->messageQueue.begin()); + return 0; + } + else + { + DEBUG_LOG(HLE, "SCE_KERNEL_ERROR_MBOX_NOMSG=sceKernelPollMbx(%i, %08x): no message in queue", id, packetAddrPtr); + return SCE_KERNEL_ERROR_MBOX_NOMSG; } } + +int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr) +{ + u32 error; + Mbx *m = kernelObjects.Get(id, error); + int *numWaitingThreads = (int*)Memory::GetPointer(numWaitingThreadsAddr); + + if (!m) + { + ERROR_LOG(HLE, "sceKernelCancelReceiveMbx(%i, %08x): invalid mbx id", id, numWaitingThreadsAddr); + return error; + } + + u32 count = m->waitingThreads.size(); + DEBUG_LOG(HLE, "sceKernelCancelReceiveMbx(%i, %08x): cancelling %d threads", id, numWaitingThreadsAddr, count); + for (size_t i = 0; i < m->waitingThreads.size(); i++) + { + Memory::Write_U32(0, m->waitingThreads[i].second); + __KernelResumeThreadFromWait(m->waitingThreads[i].first); + } + m->waitingThreads.clear(); + if (numWaitingThreads) + *numWaitingThreads = count; + return 0; +} + +int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) +{ + u32 error; + Mbx *m = kernelObjects.Get(id, error); + if (!m) + { + ERROR_LOG(HLE, "sceKernelReferMbxStatus(%i, %08x): invalid mbx id", id, infoAddr); + return error; + } + + SceKernelMbxInfo *info = (SceKernelMbxInfo*)Memory::GetPointer(infoAddr); + DEBUG_LOG(HLE, "sceKernelReferMbxStatus(%i, %08x)", id, infoAddr); + if (info) + { + strncpy(info->name, m->nmb.name, 32); + info->attr = m->nmb.attr; + info->numWaitThreads = m->waitingThreads.size(); + info->numMessage = m->messageQueue.size(); + // Fill the 'next' parameter of packets which we don't use by default but could be used by a game + if (m->messageQueue.size() != 0) + { + info->topPacketAddr = m->messageQueue[0]; + for (u32 i = 0; i < m->messageQueue.size() - 1; i++) + { + Memory::Write_U32(m->messageQueue[i + 1], Memory::Read_U32(m->messageQueue[i])); + } + Memory::Write_U32(m->messageQueue[m->messageQueue.size() - 1], 0); + } + else + { + info->topPacketAddr = 0; + } + } + else + { + return -1; + } + + return 0; +} + diff --git a/Core/HLE/sceKernelMbx.h b/Core/HLE/sceKernelMbx.h index 1b08d24472..79c3170144 100644 --- a/Core/HLE/sceKernelMbx.h +++ b/Core/HLE/sceKernelMbx.h @@ -17,11 +17,29 @@ #pragma once -void sceKernelCreateMbx(); -void sceKernelDeleteMbx(); -void sceKernelSendMbx(); -void sceKernelReceiveMbx(); -void sceKernelReceiveMbxCB(); -void sceKernelPollMbx(); -void sceKernelCancelReceiveMbx(); -void sceKernelReferMbxStatus(); \ No newline at end of file +struct NativeMbxPacket +{ + u32 next; + u8 priority; + u8 padding[3]; +}; + +struct SceKernelMbxInfo +{ + SceSize size; + char name[KERNELOBJECT_MAX_NAME_LENGTH+1]; + SceUInt attr; + int numWaitThreads; + int numMessage; + u32 topPacketAddr; +}; + +SceUID sceKernelCreateMbx(const char *name, int memoryPartition, SceUInt attr, int size, u32 optAddr); +int sceKernelDeleteMbx(SceUID id); +int sceKernelSendMbx(SceUID id, u32 addPacketAddr); +int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); +int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); +int sceKernelPollMbx(SceUID id, u32 packetAddrPtr); +int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr); +int sceKernelReferMbxStatus(SceUID id, u32 infoAddr); + diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 884a89911b..b9f03db52f 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -349,7 +349,7 @@ public: PartitionMemoryBlock(BlockAllocator *_alloc, u32 size, bool fromEnd) { alloc = _alloc; - address = alloc->Alloc(size, fromEnd); + address = alloc->Alloc(size, fromEnd, "PMB"); alloc->ListBlocks(); } ~PartitionMemoryBlock() diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 624b204ed3..234b708eb4 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1103,6 +1103,15 @@ void sceKernelDelayThread() __KernelWaitCurThread(WAITTYPE_DELAY, curThread, 0, 0, false); } +u32 __KernelGetThreadPrio(SceUID id) +{ + u32 error; + Thread *thread = kernelObjects.Get(id, error); + if (thread) + return thread->nt.currentPriority; + return 0; +} + ////////////////////////////////////////////////////////////////////////// // WAIT/SLEEP ETC ////////////////////////////////////////////////////////////////////////// diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index c1bd307547..92f88c8dc7 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -133,6 +133,7 @@ SceUID __KernelGetCurThread(); void __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(); void __KernelReturnFromThread(); // Called as HLE function +u32 __KernelGetThreadPrio(SceUID id); void _sceKernelIdle(); diff --git a/Globals.h b/Globals.h index 9de536c700..5573601147 100644 --- a/Globals.h +++ b/Globals.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "Log.h" From 35c7b411aa089d56c8a4bb75335b5b7f4ee38de3 Mon Sep 17 00:00:00 2001 From: Arthur Blot Date: Thu, 8 Nov 2012 16:24:06 +0100 Subject: [PATCH 4/4] Fixed value returning for MBXes --- Core/HLE/FunctionWrappers.h | 9 ++++++--- Core/HLE/sceKernel.cpp | 6 +++--- Core/HLE/sceKernelMbx.cpp | 30 ++++++++++++++++++------------ Core/HLE/sceKernelMbx.h | 6 +++--- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index a93eebf8ac..bab7866fd7 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -66,6 +66,10 @@ template void WrapI_IU() { RETURN(retval); } +template void WrapV_IU() { + func(PARAM(0), PARAM(1)); +} + template void WrapI_CU() { int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1)); RETURN(retval); @@ -86,9 +90,8 @@ template void WrapU_UUU() { RETURN(retval); } -template void WrapI_IUU() { - int retval = func(PARAM(0), PARAM(1), PARAM(2)); - RETURN(retval); +template void WrapV_IUU() { + func(PARAM(0), PARAM(1), PARAM(2)); } template void WrapV_UUU() { diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 6ccf4fabb6..6116b777c1 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -389,9 +389,9 @@ const HLEFunction ThreadManForUser[] = {0x8125221D,&WrapU_CIUIU,"sceKernelCreateMbx"}, {0x86255ADA,&WrapI_I,"sceKernelDeleteMbx"}, - {0xE9B3061E,&WrapI_IU,"sceKernelSendMbx"}, - {0x18260574,&WrapI_IUU,"sceKernelReceiveMbx"}, - {0xF3986382,&WrapI_IUU,"sceKernelReceiveMbxCB"}, + {0xE9B3061E,&WrapV_IU,"sceKernelSendMbx"}, + {0x18260574,&WrapV_IUU,"sceKernelReceiveMbx"}, + {0xF3986382,&WrapV_IUU,"sceKernelReceiveMbxCB"}, {0x0D81716A,&WrapI_IU,"sceKernelPollMbx"}, {0x87D4DD36,&WrapI_IU,"sceKernelCancelReceiveMbx"}, {0xA8E8C846,&WrapI_IU,"sceKernelReferMbxStatus"}, diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index db1462ba8c..0378b1e85a 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -90,7 +90,7 @@ int sceKernelDeleteMbx(SceUID id) return kernelObjects.Destroy(id); } -int sceKernelSendMbx(SceUID id, u32 packetAddr) +void sceKernelSendMbx(SceUID id, u32 packetAddr) { u32 error; Mbx *m = kernelObjects.Get(id, error); @@ -98,13 +98,15 @@ int sceKernelSendMbx(SceUID id, u32 packetAddr) if (addPacket == 0) { ERROR_LOG(HLE, "sceKernelSendMbx(%i, %08x): invalid packet address", id, packetAddr); - return -1; + RETURN(-1); + return; } if (!m) { ERROR_LOG(HLE, "sceKernelSendMbx(%i, %08x): invalid mbx id", id, packetAddr); - return error; + RETURN(error); + return; } if (m->waitingThreads.empty()) @@ -126,6 +128,7 @@ int sceKernelSendMbx(SceUID id, u32 packetAddr) { m->messageQueue.push_back(packetAddr); } + RETURN(0); } else if (m->messageQueue.empty()) { @@ -133,16 +136,17 @@ int sceKernelSendMbx(SceUID id, u32 packetAddr) __KernelResumeThreadFromWait(m->waitingThreads.front().first); DEBUG_LOG(HLE, "sceKernelSendMbx(%i, %08x): threads waiting, resuming %d", id, packetAddr, m->waitingThreads.front().first); m->waitingThreads.erase(m->waitingThreads.begin()); + RETURN(0); __KernelReSchedule(); } else { ERROR_LOG(HLE, "sceKernelSendMbx(%i, %08x): WTF!? thread waiting while there is a message in the queue?", id, packetAddr); + RETURN(-1); } - return 0; } -int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) +void sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) { u32 error; Mbx *m = kernelObjects.Get(id, error); @@ -150,7 +154,8 @@ int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) if (!m) { ERROR_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): invalid mbx id", id, packetAddrPtr, timeoutPtr); - return error; + RETURN(error); + return; } if (!m->messageQueue.empty()) @@ -158,18 +163,18 @@ int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) DEBUG_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): sending first queue message", id, packetAddrPtr, timeoutPtr); Memory::Write_U32(m->messageQueue.front(), packetAddrPtr); m->messageQueue.erase(m->messageQueue.begin()); + RETURN(0); } else { DEBUG_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): no message in queue, waiting", id, packetAddrPtr, timeoutPtr); m->AddWaitingThread(__KernelGetCurThread(), packetAddrPtr); + RETURN(0); __KernelWaitCurThread(WAITTYPE_MBX, 0, 0, 0, false); // ? } - - return 0; } -int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) +void sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) { u32 error; Mbx *m = kernelObjects.Get(id, error); @@ -178,7 +183,8 @@ int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) if (!m) { ERROR_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): invalid mbx id", id, packetAddrPtr, timeoutPtr); - return error; + RETURN(error); + return; } if (!m->messageQueue.empty()) @@ -186,15 +192,15 @@ int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) DEBUG_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): sending first queue message", id, packetAddrPtr, timeoutPtr); Memory::Write_U32(m->messageQueue.front(), packetAddrPtr); m->messageQueue.erase(m->messageQueue.begin()); + RETURN(0); } else { DEBUG_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): no message in queue, waiting", id, packetAddrPtr, timeoutPtr); m->AddWaitingThread(id, packetAddrPtr); + RETURN(0); __KernelWaitCurThread(WAITTYPE_MBX, 0, 0, 0, true); // ? } - - return 0; } int sceKernelPollMbx(SceUID id, u32 packetAddrPtr) diff --git a/Core/HLE/sceKernelMbx.h b/Core/HLE/sceKernelMbx.h index 79c3170144..e841dcb6d0 100644 --- a/Core/HLE/sceKernelMbx.h +++ b/Core/HLE/sceKernelMbx.h @@ -36,9 +36,9 @@ struct SceKernelMbxInfo SceUID sceKernelCreateMbx(const char *name, int memoryPartition, SceUInt attr, int size, u32 optAddr); int sceKernelDeleteMbx(SceUID id); -int sceKernelSendMbx(SceUID id, u32 addPacketAddr); -int sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); -int sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); +void sceKernelSendMbx(SceUID id, u32 addPacketAddr); +void sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); +void sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); int sceKernelPollMbx(SceUID id, u32 packetAddrPtr); int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr); int sceKernelReferMbxStatus(SceUID id, u32 infoAddr);