From aa28c0f40d5758f93b1825766eca4db904f8e063 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 5 Jul 2014 17:09:03 -0700 Subject: [PATCH 1/3] Improve a crash in disassembly on game shutdown. --- Core/System.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/System.cpp b/Core/System.cpp index 437b1f6716..375068f532 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -315,9 +315,10 @@ void System_Wake() { static bool pspIsInited = false; static bool pspIsIniting = false; +static bool pspIsQuiting = false; bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) { - if (pspIsIniting) { + if (pspIsIniting || pspIsQuiting) { return false; } @@ -394,12 +395,12 @@ bool PSP_IsIniting() { } bool PSP_IsInited() { - return pspIsInited; + return pspIsInited && !pspIsQuiting; } void PSP_Shutdown() { // Do nothing if we never inited. - if (!pspIsInited && !pspIsIniting) { + if (!pspIsInited && !pspIsIniting && !pspIsQuiting) { return; } @@ -409,6 +410,8 @@ void PSP_Shutdown() { } #endif + // Make sure things know right away that PSP memory, etc. is going away. + pspIsQuiting = true; if (coreState == CORE_RUNNING) Core_UpdateState(CORE_ERROR); Core_NotifyShutdown(); @@ -426,6 +429,7 @@ void PSP_Shutdown() { currentMIPS = 0; pspIsInited = false; pspIsIniting = false; + pspIsQuiting = false; } void PSP_RunLoopUntil(u64 globalticks) { From 1fd621494515d034cc830704e8a765d0929e8ea0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 5 Jul 2014 17:09:55 -0700 Subject: [PATCH 2/3] Improve function range detection. This improves a pattern like this: j endOfLoop; li v0, 0; startOfLoop: addiu v0, v0, 1 endOfLoop: bne v0, a0, startOfLoop; nop jr ra nop Where it jumps to the end of the loop, which only jumps back to the top of the loop. This might misdetect a few cases of tail recursion, but only when the funcs are right next to each other. Also, stops scanning at a jr ra, which was causing funcs to be incorrectly long in cases. --- Core/MIPS/MIPSAnalyst.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 407f4ae7d8..263ac0d89e 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -201,7 +201,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0x52d5141545a75eda, 60, "dl_write_clutformat", }, { 0x530cbe1ce9b45d58, 108, "dl_write_light_vector", }, { 0x53c9aa23504a630f, 96, "vmmul_q_5", }, - { 0x54015ccbcbc75374, 24, "strlen", }, + { 0x54015ccbcbc75374, 24, "strlen", }, // Metal Gear Solid: Peace Walker demo { 0x5550d87a851c218c, 168, "dl_write_viewport", }, { 0x55c1294280bfade0, 88, "dl_write_blend_fixed", }, { 0x56c9929e8c8c5768, 24, "fabsf", }, @@ -413,7 +413,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0xfb4253a1d9d9df9f, 20, "isnanf", }, { 0xfd34a9ad94fa6241, 76, "__extendsfdf2", }, { 0xfe4f0280240008e9, 28, "vavg_q", }, - { 0xfe5dd338ab862291, 216, "memset", }, + { 0xfe5dd338ab862291, 216, "memset", }, // Metal Gear Solid: Peace Walker demo { 0xffc8f5f8f946152c, 192, "dl_write_light_color", }, }; @@ -755,6 +755,9 @@ skip: closestJumpbackTarget = target; } } + if (aheadOp == MIPS_MAKE_JR_RA()) { + break; + } } if (closestJumpbackAddr != INVALIDTARGET && furthestJumpbackAddr == INVALIDTARGET) { @@ -846,7 +849,8 @@ skip: } // A jump later. Probably tail, but let's check if it jumps back. - u32 knownEnd = furthestBranch == 0 ? addr : furthestBranch; + // We use + 8 here in case it jumps right back to the delay slot. We'll consider that inside the func. + u32 knownEnd = furthestBranch == 0 ? addr + 8 : furthestBranch; u32 jumpback = ScanAheadForJumpback(sureTarget, currentFunction.start, knownEnd); if (jumpback != INVALIDTARGET && jumpback > addr && jumpback > knownEnd) { furthestBranch = jumpback; From a59d8b5c1f3b50d672937e5b134cd485da736a48 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 5 Jul 2014 18:09:46 -0700 Subject: [PATCH 3/3] Override the codehashing func used in Peace Walker. This makes the demo work fine even with jit enabled. May help the full game when fighting a certain boss. --- Core/HLE/ReplaceTables.cpp | 32 ++++++++++++++++++++++++++++++++ Core/MIPS/MIPSAnalyst.cpp | 1 + 2 files changed, 33 insertions(+) diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 58967b3a8f..2fca8939d8 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -458,6 +458,37 @@ static int Replace_dl_write_matrix() { return 60; } +static int Replace_peacewalker_codehash() { + u32 srcPtr = PARAM(1); + const u32 size = PARAM(2); + const u32 *table = (const u32 *)Memory::GetPointer(PARAM(3)); + const u32 salt = PARAM(4); + + // Note: this seems like an anti-cheat device, makes sure code doesn't get modified. + // It detects emuhacks being modified, so we override it here. + // We could clear the jit, but this is called a ton, and that wouldn't fix replacements. + + // We need it aligned to read behind the emuhacks. + u32 offset = srcPtr & 3; + u32 srcOffset = srcPtr & ~3; + u32 sizeOffset = offset + size; + + u32 hash = ~PARAM(0); + for (u32 i = 0; i < sizeOffset; i += 4) { + union { u32 w; u8 b[4]; } word; + word.w = Memory::Read_Instruction(srcOffset + i, true).encoding; + const u32 remaining = std::min(4U, size - i); + for (u32 j = offset; j < remaining; ++j) { + const u8 index = (word.b[j] ^ hash) & 0xFF; + hash = table[index] ^ salt ^ (hash >> 8); + } + offset = 0; + } + RETURN(~hash); + + return 9 + 13 * size; +} + static bool GetMIPSStaticAddress(u32 &addr, s32 lui_offset, s32 lw_offset) { const MIPSOpcode upper = Memory::Read_Instruction(currentMIPS->pc + lui_offset, true); if (upper != MIPS_MAKE_LUI(MIPS_GET_RT(upper), upper & 0xffff)) { @@ -586,6 +617,7 @@ static const ReplacementTableEntry entries[] = { { "topx_create_saveicon", &Hook_topx_create_saveicon, 0, REPFLAG_HOOKENTER, 0x34}, { "ff1_battle_effect", &Hook_ff1_battle_effect, 0, REPFLAG_HOOKENTER}, { "dissidia_recordframe_avi", &Hook_dissidia_recordframe_avi, 0, REPFLAG_HOOKENTER}, + { "peacewalker_codehash", &Replace_peacewalker_codehash, 0, 0}, {} }; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 263ac0d89e..944d09d833 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -299,6 +299,7 @@ static const HardHashTableEntry hardcodedHashes[] = { { 0xa2bcef60a550a3ef, 92, "matrix_rot_z", }, { 0xa373f55c65cd757a, 312, "memcpy_swizzled" }, // God Eater Burst Demo { 0xa41989db0f9bf97e, 1304, "pow", }, + { 0xa4984da0a704cd67, 72, "peacewalker_codehash" }, // Metal Gear Solid: Peace Walker demo { 0xa46cc6ea720d5775, 44, "dl_write_cull", }, { 0xa54967288afe8f26, 600, "ceil", }, { 0xa5ddbbc688e89a4d, 56, "isinf", },