More replacement function accuracy improvements. Makes J&D happy, "fixing" #7502.

This commit is contained in:
Henrik Rydgard committed 2015-02-20 00:17:47 +01:00
1 parent f1a856c53c
commit 1ecfd6cebc
3 files changed
+51 -18

No files matched your search

+49 -16
View File
@@ -20,6 +20,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "Common/Log.h"
#include "Core/Config.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/MemMap.h"
@@ -149,11 +150,13 @@ static int Replace_memcpy_jak() {
u32 srcPtr = PARAM(1);
u32 bytes = PARAM(2);
bool skip = false;
if (!bytes) {
if (bytes == 0) {
RETURN(destPtr);
return 10;
currentMIPS->r[MIPS_REG_T0] = bytes;
currentMIPS->r[MIPS_REG_A0] = bytes - 1;
currentMIPS->r[MIPS_REG_A2] = bytes - 1;
return 5;
}
currentMIPS->InvalidateICache(srcPtr, bytes);
if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) {
skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes);
@@ -163,30 +166,24 @@ static int Replace_memcpy_jak() {
const u8 *src = Memory::GetPointer(srcPtr);
if (!dst || !src) {
// Already logged.
} else if (std::min(destPtr, srcPtr) + bytes > std::max(destPtr, srcPtr)) {
} else {
// Jak style overlap.
for (int i = 0; i < (int)bytes; i++) {
for (int i = 0; i < bytes; i++) {
dst[i] = src[i];
}
} else {
memmove(dst, src, bytes);
}
}
RETURN(destPtr);
// Jak relies on more registers coming out right than the ABI specifies.
// See the disassembly of the function for the explanations for these...
currentMIPS->r[MIPS_REG_T0] = 0;
currentMIPS->r[MIPS_REG_A0] = -1;
currentMIPS->r[MIPS_REG_A2] = 0;
currentMIPS->r[MIPS_REG_A1] = srcPtr + bytes;
currentMIPS->r[MIPS_REG_A2] = -1;
currentMIPS->r[MIPS_REG_A3] = destPtr + bytes;
RETURN(destPtr);
#ifndef MOBILE_DEVICE
CBreakPoints::ExecMemCheck(srcPtr, false, bytes, currentMIPS->pc);
CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
#endif
return 10 + bytes / 4; // approximation
return 5 + bytes * 8 + 2; // approximation. This is a slow memcpy - a byte copy loop..
}
static int Replace_memcpy16() {
@@ -298,6 +295,42 @@ static int Replace_memset() {
return 10 + bytes / 4; // approximation
}
static int Replace_memset_jak() {
u32 destPtr = PARAM(0);
u8 value = PARAM(1);
u32 bytes = PARAM(2);
if (bytes == 0) {
currentMIPS->r[MIPS_REG_A2] = bytes - 1;
currentMIPS->r[MIPS_REG_A3] = bytes - 1;
currentMIPS->r[MIPS_REG_T0] = destPtr;
currentMIPS->r[MIPS_REG_T1] = 0;
RETURN(destPtr);
return 5;
}
bool skip = false;
if (Memory::IsVRAMAddress(destPtr)) {
skip = gpu->PerformMemorySet(destPtr, value, bytes);
}
if (!skip && bytes != 0) {
u8 *dst = Memory::GetPointer(destPtr);
if (dst) {
memset(dst, value, bytes);
}
}
currentMIPS->r[MIPS_REG_T0] = destPtr + bytes;
currentMIPS->r[MIPS_REG_A2] = -1;
currentMIPS->r[MIPS_REG_A3] = -1;
RETURN(destPtr);
#ifndef MOBILE_DEVICE
CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
#endif
return 5 + bytes * 10 + 2; // approximation (hm, inspecting the disasm this should be 5 + 6 * bytes + 2, but this is what works..)
}
static int Replace_strlen() {
u32 srcPtr = PARAM(0);
const char *src = (const char *)Memory::GetPointer(srcPtr);
@@ -1010,7 +1043,7 @@ static const ReplacementTableEntry entries[] = {
{ "memcpy_swizzled", &Replace_memcpy_swizzled, 0, 0 },
{ "memmove", &Replace_memmove, 0, 0 },
{ "memset", &Replace_memset, 0, 0 },
{ "memset_jak", &Replace_memset_jak, 0, 0 },
{ "strlen", &Replace_strlen, 0, REPFLAG_DISABLED },
{ "strcpy", &Replace_strcpy, 0, REPFLAG_DISABLED },
{ "strncpy", &Replace_strncpy, 0, REPFLAG_DISABLED },
+1 -1
View File
@@ -633,7 +633,7 @@ u32 sceKernelReferEventFlagStatus(SceUID id, u32 statusPtr)
}
else
{
ERROR_LOG(SCEKERNEL, "sceKernelReferEventFlagStatus(%i, %08x): invalid event flag", id, statusPtr);
ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferEventFlagStatus(%i, %08x): invalid event flag", error, id, statusPtr);
return error;
}
}
+1 -1
View File
@@ -439,7 +439,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
{ 0xe83a7a9d80a21c11, 4448, "_strtod_r", },
{ 0xe894bda909a8a8f9, 1064, "expensive_wipeout_pulse", },
{ 0xe8ad7719be44e7c8, 276, "strchr", },
{ 0xeabb9c1b4f83d2b4, 52, "memset", }, // Crisis Core (US)
{ 0xeabb9c1b4f83d2b4, 52, "memset_jak", }, // Crisis Core (US), Jak and Daxter (this is a slow memset and needs to have slow timing)
{ 0xeb0f7bf63d52ece9, 88, "strncat", },
{ 0xeb8c0834d8bbc28c, 416, "fmodf", },
{ 0xed8918f378e9a563, 628, "sd_gundam_g_generation_download_frame", }, // SD Gundam G Generation Overworld