mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #377 from PCSX2/tlb_goemon_v2
goemon gamefix improvement
This commit is contained in:
commit
b9297c6158
|
@ -25,6 +25,10 @@
|
||||||
#include "DisASM.h"
|
#include "DisASM.h"
|
||||||
#include "R5900OpcodeTables.h"
|
#include "R5900OpcodeTables.h"
|
||||||
|
|
||||||
|
// Allow to print register content when you print dissassembler info
|
||||||
|
// Note only a subset of the opcodes are supported. It is intended as a cheap debugger
|
||||||
|
//#define PRINT_REG_CONTENT
|
||||||
|
|
||||||
unsigned long opcode_addr;
|
unsigned long opcode_addr;
|
||||||
u32 disasmOpcode;
|
u32 disasmOpcode;
|
||||||
bool disSimplify;
|
bool disSimplify;
|
||||||
|
@ -710,16 +714,46 @@ const char* signedImmediate(s32 imm, int len = 0)
|
||||||
|
|
||||||
const char* disDestSource(int dest, int source)
|
const char* disDestSource(int dest, int source)
|
||||||
{
|
{
|
||||||
static char buffer[32];
|
static char buffer[64];
|
||||||
|
#ifdef PRINT_REG_CONTENT
|
||||||
|
sprintf(buffer,"%s,%s(0x%8.8x)",GPR_REG[dest],GPR_REG[source], cpuRegs.GPR.r[source].UL[0]);
|
||||||
|
#else
|
||||||
if (disSimplify && dest == source)
|
if (disSimplify && dest == source)
|
||||||
sprintf(buffer,"%s",GPR_REG[dest]);
|
sprintf(buffer,"%s",GPR_REG[dest]);
|
||||||
else
|
else
|
||||||
sprintf(buffer,"%s,%s",GPR_REG[dest],GPR_REG[source]);
|
sprintf(buffer,"%s,%s",GPR_REG[dest],GPR_REG[source]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disBranch(std::string& output, const char* op)
|
||||||
|
{
|
||||||
|
ssappendf(output, "%s\t", op);
|
||||||
|
offset_decode(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disBranch(std::string& output, const char* op, int rs)
|
||||||
|
{
|
||||||
|
#ifdef PRINT_REG_CONTENT
|
||||||
|
ssappendf(output, "%s\t%s(0x%8.8x), ", op, GPR_REG[rs], cpuRegs.GPR.r[rs].UL[0]);
|
||||||
|
#else
|
||||||
|
ssappendf(output, "%s\t%s, ", op, GPR_REG[rs]);
|
||||||
|
#endif
|
||||||
|
offset_decode(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disBranch(std::string& output, const char* op, int rs, int rt)
|
||||||
|
{
|
||||||
|
#ifdef PRINT_REG_CONTENT
|
||||||
|
ssappendf(output, "%s\t%s(0x%8.8x), %s(0x%8.8x), ", op, GPR_REG[rs], cpuRegs.GPR.r[rs].UL[0], GPR_REG[rt], cpuRegs.GPR.r[rt].UL[0]);
|
||||||
|
#else
|
||||||
|
ssappendf(output, "%s\t%s, %s, ", op, GPR_REG[rs], GPR_REG[rt]);
|
||||||
|
#endif
|
||||||
|
offset_decode(output);
|
||||||
|
}
|
||||||
|
|
||||||
//********************* Standard Opcodes***********************
|
//********************* Standard Opcodes***********************
|
||||||
void J( std::string& output ) { output += "j\t"; jump_decode(output);}
|
void J( std::string& output ) { output += "j\t"; jump_decode(output);}
|
||||||
void JAL( std::string& output ) { output += "jal\t"; jump_decode(output);}
|
void JAL( std::string& output ) { output += "jal\t"; jump_decode(output);}
|
||||||
|
@ -730,15 +764,13 @@ void BEQ( std::string& output )
|
||||||
int rt = DECODE_RT;
|
int rt = DECODE_RT;
|
||||||
|
|
||||||
if (disSimplify && rs == rt)
|
if (disSimplify && rs == rt)
|
||||||
ssappendf(output, "b\t");
|
disBranch(output, "b");
|
||||||
else if (disSimplify && rs == 0 && rt != 0)
|
else if (disSimplify && rs == 0 && rt != 0)
|
||||||
ssappendf(output, "beqz\t%s, ",GPR_REG[rt]);
|
disBranch(output, "beqz", rt);
|
||||||
else if (disSimplify && rs != 0 && rt == 0)
|
else if (disSimplify && rs != 0 && rt == 0)
|
||||||
ssappendf(output, "beqz\t%s, ",GPR_REG[rs]);
|
disBranch(output, "beqz", rs);
|
||||||
else
|
else
|
||||||
ssappendf(output, "beq\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]);
|
disBranch(output, "beq", rs, rt);
|
||||||
|
|
||||||
offset_decode(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BNE( std::string& output )
|
void BNE( std::string& output )
|
||||||
|
@ -747,17 +779,15 @@ void BNE( std::string& output )
|
||||||
int rt = DECODE_RT;
|
int rt = DECODE_RT;
|
||||||
|
|
||||||
if (disSimplify && rs == 0 && rt != 0)
|
if (disSimplify && rs == 0 && rt != 0)
|
||||||
ssappendf(output, "bnez\t%s, ",GPR_REG[rt]);
|
disBranch(output, "bnez", rt);
|
||||||
else if (disSimplify && rs != 0 && rt == 0)
|
else if (disSimplify && rs != 0 && rt == 0)
|
||||||
ssappendf(output, "bnez\t%s, ",GPR_REG[rs]);
|
disBranch(output, "bnez", rs);
|
||||||
else
|
else
|
||||||
ssappendf(output, "bne\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]);
|
disBranch(output, "bne", rt, rs);
|
||||||
|
|
||||||
offset_decode(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLEZ( std::string& output ) { _sap("blez\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BLEZ( std::string& output ) { disBranch(output, "blez", DECODE_RS); }
|
||||||
void BGTZ( std::string& output ) { _sap("bgtz\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BGTZ( std::string& output ) { disBranch(output, "bgtz", DECODE_RS); }
|
||||||
void ADDI( std::string& output ) { _sap("addi\t%s, %s, 0x%04X") GPR_REG[DECODE_RT], GPR_REG[DECODE_RS], DECODE_IMMED);}
|
void ADDI( std::string& output ) { _sap("addi\t%s, %s, 0x%04X") GPR_REG[DECODE_RT], GPR_REG[DECODE_RS], DECODE_IMMED);}
|
||||||
|
|
||||||
void ADDIU( std::string& output )
|
void ADDIU( std::string& output )
|
||||||
|
@ -798,15 +828,13 @@ void BEQL( std::string& output )
|
||||||
int rt = DECODE_RT;
|
int rt = DECODE_RT;
|
||||||
|
|
||||||
if (disSimplify && rs == rt)
|
if (disSimplify && rs == rt)
|
||||||
ssappendf(output, "b\t");
|
disBranch(output, "bl");
|
||||||
else if (disSimplify && rs == 0 && rt != 0)
|
else if (disSimplify && rs == 0 && rt != 0)
|
||||||
ssappendf(output, "beqzl\t%s, ",GPR_REG[rt]);
|
disBranch(output, "beqzl", rt);
|
||||||
else if (disSimplify && rs != 0 && rt == 0)
|
else if (disSimplify && rs != 0 && rt == 0)
|
||||||
ssappendf(output, "beqzl\t%s, ",GPR_REG[rs]);
|
disBranch(output, "beqzl", rs);
|
||||||
else
|
else
|
||||||
ssappendf(output, "beql\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]);
|
disBranch(output, "beql", rs, rt);
|
||||||
|
|
||||||
offset_decode(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BNEL( std::string& output )
|
void BNEL( std::string& output )
|
||||||
|
@ -815,17 +843,15 @@ void BNEL( std::string& output )
|
||||||
int rt = DECODE_RT;
|
int rt = DECODE_RT;
|
||||||
|
|
||||||
if (disSimplify && rs == 0 && rt != 0)
|
if (disSimplify && rs == 0 && rt != 0)
|
||||||
ssappendf(output, "bnezl\t%s, ",GPR_REG[rt]);
|
disBranch(output, "bnezl", rt);
|
||||||
else if (disSimplify && rs != 0 && rt == 0)
|
else if (disSimplify && rs != 0 && rt == 0)
|
||||||
ssappendf(output, "bnezl\t%s, ",GPR_REG[rs]);
|
disBranch(output, "bnezl", rs);
|
||||||
else
|
else
|
||||||
ssappendf(output, "bnel\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]);
|
disBranch(output, "bnel", rt, rs);
|
||||||
|
|
||||||
offset_decode(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLEZL( std::string& output ) { _sap("blezl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BLEZL( std::string& output ) { disBranch(output, "blezl", DECODE_RS); }
|
||||||
void BGTZL( std::string& output ) { _sap("bgtzl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BGTZL( std::string& output ) { disBranch(output, "bgtzl", DECODE_RS); }
|
||||||
void DADDI( std::string& output ) { _sap("daddi\t%s, 0x%04X") disDestSource(DECODE_RT, DECODE_RS), DECODE_IMMED); }
|
void DADDI( std::string& output ) { _sap("daddi\t%s, 0x%04X") disDestSource(DECODE_RT, DECODE_RS), DECODE_IMMED); }
|
||||||
void DADDIU( std::string& output ) { _sap("daddiu\t%s, 0x%04X") disDestSource(DECODE_RT, DECODE_RS), DECODE_IMMED); }
|
void DADDIU( std::string& output ) { _sap("daddiu\t%s, 0x%04X") disDestSource(DECODE_RT, DECODE_RS), DECODE_IMMED); }
|
||||||
|
|
||||||
|
@ -994,20 +1020,20 @@ void SYSCALL( std::string& output ) { output +="syscall ---";/*_sap("syscall\t0x
|
||||||
void BREAK( std::string& output ) { output += "break ---";/*_sap("break\t0x%05X") DECODE_BREAK); */}
|
void BREAK( std::string& output ) { output += "break ---";/*_sap("break\t0x%05X") DECODE_BREAK); */}
|
||||||
void CACHE( std::string& output ) { output += "cache ---";/*_sap("cache\t%s, 0x%04X(%s)") GPR_REG[DECODE_RT], DECODE_IMMED, GPR_REG[DECODE_RS]); */}
|
void CACHE( std::string& output ) { output += "cache ---";/*_sap("cache\t%s, 0x%04X(%s)") GPR_REG[DECODE_RT], DECODE_IMMED, GPR_REG[DECODE_RS]); */}
|
||||||
//************************REGIMM OPCODES***************************
|
//************************REGIMM OPCODES***************************
|
||||||
void BLTZ( std::string& output ) { _sap("bltz\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BLTZ( std::string& output ) { disBranch(output, "bltz", DECODE_RS); }
|
||||||
void BGEZ( std::string& output ) { _sap("bgez\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BGEZ( std::string& output ) { disBranch(output, "bgez", DECODE_RS); }
|
||||||
void BLTZL( std::string& output ) { _sap("bltzl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BLTZL( std::string& output ) { disBranch(output, "bltzl", DECODE_RS); }
|
||||||
void BGEZL( std::string& output ) { _sap("bgezl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BGEZL( std::string& output ) { disBranch(output, "bgezl", DECODE_RS); }
|
||||||
void TGEI( std::string& output ) { _sap("tgei\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
void TGEI( std::string& output ) { _sap("tgei\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||||
void TGEIU( std::string& output ) { _sap("tgeiu\t%s,0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
void TGEIU( std::string& output ) { _sap("tgeiu\t%s,0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||||
void TLTI( std::string& output ) { _sap("tlti\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
void TLTI( std::string& output ) { _sap("tlti\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||||
void TLTIU( std::string& output ) { _sap("tltiu\t%s,0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
void TLTIU( std::string& output ) { _sap("tltiu\t%s,0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||||
void TEQI( std::string& output ) { _sap("teqi\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
void TEQI( std::string& output ) { _sap("teqi\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||||
void TNEI( std::string& output ) { _sap("tnei\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
void TNEI( std::string& output ) { _sap("tnei\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED); }
|
||||||
void BLTZAL( std::string& output ) { _sap("bltzal\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BLTZAL( std::string& output ) { disBranch(output, "bltzal", DECODE_RS); }
|
||||||
void BGEZAL( std::string& output ) { _sap("bgezal\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BGEZAL( std::string& output ) { disBranch(output, "bgezal", DECODE_RS); }
|
||||||
void BLTZALL( std::string& output ) { _sap("bltzall\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BLTZALL( std::string& output ) { disBranch(output, "bltzall", DECODE_RS); }
|
||||||
void BGEZALL( std::string& output ) { _sap("bgezall\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); }
|
void BGEZALL( std::string& output ) { disBranch(output, "bgezall", DECODE_RS); }
|
||||||
void MTSAB( std::string& output ) { _sap("mtsab\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED);}
|
void MTSAB( std::string& output ) { _sap("mtsab\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED);}
|
||||||
void MTSAH( std::string& output ) { _sap("mtsah\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED);}
|
void MTSAH( std::string& output ) { _sap("mtsah\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED);}
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ static void execI()
|
||||||
// Based on cycle
|
// Based on cycle
|
||||||
// if( cpuRegs.cycle > 0x4f24d714 )
|
// if( cpuRegs.cycle > 0x4f24d714 )
|
||||||
// Or dump from a particular PC (useful to debug handler/syscall)
|
// Or dump from a particular PC (useful to debug handler/syscall)
|
||||||
if (cpuRegs.pc == 0x80000000) {
|
if (pc == 0x80000000) {
|
||||||
print_me = 2000;
|
print_me = 2000;
|
||||||
}
|
}
|
||||||
if (print_me) {
|
if (print_me) {
|
||||||
|
@ -254,6 +254,11 @@ void J()
|
||||||
|
|
||||||
void JAL()
|
void JAL()
|
||||||
{
|
{
|
||||||
|
// 0x3563b8 is the start address of the function that invalidate entry in TLB cache
|
||||||
|
if (EmuConfig.Gamefixes.GoemonTlbHack) {
|
||||||
|
if (_JumpTarget_ == 0x3563b8)
|
||||||
|
GoemonUnloadTlb(cpuRegs.GPR.n.a0.UL[0]);
|
||||||
|
}
|
||||||
_SetLink(31);
|
_SetLink(31);
|
||||||
doBranch(_JumpTarget_);
|
doBranch(_JumpTarget_);
|
||||||
}
|
}
|
||||||
|
@ -455,9 +460,11 @@ void BGEZALL() // Branch if Rs >= 0 and link
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
void JR()
|
void JR()
|
||||||
{
|
{
|
||||||
// 0x33ad48 is the return address of the function that populate the TLB cache
|
// 0x33ad48 and 0x35060c are the return address of the function (0x356250) that populate the TLB cache
|
||||||
if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x33ad48 && EmuConfig.Gamefixes.GoemonTlbHack) {
|
if (EmuConfig.Gamefixes.GoemonTlbHack) {
|
||||||
GoemonPreloadTlb();
|
u32 add = cpuRegs.GPR.r[_Rs_].UL[0];
|
||||||
|
if (add == 0x33ad48 || add == 0x35060c)
|
||||||
|
GoemonPreloadTlb();
|
||||||
}
|
}
|
||||||
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
|
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,6 +430,7 @@ extern void cpuTlbMissW(u32 addr, u32 bd);
|
||||||
extern void cpuTestHwInts();
|
extern void cpuTestHwInts();
|
||||||
extern void cpuClearInt(uint n);
|
extern void cpuClearInt(uint n);
|
||||||
extern void __fastcall GoemonPreloadTlb();
|
extern void __fastcall GoemonPreloadTlb();
|
||||||
|
extern void __fastcall GoemonUnloadTlb(u32 key);
|
||||||
|
|
||||||
extern void cpuSetNextEvent( u32 startCycle, s32 delta );
|
extern void cpuSetNextEvent( u32 startCycle, s32 delta );
|
||||||
extern void cpuSetNextEventDelta( s32 delta );
|
extern void cpuSetNextEventDelta( s32 delta );
|
||||||
|
|
|
@ -339,7 +339,9 @@ static void GoemonTlbMissDebug()
|
||||||
|
|
||||||
for (u32 i = 0; i < 150; i++) {
|
for (u32 i = 0; i < 150; i++) {
|
||||||
if (tlb[i].valid == 0x1 && tlb[i].low_add != tlb[i].high_add)
|
if (tlb[i].valid == 0x1 && tlb[i].low_add != tlb[i].high_add)
|
||||||
DevCon.WriteLn("Entry %d is valid. From V:0x%8.8x to V:0x%8.8x (P:0x%8.8x)", i, tlb[i].low_add, tlb[i].high_add, tlb[i].physical_add);
|
DevCon.WriteLn("GoemonTlbMissDebug: Entry %d is valid. Key %x. From V:0x%8.8x to V:0x%8.8x (P:0x%8.8x)", i, tlb[i].key, tlb[i].low_add, tlb[i].high_add, tlb[i].physical_add);
|
||||||
|
else if (tlb[i].low_add != tlb[i].high_add)
|
||||||
|
DevCon.WriteLn("GoemonTlbMissDebug: Entry %d is invalid. Key %x. From V:0x%8.8x to V:0x%8.8x (P:0x%8.8x)", i, tlb[i].key, tlb[i].low_add, tlb[i].high_add, tlb[i].physical_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +358,7 @@ void __fastcall GoemonPreloadTlb()
|
||||||
u32 paddr = tlb[i].physical_add;
|
u32 paddr = tlb[i].physical_add;
|
||||||
|
|
||||||
if ((uptr)vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] == POINTER_SIGN_BIT) {
|
if ((uptr)vtlbdata.vmap[vaddr>>VTLB_PAGE_BITS] == POINTER_SIGN_BIT) {
|
||||||
DevCon.WriteLn("Preload TLB[%d]: From V:0x%8.8x to P:0x%8.8x (%d pages)", i, vaddr, paddr, size >> VTLB_PAGE_BITS);
|
DevCon.WriteLn("GoemonPreloadTlb: Entry %d. Key %x. From V:0x%8.8x to P:0x%8.8x (%d pages)", i, tlb[i].key, vaddr, paddr, size >> VTLB_PAGE_BITS);
|
||||||
vtlb_VMap( vaddr , paddr, size);
|
vtlb_VMap( vaddr , paddr, size);
|
||||||
vtlb_VMap(0x20000000|vaddr , paddr, size);
|
vtlb_VMap(0x20000000|vaddr , paddr, size);
|
||||||
}
|
}
|
||||||
|
@ -364,6 +366,33 @@ void __fastcall GoemonPreloadTlb()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __fastcall GoemonUnloadTlb(u32 key)
|
||||||
|
{
|
||||||
|
// 0x3d5580 is the address of the TLB cache table
|
||||||
|
GoemonTlb* tlb = (GoemonTlb*)&eeMem->Main[0x3d5580];
|
||||||
|
for (u32 i = 0; i < 150; i++) {
|
||||||
|
if (tlb[i].key == key) {
|
||||||
|
if (tlb[i].valid == 0x1) {
|
||||||
|
u32 size = tlb[i].high_add - tlb[i].low_add;
|
||||||
|
u32 vaddr = tlb[i].low_add;
|
||||||
|
DevCon.WriteLn("GoemonUnloadTlb: Entry %d. Key %x. From V:0x%8.8x to V:0x%8.8x (%d pages)", i, tlb[i].key, vaddr, vaddr+size, size >> VTLB_PAGE_BITS);
|
||||||
|
|
||||||
|
vtlb_VMapUnmap( vaddr , size);
|
||||||
|
vtlb_VMapUnmap(0x20000000|vaddr , size);
|
||||||
|
|
||||||
|
// Unmap the tlb in game cache table
|
||||||
|
// Note: Game copy FEFEFEFE for others data
|
||||||
|
tlb[i].valid = 0;
|
||||||
|
tlb[i].key = 0xFEFEFEFE;
|
||||||
|
tlb[i].low_add = 0xFEFEFEFE;
|
||||||
|
tlb[i].high_add = 0xFEFEFEFE;
|
||||||
|
} else {
|
||||||
|
DevCon.Error("GoemonUnloadTlb: Entry %d is not valid. Key %x", i, tlb[i].key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generates a tlbMiss Exception
|
// Generates a tlbMiss Exception
|
||||||
static __ri void vtlb_Miss(u32 addr,u32 mode)
|
static __ri void vtlb_Miss(u32 addr,u32 mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,6 +225,6 @@ struct GoemonTlb {
|
||||||
u32 physical_add;
|
u32 physical_add;
|
||||||
u32 unk3; // likely the size
|
u32 unk3; // likely the size
|
||||||
u32 high_add;
|
u32 high_add;
|
||||||
u32 unk4;
|
u32 key; // uniq number attached to an allocation
|
||||||
u32 unk5;
|
u32 unk5;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1739,9 +1739,17 @@ static void __fastcall recRecompile( const u32 startpc )
|
||||||
xCALL(PreBlockCheck);
|
xCALL(PreBlockCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x33ad48 is the return address of the function that populate the TLB cache
|
if (EmuConfig.Gamefixes.GoemonTlbHack) {
|
||||||
if (pc == 0x33ad48 && EmuConfig.Gamefixes.GoemonTlbHack) {
|
if (pc == 0x33ad48 || pc == 0x35060c) {
|
||||||
xCALL(GoemonPreloadTlb);
|
// 0x33ad48 and 0x35060c are the return address of the function (0x356250) that populate the TLB cache
|
||||||
|
xCALL(GoemonPreloadTlb);
|
||||||
|
} else if (pc == 0x3563b8) {
|
||||||
|
// Game will unmap some virtual addresses. If a constant address were hardcoded in the block, we would be in a bad situation.
|
||||||
|
AtomicExchange( eeRecNeedsReset, true );
|
||||||
|
// 0x3563b8 is the start address of the function that invalidate entry in TLB cache
|
||||||
|
MOV32MtoR(ECX, (int)&cpuRegs.GPR.n.a0.UL[ 0 ] );
|
||||||
|
xCALL(GoemonUnloadTlb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// go until the next branch
|
// go until the next branch
|
||||||
|
|
|
@ -109,7 +109,7 @@ bool GSClut::WriteTest(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
|
||||||
case 4: if(m_CBP[0] == TEX0.CBP) return false; m_CBP[0] = TEX0.CBP; break;
|
case 4: if(m_CBP[0] == TEX0.CBP) return false; m_CBP[0] = TEX0.CBP; break;
|
||||||
case 5: if(m_CBP[1] == TEX0.CBP) return false; m_CBP[1] = TEX0.CBP; break;
|
case 5: if(m_CBP[1] == TEX0.CBP) return false; m_CBP[1] = TEX0.CBP; break;
|
||||||
case 6: ASSERT(0); return false; // ffx2 menu
|
case 6: ASSERT(0); return false; // ffx2 menu
|
||||||
case 7: ASSERT(0); return false; // ford mustang racing
|
case 7: ASSERT(0); return false; // ford mustang racing // Bouken Jidai Katsugeki Goemon
|
||||||
default: __assume(0);
|
default: __assume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -851,7 +851,7 @@ template<int i> void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
|
||||||
|
|
||||||
if((TEX0.TBW & 1) && (TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT4))
|
if((TEX0.TBW & 1) && (TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT4))
|
||||||
{
|
{
|
||||||
ASSERT(TEX0.TBW == 1); // TODO
|
ASSERT(TEX0.TBW == 1); // TODO // Bouken Jidai Katsugeki Goemon
|
||||||
|
|
||||||
TEX0.TBW &= ~1; // GS User 2.6
|
TEX0.TBW &= ~1; // GS User 2.6
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue