more f-zero work - no success :( Still fp errors.

maybe we should pull in a full accuracy ppc fp emulator.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1971 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2009-01-21 12:41:01 +00:00
parent 620bf888e7
commit 56ee6e5497
8 changed files with 106 additions and 63 deletions

View File

@ -41,7 +41,7 @@ void PPCDebugInterface::disasm(unsigned int address, char *dest, int max_size)
}
else
{
strcpy(dest, "No RAM here - invalid");
strcpy(dest, "(No RAM here)");
}
}
else

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <map>
#include "Common.h"
#include "HLE.h"
#include "../PowerPC/PowerPC.h"
@ -69,10 +72,15 @@ static const SPatch OSPatches[] =
{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine },
{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize },
{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength },
{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize },
{ "PanicAlert", HLE_Misc::HLEPanicAlert },
{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal },
{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal },
{ ".atan2", HLE_Misc::SMB_atan2},
{ ".sqrt_fz", HLE_Misc::FZ_sqrt},
{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal },
{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal },
//{ ".kill_infinites", HLE_Misc::FZero_kill_infinites },
// special
@ -85,6 +93,9 @@ static const SPatch OSBreakPoints[] =
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
};
static std::map<u32, u32> orig_instruction;
void Patch(u32 address, const char *hle_func_name)
{
for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++)
@ -98,15 +109,18 @@ void Patch(u32 address, const char *hle_func_name)
}
void PatchFunctions()
{
{
orig_instruction.clear();
for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++)
{
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
if (symbol > 0)
{
u32 HLEPatchValue = (1 & 0x3f) << 26;
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) {
orig_instruction[addr] = Memory::ReadUnchecked_U32(addr);
Memory::Write_U32(HLEPatchValue | i, addr);
}
LOG(HLE,"Patching %s %08x", OSPatches[i].m_szPatchName, symbol->address);
}
}
@ -139,4 +153,13 @@ void Execute(u32 _CurrentPC, u32 _Instruction)
// _dbg_assert_msg_(HLE,NPC == LR, "Broken HLE function (doesn't set NPC)", OSPatches[pos].m_szPatchName);
}
u32 GetOrigInstruction(u32 addr)
{
std::map<u32, u32>::const_iterator iter = orig_instruction.find(addr);
if (iter != orig_instruction.end())
return iter->second;
else
return 0;
}
}

View File

@ -25,6 +25,8 @@ namespace HLE
void PatchFunctions();
void Patch(u32 pc, const char *func_name);
void Execute(u32 _CurrentPC, u32 _Instruction);
u32 GetOrigInstruction(u32 em_address);
}
#endif

View File

@ -129,7 +129,7 @@ void SMB_evil_vec_setlength()
float x = F(r3);
float y = F(r3 + 4);
float z = F(r3 + 8);
float inv_len = (float)(rPS0(1) / sqrt(x*x + y*y + z*z));
float inv_len = (float)(rPS0(0) / sqrt(x*x + y*y + z*z));
x *= inv_len;
y *= inv_len;
z *= inv_len;
@ -181,23 +181,71 @@ void FZero_kill_infinites()
NPC = LR;
}
void FZero_evil_vec_something()
void FZ_sqrt() {
u32 r3 = GPR(3);
double x = rPS0(0);
x = sqrt(x);
FW(r3, (float)x);
rPS0(0) = x;
NPC = LR;
}
// Internal square root function in the crazy math lib. Acts a bit odd, just read it. It's not a bug :p
void FZ_sqrt_internal()
{
/*
double f = sqrt(rPS0(1));
rPS0(0) = rPS0(1);
rPS1(0) = rPS0(1);
rPS0(1) = f;
rPS1(1) = f;
NPC = LR;
}
// Internal inverse square root function in the crazy math lib.
void FZ_rsqrt_internal()
{
double f = 1.0 / sqrt(rPS0(1));
rPS0(1) = f;
rPS1(1) = f;
NPC = LR;
}
void FZero_evil_vec_normalize()
{
u32 r3 = GPR(3);
float x = F(r3);
float y = F(r3 + 4);
float z = F(r3 + 8);
float sq_len = x*x + y*y + z*z;
float inv_len = 1.0f / sqrtf(sq_len);
x *= inv_len;
y *= inv_len;
z *= inv_len;
FW(r3, x);
FW(r3 + 4, y);
FW(r3 + 8, z);
rPS0(1) = inv_len * sq_len; // len
rPS1(1) = inv_len * sq_len; // len
NPC = LR;
/*
.evil_vec_something
(f6, f7, f8) <- [r3]
f1 = f6 * f6
f1 += f7 * f7
f1 += f8 * f8
f2 = mystery
f4 = f2 * f1
f3 = f2 + f2
f1 = 1/f0
f6 *= f1
f7 *= f1
f8 *= f1
8006d668: lis r5, 0xE000
8006d66c: lfs f6, 0 (r3)
8006d670: lfs f7, 0x0004 (r3)
8006d674: fmuls f1,f6,f6
8006d678: lfs f8, 0x0008 (r3)
8006d67c: fmadds f1,f7,f7,f1
8006d680: fmadds f1,f8,f8,f1
8006d684: lfs f2, 0x01A0 (r5)
8006d688: mcrfs cr1, cr4
8006d68c: mcrfs cr0, cr3
8006d690: bso- cr1,->0x8006D6E8
8006d694: ble- cr1,->0x8006D6E8
8006d698: bso- ->0x8006D6E8
8006d69c: fmr f0,f2
8006d6a0: fmuls f4,f2,f1
8006d6a4: fadds f3,f2,f2
@ -217,11 +265,6 @@ void FZero_evil_vec_something()
8006d6dc: stfs f8, 0x0008 (r3)
8006d6e0: fmuls f1,f1,f0
8006d6e4: blr
8006d6e8: lfs f1, 0x0198 (r5)
8006d6ec: stfs f1, 0 (r3)
8006d6f0: stfs f1, 0x0004 (r3)
8006d6f4: stfs f1, 0x0008 (r3)
8006d6f8: blr
*/
NPC = LR;
}

View File

@ -34,6 +34,10 @@ namespace HLE_Misc
void SMB_atan2();
void SMB_evil_vec_setlength();
void FZero_kill_infinites();
void FZero_evil_vec_normalize();
void FZ_sqrt();
void FZ_sqrt_internal();
void FZ_rsqrt_internal();
}
#endif

View File

@ -700,7 +700,7 @@ void CompileInstruction(UGeckoInstruction _inst)
GekkoOPInfo *info = GetOpInfo(_inst);
if (info) {
#ifdef OPLOG
if (!strcmp(info->opname, "mcrfs")) {
if (!strcmp(info->opname, "mffsx")) { ///"mcrfs"
rsplocations.push_back(jit.js.compilerPC);
}
#endif
@ -766,7 +766,7 @@ void LogCompiledInstructions()
#ifdef OPLOG
f = fopen(StringFromFormat(FULL_LOGS_DIR "mcrfs_at.txt", time).c_str(), "w");
for (size_t i = 0; i < rsplocations.size(); i++) {
fprintf(f, "mcrfs: %08x\n", rsplocations[i]);
fprintf(f, "mffsx: %08x\n", rsplocations[i]);
}
fclose(f);
#endif