From 87a07d7355182f284be02b6a7b99061218eec324 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 2 Mar 2014 01:15:00 -0800 Subject: [PATCH] Workaround bug in Kurohyou 2 (uninitialized data.) The game calls scePsmfGetEPWithTimestamp(), but without any chapters. This means nothing is written to its pointer. But it takes the value there anyway. It happens that the value there is 0, but only because something wrote it to the stack before the call. It seems like scePsmfVerifyPsmf() is the one writing it, since it has a different value shortly before that call. So, as a workaround, just write some 0s into the stack. Games without bugs should not care. Hard to predict what will happen to another buggy game. --- Core/HLE/sceKernelModule.cpp | 2 +- Core/HLE/scePsmf.cpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 906a87e8a1..0f3c470190 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1046,7 +1046,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro for (int i = 0; i < entry->numFuncs; ++i) { // This is the id of the import. func.nid = nidDataPtr[i]; - // This is the address to write the j abnd delay slot to. + // This is the address to write the j and delay slot to. func.stubAddr = entry->firstSymAddr + i * 8; module->ImportFunc(func); } diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index e0e695e372..ed39bbde1e 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -728,6 +728,9 @@ u32 scePsmfVerifyPsmf(u32 psmfAddr) ERROR_LOG(ME, "scePsmfVerifyPsmf(%08x): bad version %08x", psmfAddr, version); return ERROR_PSMF_NOT_FOUND; } + // 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); DEBUG_LOG(ME, "scePsmfVerifyPsmf(%08x)", psmfAddr); return 0; } @@ -800,13 +803,13 @@ u32 scePsmfGetEPWithId(u32 psmfStruct, int epid, u32 entryAddr) Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x): invalid psmf", psmfStruct, epid, entryAddr); - return ERROR_PSMF_NOT_FOUND; + return ERROR_PSMF_NOT_INITIALIZED; } DEBUG_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x)", psmfStruct, epid, entryAddr); if (epid < 0 || epid >= (int)psmf->EPMap.size()) { ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i): invalid id", psmfStruct, epid); - return ERROR_PSMF_INVALID_ID; + return ERROR_PSMF_NOT_FOUND; } if (Memory::IsValidAddress(entryAddr)) { Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]); @@ -819,19 +822,19 @@ u32 scePsmfGetEPWithTimestamp(u32 psmfStruct, u32 ts, u32 entryAddr) Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x): invalid psmf", psmfStruct, ts, entryAddr); - return ERROR_PSMF_NOT_FOUND; + return ERROR_PSMF_NOT_INITIALIZED; } DEBUG_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x)", psmfStruct, ts, entryAddr); if (ts < psmf->presentationStartTime) { ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid timestamp", psmfStruct, ts); - return ERROR_PSMF_INVALID_TIMESTAMP; + return ERROR_PSMF_NOT_FOUND; } int epid = psmf->FindEPWithTimestamp(ts); if (epid < 0 || epid >= (int)psmf->EPMap.size()) { ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid id", psmfStruct, epid); - return ERROR_PSMF_INVALID_ID; + return ERROR_PSMF_NOT_FOUND; } if (Memory::IsValidAddress(entryAddr)) {