daedalus/Source/OSHLE/patch_util_hle.inl
2022-06-22 23:35:36 +10:00

244 lines
5.2 KiB
C++

#define TEST_DISABLE_UTIL_FUNCS //DAEDALUS_PROFILE(__FUNCTION__);
u32 Patch___osAtomicDec()
{
TEST_DISABLE_UTIL_FUNCS
#ifdef DAEDALUS_DEBUG_CONSOLE
DBGConsole_Msg(0, "osAtomicDec");
#endif
u8 *p = (u8*)ReadAddress(gGPR[REG_a0]._u32_0);
u32 value = QuickRead32Bits(p, 0x0);
u32 result= 0;
if (value)
{
value-=1;
result=1;
QuickWrite32Bits(p, 0x0, value);
}
gGPR[REG_v0]._s64 = (s64)result;
return PATCH_RET_JR_RA;
}
//*****************************************************************************
//
//*****************************************************************************
u32 Patch_memcpy()
{
TEST_DISABLE_UTIL_FUNCS
u32 dst = gGPR[REG_a0]._u32_0;
u32 src = gGPR[REG_a1]._u32_0;
u32 len = gGPR[REG_a2]._u32_0;
// Set return val here (return dest)
gGPR[REG_v0]._s64 = (s64)gGPR[REG_a0]._u32_0;
//NOP! fixes SpiderMan
if (len == 0)
return PATCH_RET_JR_RA;
#if 1 //1->Fast, 0->Old way
fast_memcpy_swizzle( (void *)ReadAddress(dst), (void *)ReadAddress(src), len);
#else
//DBGConsole_Msg(0, "memcpy(0x%08x, 0x%08x, %d)", dst, src, len);
u8 *pdst = (u8*)ReadAddress(dst);
u8 *psrc = (u8*)ReadAddress(src);
while(len--)
{
*(u8*)((u32)pdst++ ^ U8_TWIDDLE) = *(u8*)((u32)psrc++ ^ U8_TWIDDLE);
}
#endif
return PATCH_RET_JR_RA;
}
//*****************************************************************************
//
//*****************************************************************************
// Used by Killer Instinct
u32 Patch_strlen()
{
TEST_DISABLE_UTIL_FUNCS
u32 string = gGPR[REG_a0]._u32_0;
const u8 *psrc = (const u8*)ReadAddress(string);
const u8 *start = psrc;
while (*((u8*)((uintptr_t)psrc++^U8_TWIDDLE)) );
gGPR[REG_v0]._s64 = (s64)(psrc - start - 1);
return PATCH_RET_JR_RA;
}
//*****************************************************************************
//
//*****************************************************************************
u32 Patch_strchr()
{
TEST_DISABLE_UTIL_FUNCS
u32 string = gGPR[REG_a0]._u32_0;
u8 MatchChar = (u8)(gGPR[REG_a1]._u32_0 & 0xFF);
u32 MatchAddr = 0;
u8 *start = (u8*)ReadAddress(string);
u8 *psrc = start;
for (;; psrc++)
{
const u8 SrcChar = *((u8*)((uintptr_t)psrc^U8_TWIDDLE));
if( SrcChar == MatchChar )
{
MatchAddr = string + psrc - start; //Return char address
break;
}
if( SrcChar == 0 ) break; //Return NULL address
}
gGPR[REG_v0]._s64 = (s64) MatchAddr;
return PATCH_RET_JR_RA;
}
//*****************************************************************************
//
//*****************************************************************************
// Have yet to see a game that uses this
u32 Patch_strcmp()
{
u32 i;
u32 sA = gGPR[REG_a0]._u32_0;
u32 sB = gGPR[REG_a1]._u32_0;
u32 len = gGPR[REG_a2]._u32_0;
u8 A, B;
#ifdef DAEDALUS_DEBUG_CONSOLE
DBGConsole_Msg(0, "strcmp(%s,%s,%d)", sA, sB, len);
#endif
for (i = 0; (A = Read8Bits(sA+i)) != 0 && i < len; i++)
{
B = Read8Bits(sB + i);
if ( A != B)
break;
}
if (i == len || (A == 0 && Read8Bits(sB + i) == 0))
i = 0;
gGPR[REG_v0]._s64 = (s64)i;
return PATCH_RET_JR_RA;
}
//*****************************************************************************
//
//*****************************************************************************
/*void * bcopy(const void * src, void * dst, len) */
// Note different order to src/dst than memcpy!
u32 Patch_bcopy()
{
TEST_DISABLE_UTIL_FUNCS
u32 src = gGPR[REG_a0]._u32_0;
u32 dst = gGPR[REG_a1]._u32_0;
u32 len = gGPR[REG_a2]._u32_0;
// Set return val here (return dest)
gGPR[REG_v0]._s64 = (s64)gGPR[REG_a1]._u32_0;
if (len == 0)
return PATCH_RET_JR_RA;
if (src == dst)
return PATCH_RET_JR_RA;
//DBGConsole_Msg(0, "bcopy(0x%08x,0x%08x,%d)", src, dst, len);
u8 *pdst = (u8*)ReadAddress(dst);
u8 *psrc = (u8*)ReadAddress(src);
if (dst > src && dst < src + len)
{
pdst += len;
psrc += len;
while(len--)
{
*(u8*)((uintptr_t)pdst-- ^ U8_TWIDDLE) = *(u8*)((uintptr_t)psrc-- ^ U8_TWIDDLE);
}
}
else
{
#if 1 // 1->Fast way, 0->Old way
fast_memcpy_swizzle( (void *)pdst, (const void *)psrc, len);
#else
while(len--)
{
*(u8*)((u32)pdst++ ^ U8_TWIDDLE) = *(u8*)((u32)psrc++ ^ U8_TWIDDLE);
}
#endif
}
// Mmm already returned dest... -Salvy
//gGPR[REG_v0]._s64 = 0;
return PATCH_RET_JR_RA;
}
//*****************************************************************************
//
//*****************************************************************************
// By Jun Su
u32 Patch_bzero()
{
u32 dst = gGPR[REG_a0]._u32_0;
u32 len = gGPR[REG_a1]._u32_0;
u8* dst8 = (u8*)ReadAddress(dst);
#ifdef DAEDALUS_ENDIAN_BIG
memset( dst8, 0, len);
#else
// Align dst on 4 bytes or just resume if already done
while(((uintptr_t)dst8 & 0x3) && len)
{
*(u8*)((uintptr_t)dst8++ ^ U8_TWIDDLE) = 0;
len--;
}
u32 *dst32=(u32*)dst8;
u32 len32 = len >> 2;
u32 len128= 0;
len &= 0x3;
while (len32&0x3)
{
*dst32++ = 0;
len32--;
}
len128 = len32 >> 2;
while (len128--)
{
*dst32++ = 0;
*dst32++ = 0;
*dst32++ = 0;
*dst32++ = 0;
}
dst8=(u8*)dst32;
//Write(0) to the unaligned remains(if any), byte by byte...
while(len--)
{
*(u8*)((uintptr_t)dst8++ ^ U8_TWIDDLE) = 0;
}
#endif
// return value of dest
gGPR[REG_v0]._s64 = (s64) gGPR[REG_a0]._u32_0;
return PATCH_RET_JR_RA;
}