From bf9fc521cbefe7e44c965d50e4bdfa310908d95d Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 7 Dec 2014 17:21:43 +0100 Subject: [PATCH 1/8] disassembler: Allow to print register value * Create a disBranch to factorize a bit the code * Add PRINT_REG_CONTENT define that add a 32bits value of registers for standard opcode. (Far from perfect, but it very useful) --- pcsx2/DebugTools/DisR5900asm.cpp | 98 ++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/pcsx2/DebugTools/DisR5900asm.cpp b/pcsx2/DebugTools/DisR5900asm.cpp index 8bb98babb3..647dd4b3e9 100644 --- a/pcsx2/DebugTools/DisR5900asm.cpp +++ b/pcsx2/DebugTools/DisR5900asm.cpp @@ -25,6 +25,10 @@ #include "DisASM.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; u32 disasmOpcode; bool disSimplify; @@ -710,16 +714,46 @@ const char* signedImmediate(s32 imm, int len = 0) 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) sprintf(buffer,"%s",GPR_REG[dest]); else sprintf(buffer,"%s,%s",GPR_REG[dest],GPR_REG[source]); +#endif + 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*********************** void J( std::string& output ) { output += "j\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; if (disSimplify && rs == rt) - ssappendf(output, "b\t"); + disBranch(output, "b"); 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) - ssappendf(output, "beqz\t%s, ",GPR_REG[rs]); + disBranch(output, "beqz", rs); else - ssappendf(output, "beq\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]); - - offset_decode(output); + disBranch(output, "beq", rs, rt); } void BNE( std::string& output ) @@ -747,17 +779,15 @@ void BNE( std::string& output ) int rt = DECODE_RT; 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) - ssappendf(output, "bnez\t%s, ",GPR_REG[rs]); + disBranch(output, "bnez", rs); else - ssappendf(output, "bne\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]); - - offset_decode(output); + disBranch(output, "bne", rt, rs); } -void BLEZ( std::string& output ) { _sap("blez\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BGTZ( std::string& output ) { _sap("bgtz\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } +void BLEZ( std::string& output ) { disBranch(output, "blez", DECODE_RS); } +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 ADDIU( std::string& output ) @@ -798,15 +828,13 @@ void BEQL( std::string& output ) int rt = DECODE_RT; if (disSimplify && rs == rt) - ssappendf(output, "b\t"); + disBranch(output, "bl"); 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) - ssappendf(output, "beqzl\t%s, ",GPR_REG[rs]); + disBranch(output, "beqzl", rs); else - ssappendf(output, "beql\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]); - - offset_decode(output); + disBranch(output, "beql", rs, rt); } void BNEL( std::string& output ) @@ -815,17 +843,15 @@ void BNEL( std::string& output ) int rt = DECODE_RT; 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) - ssappendf(output, "bnezl\t%s, ",GPR_REG[rs]); + disBranch(output, "bnezl", rs); else - ssappendf(output, "bnel\t%s, %s, ",GPR_REG[rs], GPR_REG[rt]); - - offset_decode(output); + disBranch(output, "bnel", rt, rs); } -void BLEZL( std::string& output ) { _sap("blezl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BGTZL( std::string& output ) { _sap("bgtzl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } +void BLEZL( std::string& output ) { disBranch(output, "blezl", DECODE_RS); } +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 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 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*************************** -void BLTZ( std::string& output ) { _sap("bltz\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BGEZ( std::string& output ) { _sap("bgez\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BLTZL( std::string& output ) { _sap("bltzl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BGEZL( std::string& output ) { _sap("bgezl\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } +void BLTZ( std::string& output ) { disBranch(output, "bltz", DECODE_RS); } +void BGEZ( std::string& output ) { disBranch(output, "bgez", DECODE_RS); } +void BLTZL( std::string& output ) { disBranch(output, "bltzl", DECODE_RS); } +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 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 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 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 BGEZAL( std::string& output ) { _sap("bgezal\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BLTZALL( std::string& output ) { _sap("bltzall\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } -void BGEZALL( std::string& output ) { _sap("bgezall\t%s, ") GPR_REG[DECODE_RS]); offset_decode(output); } +void BLTZAL( std::string& output ) { disBranch(output, "bltzal", DECODE_RS); } +void BGEZAL( std::string& output ) { disBranch(output, "bgezal", DECODE_RS); } +void BLTZALL( std::string& output ) { disBranch(output, "bltzall", DECODE_RS); } +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 MTSAH( std::string& output ) { _sap("mtsah\t%s, 0x%04X") GPR_REG[DECODE_RS], DECODE_IMMED);} From 8d8aa874575c2cdf529f18f6ef25c87a2ac0b03c Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 7 Dec 2014 17:30:22 +0100 Subject: [PATCH 2/8] pcsx2: interpreter: better use pc cpuRegs.pc is the actual pc+4... --- pcsx2/Interpreter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/Interpreter.cpp b/pcsx2/Interpreter.cpp index a4448e8d4c..ab7e9a07a3 100644 --- a/pcsx2/Interpreter.cpp +++ b/pcsx2/Interpreter.cpp @@ -170,7 +170,7 @@ static void execI() // Based on cycle // if( cpuRegs.cycle > 0x4f24d714 ) // Or dump from a particular PC (useful to debug handler/syscall) - if (cpuRegs.pc == 0x80000000) { + if (pc == 0x80000000) { print_me = 2000; } if (print_me) { From 2cfbc6e5ef35afb4bb7d1d082f59fe33e7028dbc Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 7 Dec 2014 17:25:56 +0100 Subject: [PATCH 3/8] pcsx2:tlb: extend goemon gamefix Add GoemonUnloadTlb function that invalidate TLB cache. Currently the function is only used on the interpreter. It fixes TLB error after a reload of data. Next step: porting to the recompiler --- pcsx2/Interpreter.cpp | 10 ++++++++-- pcsx2/R5900.h | 1 + pcsx2/vtlb.cpp | 31 +++++++++++++++++++++++++++++-- pcsx2/vtlb.h | 2 +- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/pcsx2/Interpreter.cpp b/pcsx2/Interpreter.cpp index ab7e9a07a3..4dfc56b4ce 100644 --- a/pcsx2/Interpreter.cpp +++ b/pcsx2/Interpreter.cpp @@ -254,6 +254,11 @@ void J() 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); doBranch(_JumpTarget_); } @@ -456,8 +461,9 @@ void BGEZALL() // Branch if Rs >= 0 and link void JR() { // 0x33ad48 is the return address of the function that populate the TLB cache - if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x33ad48 && EmuConfig.Gamefixes.GoemonTlbHack) { - GoemonPreloadTlb(); + if (EmuConfig.Gamefixes.GoemonTlbHack) { + if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x33ad48) + GoemonPreloadTlb(); } doBranch(cpuRegs.GPR.r[_Rs_].UL[0]); } diff --git a/pcsx2/R5900.h b/pcsx2/R5900.h index cd027895a2..1b8057e0a4 100644 --- a/pcsx2/R5900.h +++ b/pcsx2/R5900.h @@ -430,6 +430,7 @@ extern void cpuTlbMissW(u32 addr, u32 bd); extern void cpuTestHwInts(); extern void cpuClearInt(uint n); extern void __fastcall GoemonPreloadTlb(); +extern void __fastcall GoemonUnloadTlb(u32 key); extern void cpuSetNextEvent( u32 startCycle, s32 delta ); extern void cpuSetNextEventDelta( s32 delta ); diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index da746654b9..6c08b2e119 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -339,7 +339,7 @@ static void GoemonTlbMissDebug() for (u32 i = 0; i < 150; i++) { 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); } } @@ -356,7 +356,7 @@ void __fastcall GoemonPreloadTlb() u32 paddr = tlb[i].physical_add; 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(0x20000000|vaddr , paddr, size); } @@ -364,6 +364,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) { + DevCon.WriteLn("GoemonUnloadTlb: Entry %d. 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); + u32 size = tlb[i].high_add - tlb[i].low_add; + u32 vaddr = tlb[i].low_add; + + 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 is not valid"); + } + } + } +} + // Generates a tlbMiss Exception static __ri void vtlb_Miss(u32 addr,u32 mode) { diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index 1e10a88103..13917b18cd 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -225,6 +225,6 @@ struct GoemonTlb { u32 physical_add; u32 unk3; // likely the size u32 high_add; - u32 unk4; + u32 key; // uniq number attached to an allocation u32 unk5; }; From a8ad59815390407cb890d8770e185061c90f9f75 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 7 Dec 2014 19:24:14 +0100 Subject: [PATCH 4/8] pcsx2:tlb: improve goemon gamefix log --- pcsx2/vtlb.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index 6c08b2e119..0c4bd7a4e7 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -340,6 +340,8 @@ static void GoemonTlbMissDebug() for (u32 i = 0; i < 150; i++) { if (tlb[i].valid == 0x1 && tlb[i].low_add != tlb[i].high_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); } } @@ -371,9 +373,9 @@ void __fastcall GoemonUnloadTlb(u32 key) for (u32 i = 0; i < 150; i++) { if (tlb[i].key == key) { if (tlb[i].valid == 0x1) { - DevCon.WriteLn("GoemonUnloadTlb: Entry %d. 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); 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); @@ -385,7 +387,7 @@ void __fastcall GoemonUnloadTlb(u32 key) tlb[i].low_add = 0xFEFEFEFE; tlb[i].high_add = 0xFEFEFEFE; } else { - DevCon.Error("GoemonUnloadTlb: Entry is not valid"); + DevCon.Error("GoemonUnloadTlb: Entry %d is not valid. Key %x", i, tlb[i].key); } } } From e6de35f5ac0cdd6b3b4c78f6262a5d0cd2393193 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 7 Dec 2014 17:50:38 +0100 Subject: [PATCH 5/8] pcsx2:tlb: enable GoemonUnloadTlb on recompiler --- pcsx2/x86/ix86-32/iR5900-32.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 378adeaf18..edc3fc7ef6 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -1739,9 +1739,15 @@ static void __fastcall recRecompile( const u32 startpc ) xCALL(PreBlockCheck); } - // 0x33ad48 is the return address of the function that populate the TLB cache - if (pc == 0x33ad48 && EmuConfig.Gamefixes.GoemonTlbHack) { - xCALL(GoemonPreloadTlb); + if (EmuConfig.Gamefixes.GoemonTlbHack) { + if (pc == 0x33ad48) { + // 0x33ad48 is the return address of the function that populate the TLB cache + xCALL(GoemonPreloadTlb); + } else if (pc == 0x3563b8) { + // 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 From cb73ed47377d19c783bec55c64c9836e50051e2d Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sun, 7 Dec 2014 19:25:14 +0100 Subject: [PATCH 6/8] pcsx2:tlb:goemon: allocation can be called from 2 places * game is working :) Note1: I dissassemble the main exe to search all call of the allocation (unlikely to have more calls) Note2: it is easier to use the return of the function so allocation is done in the tlb[array] cache --- pcsx2/Interpreter.cpp | 5 +++-- pcsx2/x86/ix86-32/iR5900-32.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pcsx2/Interpreter.cpp b/pcsx2/Interpreter.cpp index 4dfc56b4ce..8a5bb75279 100644 --- a/pcsx2/Interpreter.cpp +++ b/pcsx2/Interpreter.cpp @@ -460,9 +460,10 @@ void BGEZALL() // Branch if Rs >= 0 and link *********************************************************/ 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 (EmuConfig.Gamefixes.GoemonTlbHack) { - if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x33ad48) + u32 add = cpuRegs.GPR.r[_Rs_].UL[0]; + if (add == 0x33ad48 || add == 0x35060c) GoemonPreloadTlb(); } doBranch(cpuRegs.GPR.r[_Rs_].UL[0]); diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index edc3fc7ef6..82578aa8f3 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -1740,8 +1740,8 @@ static void __fastcall recRecompile( const u32 startpc ) } if (EmuConfig.Gamefixes.GoemonTlbHack) { - if (pc == 0x33ad48) { - // 0x33ad48 is the return address of the function that populate the TLB cache + if (pc == 0x33ad48 || pc == 0x35060c) { + // 0x33ad48 and 0x35060c are the return address of the function (0x356250) that populate the TLB cache xCALL(GoemonPreloadTlb); } else if (pc == 0x3563b8) { // 0x3563b8 is the start address of the function that invalidate entry in TLB cache From 18405e2598f5032645201d22830da02f0a90f9ac Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Fri, 12 Dec 2014 22:31:31 +0100 Subject: [PATCH 7/8] gsdx: add goemon comment on some assertion If someone want to trigger them --- plugins/GSdx/GSClut.cpp | 2 +- plugins/GSdx/GSState.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/GSdx/GSClut.cpp b/plugins/GSdx/GSClut.cpp index cf913b3279..01c3cda8fb 100644 --- a/plugins/GSdx/GSClut.cpp +++ b/plugins/GSdx/GSClut.cpp @@ -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 5: if(m_CBP[1] == TEX0.CBP) return false; m_CBP[1] = TEX0.CBP; break; 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); } diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 10917b4fb7..c09eb8c226 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -851,7 +851,7 @@ template void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r) 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 } From 01b0556419bc292667a3608d8377a31bf320bc60 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Fri, 12 Dec 2014 22:43:01 +0100 Subject: [PATCH 8/8] goemon: reset recompiler after tlb unmap Let's avoid unvalid virtual address on recompiler block --- pcsx2/x86/ix86-32/iR5900-32.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 82578aa8f3..9128eae4e5 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -1744,6 +1744,8 @@ static void __fastcall recRecompile( const u32 startpc ) // 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);