From 8211637b4c34f5cca46441b982f4d885b1c262d2 Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 8 Jan 2013 16:16:18 +0800 Subject: [PATCH 1/8] Implement sceMpegUnRegistStream & sceMpegAvcDecodeStop --- Core/HLE/FunctionWrappers.h | 5 ++ Core/HLE/sceMpeg.cpp | 93 ++++++++++++++++++++++++++++++++----- 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index a737e89e3f..cc100517fc 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -216,6 +216,11 @@ template void WrapU_UU() { RETURN(retval); } +template void WrapU_UUI() { + u32 retval = func(PARAM(0), PARAM(1), PARAM(2)); + RETURN(retval); +} + template void WrapU_CUUU() { u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); RETURN(retval); diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 47f1c89ba5..6f48269a31 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -77,6 +77,9 @@ static const int NUM_ES_BUFFERS = 2; static const int PSP_ERROR_MPEG_NO_DATA = 0x80618001; +static const int TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650 = 0X00; +static const int TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888 = 0X03; + int getMaxAheadTimestamp(const SceMpegRingBuffer &ringbuf) { return std::max(40000, ringbuf.packets * 700); // empiric value from JPCSP, thanks! } @@ -90,9 +93,10 @@ struct AvcContext { }; struct StreamInfo -{ +{ int type; int num; + int sid; }; typedef std::map StreamInfoMap; @@ -122,6 +126,7 @@ struct MpegContext { p.Do(avcRegistered); p.Do(atracRegistered); p.Do(pcmRegistered); + p.Do(dataRegistered); p.Do(isAnalyzed); p.Do(streamMap); mediaengine->DoState(p); @@ -151,6 +156,7 @@ struct MpegContext { bool avcRegistered; bool atracRegistered; bool pcmRegistered; + bool dataRegistered; bool isAnalyzed; @@ -345,8 +351,7 @@ u32 sceMpegRingbufferQueryMemSize(int packets) u32 sceMpegRingbufferConstruct(u32 ringbufferAddr, u32 numPackets, u32 data, u32 size, u32 callbackAddr, u32 callbackArg) { - DEBUG_LOG(HLE, "sceMpegRingbufferConstruct(%08x, %i, %08x, %i, %08x, %i)", - ringbufferAddr, numPackets, data, size, callbackAddr, callbackArg); + DEBUG_LOG(HLE, "sceMpegRingbufferConstruct(%08x, %i, %08x, %i, %08x, %i)", ringbufferAddr, numPackets, data, size, callbackAddr, callbackArg); SceMpegRingBuffer ring; InitRingbuffer(&ring, numPackets, data, size, callbackAddr, callbackArg); Memory::WriteStruct(ringbufferAddr, &ring); @@ -392,6 +397,7 @@ u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr, u32 f ctx->avcRegistered = false; ctx->atracRegistered = false; ctx->pcmRegistered = false; + ctx->dataRegistered = false; ctx->defaultFrameWidth = frameWidth; for (int i = 0; i < NUM_ES_BUFFERS; i++) { ctx->esBuffers[i] = false; @@ -436,12 +442,17 @@ int sceMpegAvcDecodeMode(u32 mpeg, u32 modeAddr) if (Memory::IsValidAddress(modeAddr)) { int mode = Memory::Read_U32(modeAddr); int pixelMode = Memory::Read_U32(modeAddr + 4); - ctx->videoPixelMode = pixelMode; - return 0; + if (pixelMode >= TPSM_PIXEL_STORAGE_MODE_16BIT_BGR5650 && pixelMode <= TPSM_PIXEL_STORAGE_MODE_32BIT_ABGR8888) { + ctx->videoPixelMode = pixelMode; + } else { + ERROR_LOG(HLE, "sceMpegAvcDecodeMode(%i, %i): unknown pixelMode ", mode, pixelMode); + } } else { - WARN_LOG(HLE, "sceMpegAvcDecodeMode(%08x, %08x): invalid modeAddr", mpeg, modeAddr); - return -1; + ERROR_LOG(HLE, "sceMpegAvcDecodeMode(%08x, %08x): invalid modeAddr", mpeg, modeAddr); + return -1; } + + return 0; } int sceMpegQueryStreamOffset(u32 mpeg, u32 bufferAddr, u32 offsetAddr) @@ -518,6 +529,12 @@ int sceMpegRegistStream(u32 mpeg, u32 streamType, u32 streamNum) case MPEG_PCM_STREAM: ctx->pcmRegistered = true; break; + case MPEG_DATA_STREAM: + ctx->dataRegistered = true; + break; + default : + DEBUG_LOG(HLE, "sceMpegRegistStream(%i) : unknown stream type", streamType); + break; } // ... u32 sid = streamIdGen++; @@ -672,13 +689,49 @@ u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr, u32 i u32 sceMpegAvcDecodeStop(u32 mpeg, u32 frameWidth, u32 bufferAddr, u32 statusAddr) { - ERROR_LOG(HLE, "UNIMPL sceMpegAvcDecodeStop(%08x, %08x, %08x, %08x)", mpeg, frameWidth, bufferAddr, statusAddr); + ERROR_LOG(HLE, "sceMpegAvcDecodeStop(%08x, %08x, %08x, %08x)", mpeg, frameWidth, bufferAddr, statusAddr); + if (Memory::IsValidAddress(statusAddr)) { + Memory::Write_U32(0,statusAddr); + } else { + ERROR_LOG(HLE, "sceMpegAvcDecodeStop(%08x, %08x): invalid statusAddr", mpeg, statusAddr); + return -1; + } return 0; } u32 sceMpegUnRegistStream(u32 mpeg, int streamUid) { - ERROR_LOG(HLE, "UNIMPL sceMpegUnRegistStream(%08x, %i)", mpeg, streamUid); + MpegContext *ctx = getMpegCtx(mpeg); + if (!ctx) + { + WARN_LOG(HLE, "sceMpegUnRegistStream(%08x, %i, %i): bad mpeg handle", mpeg, streamUid); + return -1; + } + + StreamInfo info; + + switch (info.type) { + case MPEG_AVC_STREAM: + ctx->avcRegistered = false; + break; + case MPEG_AUDIO_STREAM: + case MPEG_ATRAC_STREAM: + ctx->atracRegistered = false; + break; + case MPEG_PCM_STREAM: + ctx->pcmRegistered = false; + break; + case MPEG_DATA_STREAM: + ctx->dataRegistered = false; + break; + default : + DEBUG_LOG(HLE, "sceMpegUnRegistStream(%i) : unknown streamID ", streamUid); + break; + } + ctx->streamMap[streamUid] = info; + info.type = -1; + info.sid = -1 ; + ctx->isAnalyzed = false; return 0; } @@ -724,7 +777,11 @@ int sceMpegAvcDecodeYCbCr(u32 mpeg, u32 auAddr, u32 bufferAddr, u32 initAddr) u32 sceMpegAvcDecodeFlush(u32 mpeg) { + MpegContext *ctx = getMpegCtx(mpeg); ERROR_LOG(HLE, "UNIMPL sceMpegAvcDecodeFlush(%08x)", mpeg); + if ( ctx->videoFrameCount > 0 || ctx->audioFrameCount > 0) { + //__MpegFinish(); + } return 0; } @@ -787,9 +844,6 @@ int sceMpegRingbufferAvailableSize(u32 ringbufferAddr) return ringbuffer.packetsFree; } - - - void PostPutAction::run(MipsCall &call) { SceMpegRingBuffer ringbuffer; Memory::ReadStruct(ringAddr_, &ringbuffer); @@ -985,6 +1039,12 @@ u32 sceMpegChangeGetAuMode(u32 mpeg, int streamUid, int mode) return 0; } +u32 sceMpegChangeGetAvcAuMode(u32 mpeg, u32 stream_addr, int mode) +{ + ERROR_LOG(HLE, "UNIMPL sceMpegChangeGetAvcAuMode(%08x, %08x, %i)", mpeg, stream_addr, mode); + return 0; +} + u32 sceMpegGetPcmAu(u32 mpeg, int streamUid, u32 auAddr, u32 attrAddr) { ERROR_LOG(HLE, "UNIMPL sceMpegGetPcmAu(%08x, %i, %08x, %08x)", mpeg, streamUid, auAddr, attrAddr); @@ -1004,6 +1064,13 @@ u32 sceMpegFlushAllStream(u32 mpeg) return 0; } +u32 sceMpegFlushStream(u32 mpeg, int stream_addr) +{ + ERROR_LOG(HLE, "UNIMPL sceMpegFlushStream(%08x, %i)", mpeg , stream_addr); + //__MpegFinish(); + return 0; +} + u32 sceMpegAvcCopyYCbCr(u32 mpeg, u32 sourceAddr, u32 YCbCrAddr) { ERROR_LOG(HLE, "UNIMPL sceMpegAvcCopyYCbCr(%08x, %08x, %08x)", mpeg, sourceAddr, YCbCrAddr); @@ -1093,6 +1160,7 @@ const HLEFunction sceMpeg[] = {0x42560f23,WrapI_UUU,"sceMpegRegistStream"}, {0x591a4aa2,WrapU_UI,"sceMpegUnRegistStream"}, {0x707b7629,WrapU_U,"sceMpegFlushAllStream"}, + {0x500F0429,WrapU_UI,"sceMpegFlushStream"}, {0xa780cf7e,WrapI_U,"sceMpegMallocAvcEsBuf"}, {0xceb870b1,WrapI_UI,"sceMpegFreeAvcEsBuf"}, {0x167afd9e,WrapI_UUU,"sceMpegInitAu"}, @@ -1121,6 +1189,7 @@ const HLEFunction sceMpeg[] = {0x8C1E027D,WrapU_UIUU,"sceMpegGetPcmAu"}, {0xC02CF6B5,WrapI_UUU,"sceMpegQueryPcmEsSize"}, {0xC45C99CC,WrapU_UUU,"sceMpegQueryUserdataEsSize"}, + {0x234586AE,WrapU_UUI,"sceMpegChangeGetAvcAuMode"}, }; const HLEFunction sceMp3[] = From 984663b8829ed4989edbd010e38cba384df170c8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 8 Jan 2013 00:29:52 -0800 Subject: [PATCH 2/8] Add a couple unknown syscalls hit in games. Specifically Velocity and Mad Blocker Alpha. --- Core/HLE/sceAtrac.cpp | 1 + Core/HLE/sceMpeg.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp index 9a07bd8f6f..1ab805cf49 100644 --- a/Core/HLE/sceAtrac.cpp +++ b/Core/HLE/sceAtrac.cpp @@ -377,6 +377,7 @@ const HLEFunction sceAtrac3plus[] = {0x9CD7DE03,0,"sceAtracSetMOutHalfwayBufferAndGetID"}, {0x5622B7C1,WrapI_UIIU,"sceAtracSetAA3DataAndGetID"}, {0x5DD66588,0,"sceAtracSetAA3HalfwayBufferAndGetID"}, + {0x231FC6B7,0,"_sceAtracGetContextAddress"}, }; diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 47f1c89ba5..2f14504c22 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1144,6 +1144,8 @@ const HLEFunction sceMp3[] = {0xD0A56296,WrapI_U,"sceMp3CheckStreamDataNeeded"}, {0xD8F54A51,0,"sceMp3GetLoopNum"}, {0xF5478233,0,"sceMp3ReleaseMp3Handle"}, + {0xAE6D2027,0,"sceMp3GetVersion"}, + {0x3548AEC8,0,"sceMp3GetFrameNum"}, }; void Register_sceMpeg() From 79f9ebc2e11bcacc7915b4aee712c19db43b32ad Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 1 Jan 2013 18:08:42 -0800 Subject: [PATCH 3/8] Keep track of exported symbols and link them later. --- Core/HLE/HLE.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 2ebb7b5149..4ed00ba669 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -51,6 +51,7 @@ enum static std::vector moduleDB; static std::vector unresolvedSyscalls; +static std::vector exportedCalls; static int hleAfterSyscall = HLE_AFTER_NOTHING; static char hleAfterSyscallReschedReason[512]; @@ -63,6 +64,7 @@ void HLEDoState(PointerWrap &p) { Syscall sc = {0}; p.Do(unresolvedSyscalls, sc); + p.Do(exportedCalls, sc); p.DoMarker("HLE"); } @@ -71,6 +73,7 @@ void HLEShutdown() hleAfterSyscall = HLE_AFTER_NOTHING; moduleDB.clear(); unresolvedSyscalls.clear(); + exportedCalls.clear(); } void RegisterModule(const char *name, int numFunctions, const HLEFunction *funcTable) @@ -124,15 +127,26 @@ const HLEFunction *GetFunc(const char *moduleName, u32 nib) const char *GetFuncName(const char *moduleName, u32 nib) { + _dbg_assert_msg_(HLE, moduleName != NULL, "Invalid module name."); + const HLEFunction *func = GetFunc(moduleName,nib); if (func) return func->name; - else + + // Was this function exported previously? + static char temp[256]; + for (auto it = exportedCalls.begin(), end = exportedCalls.end(); it != end; ++it) { - static char temp[256]; - sprintf(temp,"[UNK: 0x%08x ]",nib); - return temp; + if (!strcmp(it->moduleName, moduleName) && it->nid == nib) + { + sprintf(temp, "[EXP: 0x%08x]", nib); + return temp; + } } + + // No good, we can't find it. + sprintf(temp,"[UNK: 0x%08x]", nib); + return temp; } u32 GetSyscallOp(const char *moduleName, u32 nib) @@ -173,17 +187,30 @@ void WriteSyscall(const char *moduleName, u32 nib, u32 address) } else { + // Did another module export this already? + for (auto it = exportedCalls.begin(), end = exportedCalls.end(); it != end; ++it) + { + if (!strcmp(it->moduleName, moduleName) && it->nid == nib) + { + Memory::Write_U32(MIPS_MAKE_J(it->symAddr), address); // j symAddr + Memory::Write_U32(MIPS_MAKE_NOP(), address + 4); // nop (delay slot) + return; + } + } + // Module inexistent.. for now; let's store the syscall for it to be resolved later INFO_LOG(HLE,"Syscall (%s,%08x) unresolved, storing for later resolving", moduleName, nib); Syscall sysc = {"", address, nib}; - strncpy(sysc.moduleName, moduleName, 32); - sysc.moduleName[31] = '\0'; + strncpy(sysc.moduleName, moduleName, KERNELOBJECT_MAX_NAME_LENGTH); + sysc.moduleName[KERNELOBJECT_MAX_NAME_LENGTH] = '\0'; unresolvedSyscalls.push_back(sysc); } } void ResolveSyscall(const char *moduleName, u32 nib, u32 address) { + _dbg_assert_msg_(HLE, moduleName != NULL, "Invalid module name."); + for (size_t i = 0; i < unresolvedSyscalls.size(); i++) { Syscall *sysc = &unresolvedSyscalls[i]; @@ -196,6 +223,11 @@ void ResolveSyscall(const char *moduleName, u32 nib, u32 address) Memory::Write_U32(MIPS_MAKE_NOP(), sysc->symAddr + 4); } } + + Syscall ex = {"", address, nib}; + strncpy(ex.moduleName, moduleName, KERNELOBJECT_MAX_NAME_LENGTH); + ex.moduleName[KERNELOBJECT_MAX_NAME_LENGTH] = '\0'; + exportedCalls.push_back(ex); } const char *GetFuncName(int moduleIndex, int func) From 8cf759bbc4f824598dcfba19ba97a1c95106146d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 4 Jan 2013 00:36:08 -0800 Subject: [PATCH 4/8] Load the exports that tell us module info. Thanks JPCSP. --- Core/HLE/sceKernelModule.cpp | 89 +++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 3a5907dd40..8d866d1d4f 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -44,6 +44,22 @@ enum { PSP_THREAD_ATTR_USER = 0x80000000 }; +enum { + // Function exports. + NID_MODULE_START = 0xD632ACDB, + NID_MODULE_STOP = 0xCEE8593C, + NID_MODULE_REBOOT_BEFORE = 0x2F064FA6, + NID_MODULE_REBOOT_PHASE = 0xADF12745, + NID_MODULE_BOOTSTART = 0xD3744BE0, + + // Variable exports. + NID_MODULE_INFO = 0xF01D73A7, + NID_MODULE_START_THREAD_PARAMETER = 0x0F7C276C, + NID_MODULE_STOP_THREAD_PARAMETER = 0xCF0CC697, + NID_MODULE_REBOOT_BEFORE_THREAD_PARAMETER = 0xF4F4299D, + NID_MODULE_SDK_VERSION = 0x11B97506, +}; + static const char *blacklistedModules[] = { "sceATRAC3plus_Library", "sceFont_Library", @@ -229,6 +245,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro { Module *module = new Module; kernelObjects.Create(module); + memset(&module->nm, 0, sizeof(module->nm)); u8 *newptr = 0; if (*(u32*)ptr == 0x4543537e) { // "~SCE" @@ -464,8 +481,66 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro { u32 nid = residentPtr[j]; u32 exportAddr = residentPtr[ent->fcount + ent->vcount + j]; - ResolveSyscall(name, nid, exportAddr); + + switch (nid) + { + case NID_MODULE_START: + module->nm.module_start_func = exportAddr; + break; + case NID_MODULE_STOP: + module->nm.module_stop_func = exportAddr; + break; + case NID_MODULE_REBOOT_BEFORE: + module->nm.module_reboot_before_func = exportAddr; + break; + case NID_MODULE_REBOOT_PHASE: + module->nm.module_reboot_phase_func = exportAddr; + break; + case NID_MODULE_BOOTSTART: + module->nm.module_bootstart_func = exportAddr; + break; + default: + ResolveSyscall(name, nid, exportAddr); + } } + + for (u32 j = 0; j < ent->vcount; j++) + { + u32 nid = residentPtr[ent->fcount + j]; + u32 exportAddr = residentPtr[ent->fcount + ent->vcount + ent->fcount + j]; + + switch (nid) + { + case NID_MODULE_INFO: + // TODO + break; + case NID_MODULE_START_THREAD_PARAMETER: + // TODO: What's at 0? + module->nm.module_start_thread_priority = Memory::Read_U32(exportAddr + 4); + module->nm.module_start_thread_stacksize = Memory::Read_U32(exportAddr + 8); + module->nm.module_start_thread_attr = Memory::Read_U32(exportAddr + 12); + break; + case NID_MODULE_STOP_THREAD_PARAMETER: + // TODO: What's at 0? + module->nm.module_stop_thread_priority = Memory::Read_U32(exportAddr + 4); + module->nm.module_stop_thread_stacksize = Memory::Read_U32(exportAddr + 8); + module->nm.module_stop_thread_attr = Memory::Read_U32(exportAddr + 12); + break; + case NID_MODULE_REBOOT_BEFORE_THREAD_PARAMETER: + // TODO: What's at 0? + module->nm.module_reboot_before_thread_priority = Memory::Read_U32(exportAddr + 4); + module->nm.module_reboot_before_thread_stacksize = Memory::Read_U32(exportAddr + 8); + module->nm.module_reboot_before_thread_attr = Memory::Read_U32(exportAddr + 12); + break; + case NID_MODULE_SDK_VERSION: + // TODO + break; + default: + // TODO + break; + } + } + if (ent->size > 4) { ent = (PspLibEntEntry*)((u8*)ent + ent->size * 4); @@ -562,6 +637,18 @@ Module *__KernelLoadModule(u8 *fileptr, SceKernelLMOption *options, std::string void __KernelStartModule(Module *m, int args, const char *argp, SceKernelSMOption *options) { + if (m->nm.module_start_func != 0 || m->nm.module_start_func != -1) + { + if (m->nm.module_start_func != m->nm.entry_addr) + WARN_LOG(LOADER, "Main module has start func (%08x) different from entry (%08x)?", m->nm.module_start_func, m->nm.entry_addr); + if (m->nm.module_start_thread_priority != 0 && m->nm.module_start_thread_priority != options->priority) + WARN_LOG(LOADER, "Main module has different priority (%02x vs. %02x)", m->nm.module_start_thread_priority, options->priority); + if (m->nm.module_start_thread_stacksize != 0 && m->nm.module_start_thread_stacksize != options->stacksize) + WARN_LOG(LOADER, "Main module has different stack size (%08x vs. %08x)", m->nm.module_start_thread_stacksize, options->stacksize); + if (m->nm.module_start_thread_attr != 0 && m->nm.module_start_thread_attr != options->attribute) + WARN_LOG(LOADER, "Main module has different attr (%08x vs. %08x)", m->nm.module_start_thread_attr, options->attribute); + } + __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); mainModuleID = m->GetUID(); //TODO: if current thread, put it in wait state, waiting for the new thread From 559095230b47cf93be2be9d2ff77a94bb5461f7d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 7 Jan 2013 01:05:26 -0800 Subject: [PATCH 5/8] Take the module info when starting the main module. Fixes Ys Seven, Fieldrunners, Shadow of Destiny, maybe others. --- Core/HLE/sceKernelModule.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 8d866d1d4f..27675b1fbc 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -641,12 +641,6 @@ void __KernelStartModule(Module *m, int args, const char *argp, SceKernelSMOptio { if (m->nm.module_start_func != m->nm.entry_addr) WARN_LOG(LOADER, "Main module has start func (%08x) different from entry (%08x)?", m->nm.module_start_func, m->nm.entry_addr); - if (m->nm.module_start_thread_priority != 0 && m->nm.module_start_thread_priority != options->priority) - WARN_LOG(LOADER, "Main module has different priority (%02x vs. %02x)", m->nm.module_start_thread_priority, options->priority); - if (m->nm.module_start_thread_stacksize != 0 && m->nm.module_start_thread_stacksize != options->stacksize) - WARN_LOG(LOADER, "Main module has different stack size (%08x vs. %08x)", m->nm.module_start_thread_stacksize, options->stacksize); - if (m->nm.module_start_thread_attr != 0 && m->nm.module_start_thread_attr != options->attribute) - WARN_LOG(LOADER, "Main module has different attr (%08x vs. %08x)", m->nm.module_start_thread_attr, options->attribute); } __KernelSetupRootThread(m->GetUID(), args, argp, options->priority, options->stacksize, options->attribute); @@ -708,6 +702,14 @@ bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std:: option.priority = 0x20; option.stacksize = 0x40000; // crazy? but seems to be the truth + // Replace start options with module-specified values if they exist. + if (module->nm.module_start_thread_attr != 0) + option.attribute = module->nm.module_start_thread_attr; + if (module->nm.module_start_thread_priority != 0) + option.priority = module->nm.module_start_thread_priority; + if (module->nm.module_start_thread_stacksize != 0) + option.stacksize = module->nm.module_start_thread_stacksize; + __KernelStartModule(module, (u32)strlen(filename) + 1, filename, &option); __KernelStartIdleThreads(); From 0619f230b69f2b306cbe273c8dd41179180e2625 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 7 Jan 2013 22:57:56 -0800 Subject: [PATCH 6/8] Cleanup some todos and logging in exports. --- Core/HLE/sceKernelModule.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 27675b1fbc..94319a8ccc 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -512,31 +512,33 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro switch (nid) { case NID_MODULE_INFO: - // TODO break; case NID_MODULE_START_THREAD_PARAMETER: - // TODO: What's at 0? + if (Memory::Read_U32(exportAddr) != 3) + WARN_LOG(LOADER, "Strange value at module_start_thread_parameter export: %08x", Memory::Read_U32(exportAddr)); module->nm.module_start_thread_priority = Memory::Read_U32(exportAddr + 4); module->nm.module_start_thread_stacksize = Memory::Read_U32(exportAddr + 8); module->nm.module_start_thread_attr = Memory::Read_U32(exportAddr + 12); break; case NID_MODULE_STOP_THREAD_PARAMETER: - // TODO: What's at 0? + if (Memory::Read_U32(exportAddr) != 3) + WARN_LOG(LOADER, "Strange value at module_stop_thread_parameter export: %08x", Memory::Read_U32(exportAddr)); module->nm.module_stop_thread_priority = Memory::Read_U32(exportAddr + 4); module->nm.module_stop_thread_stacksize = Memory::Read_U32(exportAddr + 8); module->nm.module_stop_thread_attr = Memory::Read_U32(exportAddr + 12); break; case NID_MODULE_REBOOT_BEFORE_THREAD_PARAMETER: - // TODO: What's at 0? + if (Memory::Read_U32(exportAddr) != 3) + WARN_LOG(LOADER, "Strange value at module_reboot_before_thread_parameter export: %08x", Memory::Read_U32(exportAddr)); module->nm.module_reboot_before_thread_priority = Memory::Read_U32(exportAddr + 4); module->nm.module_reboot_before_thread_stacksize = Memory::Read_U32(exportAddr + 8); module->nm.module_reboot_before_thread_attr = Memory::Read_U32(exportAddr + 12); break; case NID_MODULE_SDK_VERSION: - // TODO + DEBUG_LOG(LOADER, "Module SDK: %08x", Memory::Read_U32(exportAddr)); break; default: - // TODO + DEBUG_LOG(LOADER, "Unexpected variable with nid: %08x", nid); break; } } From da865e83dcbbdbe3c3b71266079e633719b23757 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 8 Jan 2013 00:35:55 -0800 Subject: [PATCH 7/8] Write an unknown syscall for unresolved imports. --- Core/HLE/HLE.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp index 4ed00ba669..4fcb6b93c1 100644 --- a/Core/HLE/HLE.cpp +++ b/Core/HLE/HLE.cpp @@ -204,6 +204,10 @@ void WriteSyscall(const char *moduleName, u32 nib, u32 address) strncpy(sysc.moduleName, moduleName, KERNELOBJECT_MAX_NAME_LENGTH); sysc.moduleName[KERNELOBJECT_MAX_NAME_LENGTH] = '\0'; unresolvedSyscalls.push_back(sysc); + + // Write a trap so we notice this func if it's called before resolving. + Memory::Write_U32(MIPS_MAKE_JR_RA(), address); // jr ra + Memory::Write_U32(GetSyscallOp("(invalid syscall)", nib), address + 4); } } From 72e9aed0fe12738923353447c3cc54a2879e6dfc Mon Sep 17 00:00:00 2001 From: raven02 Date: Tue, 8 Jan 2013 17:04:51 +0800 Subject: [PATCH 8/8] Implement sceMpegChangeGetAuMode --- Core/HLE/sceMpeg.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 6f48269a31..5d41e8534d 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -127,6 +127,9 @@ struct MpegContext { p.Do(atracRegistered); p.Do(pcmRegistered); p.Do(dataRegistered); + p.Do(ignoreAtrac); + p.Do(ignorePcm); + p.Do(ignoreAvc); p.Do(isAnalyzed); p.Do(streamMap); mediaengine->DoState(p); @@ -158,6 +161,10 @@ struct MpegContext { bool pcmRegistered; bool dataRegistered; + bool ignoreAtrac; + bool ignorePcm; + bool ignoreAvc; + bool isAnalyzed; StreamInfoMap streamMap; @@ -398,6 +405,9 @@ u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr, u32 f ctx->atracRegistered = false; ctx->pcmRegistered = false; ctx->dataRegistered = false; + ctx->ignoreAtrac = false; + ctx->ignorePcm = false; + ctx->ignoreAvc = false; ctx->defaultFrameWidth = frameWidth; for (int i = 0; i < NUM_ES_BUFFERS; i++) { ctx->esBuffers[i] = false; @@ -1035,7 +1045,45 @@ int sceMpegQueryPcmEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) u32 sceMpegChangeGetAuMode(u32 mpeg, int streamUid, int mode) { - ERROR_LOG(HLE, "UNIMPL sceMpegChangeGetAuMode(%08x, %i, %i)", mpeg, streamUid, mode); + MpegContext *ctx = getMpegCtx(mpeg); + if (!ctx) { + WARN_LOG(HLE, "sceMpegChangeGetAuMode(%08x, %i, %i): bad mpeg handle", mpeg, streamUid, mode); + return -1; + } + + StreamInfo info; + info.sid = streamUid; + if (info.sid) { + switch (info.type) { + case MPEG_AVC_STREAM: + if(mode == MPEG_AU_MODE_DECODE) { + ctx->ignoreAvc = false; + } else if (mode == MPEG_AU_MODE_SKIP) { + ctx->ignoreAvc = true; + } + break; + case MPEG_AUDIO_STREAM: + case MPEG_ATRAC_STREAM: + if(mode == MPEG_AU_MODE_DECODE) { + ctx->ignoreAtrac = false; + } else if (mode == MPEG_AU_MODE_SKIP) { + ctx->ignoreAtrac = true; + } + break; + case MPEG_PCM_STREAM: + if(mode == MPEG_AU_MODE_DECODE) { + ctx->ignorePcm = false; + } else if (mode == MPEG_AU_MODE_SKIP) { + ctx->ignorePcm = true; + } + break; + default: + ERROR_LOG(HLE, "UNIMPL sceMpegChangeGetAuMode(%08x, %i): unkown streamID", mpeg, streamUid); + break; + } + } else { + ERROR_LOG(HLE, "UNIMPL sceMpegChangeGetAuMode(%08x, %i): unkown streamID", mpeg, streamUid); + } return 0; } @@ -1060,7 +1108,11 @@ u32 sceMpegRingbufferQueryPackNum(int memorySize) u32 sceMpegFlushAllStream(u32 mpeg) { + MpegContext *ctx = getMpegCtx(mpeg); ERROR_LOG(HLE, "UNIMPL sceMpegFlushAllStream(%08x)", mpeg); + if ( ctx->videoFrameCount > 0 || ctx->audioFrameCount > 0) { + //__MpegFinish(); + } return 0; } @@ -1108,7 +1160,7 @@ int sceMpegAvcQueryYCbCrSize(u32 mpeg, u32 mode, u32 width, u32 height, u32 resu if ((width & 15) != 0 || (height & 15) != 0 || height > 272 || width > 480) { ERROR_LOG(HLE, "sceMpegAvcQueryYCbCrSize: bad w/h %i x %i", width, height); - return -1; + return ERROR_MPEG_INVALID_VALUE; } DEBUG_LOG(HLE, "sceMpegAvcQueryYCbCrSize(%08x, %i, %i, %i, %08x)", mpeg, mode, width, height, resultAddr);