From f22e5125c50c2592a193c442787c75d46e82e653 Mon Sep 17 00:00:00 2001 From: LegendOfDragoon Date: Sun, 19 Apr 2015 19:16:10 -0700 Subject: [PATCH 1/4] Fix memory leak in RSP Due to the newer spec design in PJ64 2.x, CloseDLL() doesn't get called as often. So there are instances where it calls AllocateMemory() multiple times without ever calling FreeMemory(). --- Source/RSP/memory.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/Source/RSP/memory.c b/Source/RSP/memory.c index 6d1e5f4f6..a6cf3c026 100644 --- a/Source/RSP/memory.c +++ b/Source/RSP/memory.c @@ -35,24 +35,30 @@ BYTE * RecompCode, * RecompCodeSecondary, * RecompPos, *JumpTables; void ** JumpTable; int AllocateMemory (void) { - RecompCode=(BYTE *) VirtualAlloc( NULL, 0x00400004, MEM_RESERVE, PAGE_EXECUTE_READWRITE); - RecompCode=(BYTE *) VirtualAlloc( RecompCode, 0x00400000, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - - if(RecompCode == NULL) { - DisplayError("Not enough memory for RSP RecompCode!"); - return FALSE; + if (RecompCode == NULL){ + RecompCode=(BYTE *) VirtualAlloc( NULL, 0x00400004, MEM_RESERVE, PAGE_EXECUTE_READWRITE); + RecompCode=(BYTE *) VirtualAlloc( RecompCode, 0x00400000, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + if(RecompCode == NULL) { + DisplayError("Not enough memory for RSP RecompCode!"); + return FALSE; + } } - RecompCodeSecondary = (BYTE *)VirtualAlloc( NULL, 0x00200000, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); - if(RecompCodeSecondary == NULL) { - DisplayError("Not enough memory for RSP RecompCode Secondary!"); - return FALSE; + if (RecompCodeSecondary == NULL){ + RecompCodeSecondary = (BYTE *)VirtualAlloc( NULL, 0x00200000, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + if(RecompCodeSecondary == NULL) { + DisplayError("Not enough memory for RSP RecompCode Secondary!"); + return FALSE; + } } - JumpTables = (BYTE *)VirtualAlloc( NULL, 0x1000 * MaxMaps, MEM_COMMIT, PAGE_READWRITE ); - if( JumpTables == NULL ) { - DisplayError("Not enough memory for Jump Table!"); - return FALSE; + if (JumpTables == NULL){ + JumpTables = (BYTE *)VirtualAlloc( NULL, 0x1000 * MaxMaps, MEM_COMMIT, PAGE_READWRITE ); + if( JumpTables == NULL ) { + DisplayError("Not enough memory for Jump Table!"); + return FALSE; + } } JumpTable = (void **)JumpTables; @@ -65,6 +71,10 @@ void FreeMemory (void) { VirtualFree( RecompCode, 0 , MEM_RELEASE); VirtualFree( JumpTable, 0 , MEM_RELEASE); VirtualFree( RecompCodeSecondary, 0 , MEM_RELEASE); + + RecompCode = NULL; + JumpTables = NULL; + RecompCodeSecondary = NULL; } void ResetJumpTables ( void ) From 82f614ff2dc59a2863f17ebd90dbe8c173892440 Mon Sep 17 00:00:00 2001 From: LegendOfDragoon Date: Sun, 19 Apr 2015 20:56:36 -0700 Subject: [PATCH 2/4] Fix / Optimize RSP Accumulator Analysis the & 0xFFC was missing, which caused it to return true when it should have returned false. This means that LLE audio should be more optimized now. I also made it do delay slot, incase the delay slot instruction writes to accumulator. Minor optimization here. As for JAL, I made it do break instead of return FALSE because in Battle For Naboo, it actually does come back and continue an existing calculation. I think it is only an issue if you do a separate analysis for the Low Accumulator and Mid/High Accumulators. It's still better to be safe, just incase I or someone else actually implement a separate analysis for the Accumulators later down the road. --- Source/RSP/Recompiler Analysis.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Source/RSP/Recompiler Analysis.c b/Source/RSP/Recompiler Analysis.c index 63141c71c..dc65196b6 100644 --- a/Source/RSP/Recompiler Analysis.c +++ b/Source/RSP/Recompiler Analysis.c @@ -199,16 +199,24 @@ DWORD WriteToAccum2 (int Location, int PC, BOOL RecursiveCall) { break; case RSP_J: /* there is no way a loopback is going to use accumulator */ - if (Compiler.bAudioUcode && ((int)(RspOp.target << 2) < PC)) { + if (Compiler.bAudioUcode && (((int)(RspOp.target << 2) & 0xFFC) < PC)) { return FALSE; } /* rarely occurs let them have their way */ - return TRUE; + else { + Instruction_State = DO_DELAY_SLOT; + break; + } case RSP_JAL: /* there is no way calling a subroutine is going to use accum */ /* or come back and continue an existing calculation */ - return (Compiler.bAudioUcode) ? FALSE : TRUE; + if(Compiler.bAudioUcode) { + break; + } else { + Instruction_State = DO_DELAY_SLOT; + break; + } case RSP_BEQ: case RSP_BNE: From 603df8e167004cab8db03bc016bd74360fff5e31 Mon Sep 17 00:00:00 2001 From: LegendOfDragoon Date: Sun, 19 Apr 2015 21:11:47 -0700 Subject: [PATCH 3/4] Add 2 cases in Cop0_MF for RSP Recompiler Case 0 and Case 1 was missing in RSP Recompiler. Jet Force Gemini LLE GFX uses case 1. --- Source/RSP/Recompiler Ops.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/RSP/Recompiler Ops.c b/Source/RSP/Recompiler Ops.c index 5334b95a1..2f52ee040 100644 --- a/Source/RSP/Recompiler Ops.c +++ b/Source/RSP/Recompiler Ops.c @@ -1554,6 +1554,14 @@ void Compile_Cop0_MF ( void ) { return; #else switch (RSPOpC.rd) { + case 0: + MoveVariableToX86reg(RSPInfo.SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG", x86_EAX); + MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); + break; + case 1: + MoveVariableToX86reg(RSPInfo.SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG", x86_EAX); + MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); + break; case 5: MoveVariableToX86reg(RSPInfo.SP_DMA_FULL_REG, "SP_DMA_FULL_REG", x86_EAX); MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); From 882b0f584188cce003b007b411b82582ddd94dc1 Mon Sep 17 00:00:00 2001 From: LegendOfDragoon Date: Sun, 19 Apr 2015 21:20:10 -0700 Subject: [PATCH 4/4] Change CompilerWarning to DisplayError in Cop0_MF In RSP interpreter, it is DisplayError and I feel like it's an important message, so it should be DisplayError in RSP recompiler as well, in my opinion. --- Source/RSP/Recompiler Ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RSP/Recompiler Ops.c b/Source/RSP/Recompiler Ops.c index 2f52ee040..3c2f7070b 100644 --- a/Source/RSP/Recompiler Ops.c +++ b/Source/RSP/Recompiler Ops.c @@ -1608,7 +1608,7 @@ void Compile_Cop0_MF ( void ) { break; default: - CompilerWarning("have not implemented RSP MF CP0 reg %s (%d)",COP0_Name(RSPOpC.rd),RSPOpC.rd); + DisplayError("have not implemented RSP MF CP0 reg %s (%d)",COP0_Name(RSPOpC.rd),RSPOpC.rd); } #endif }