From d9ae43b69dac59658686daa22a4f98dbe11ffa55 Mon Sep 17 00:00:00 2001
From: zilmar <zilmar@pj64-emu.com>
Date: Thu, 22 Aug 2024 16:30:20 +0930
Subject: [PATCH] RSP: have RSPRegisterHandlerPlugin as part of RSP System
 instead of a global

---
 Source/Project64-rsp-core/RSPInfo.cpp         |  3 +-
 Source/Project64-rsp-core/RSPInfo.h           |  1 -
 .../Recompiler/RspRecompilerCPU.cpp           | 70 ++++++++++++++++---
 .../Recompiler/RspRecompilerCPU.h             |  8 ++-
 .../Recompiler/RspRecompilerOps.cpp           | 21 +++---
 .../Recompiler/RspRecompilerOps.h             |  1 +
 Source/Project64-rsp-core/cpu/RSPCpu.cpp      |  3 +-
 Source/Project64-rsp-core/cpu/RSPCpu.h        |  1 -
 .../cpu/RSPInterpreterOps.cpp                 | 21 +++---
 .../cpu/RSPInterpreterOps.h                   |  2 +
 Source/Project64-rsp-core/cpu/RSPRegister.cpp |  2 +
 .../cpu/RSPRegisterHandler.cpp                | 29 ++++----
 .../cpu/RSPRegisterHandler.h                  |  3 +-
 .../cpu/RSPRegisterHandlerPlugin.cpp          | 11 +--
 .../cpu/RSPRegisterHandlerPlugin.h            |  6 +-
 Source/Project64-rsp-core/cpu/RspMemory.cpp   | 49 +------------
 Source/Project64-rsp-core/cpu/RspMemory.h     |  7 +-
 Source/Project64-rsp-core/cpu/RspSystem.cpp   | 42 ++++++++++-
 Source/Project64-rsp-core/cpu/RspSystem.h     | 14 ++++
 19 files changed, 186 insertions(+), 108 deletions(-)

diff --git a/Source/Project64-rsp-core/RSPInfo.cpp b/Source/Project64-rsp-core/RSPInfo.cpp
index 89268f192..125e04b08 100644
--- a/Source/Project64-rsp-core/RSPInfo.cpp
+++ b/Source/Project64-rsp-core/RSPInfo.cpp
@@ -147,7 +147,6 @@ void RspRomOpened(void)
     {
         RdramSize = 0x00400000;
     }
-    g_RSPRegisterHandler.reset(new RSPRegisterHandlerPlugin(RSPInfo, RdramSize));
 }
 
 void RspRomClosed(void)
@@ -157,7 +156,7 @@ void RspRomClosed(void)
         StopTimer();
         GenerateTimerResults();
     }
-    g_RSPRegisterHandler.reset(nullptr);
+    RSPSystem.RomClosed();
     ClearAllx86Code();
     RDPLog.StopLog();
     StopCPULog();
diff --git a/Source/Project64-rsp-core/RSPInfo.h b/Source/Project64-rsp-core/RSPInfo.h
index 2d7db73d9..f4b0befed 100644
--- a/Source/Project64-rsp-core/RSPInfo.h
+++ b/Source/Project64-rsp-core/RSPInfo.h
@@ -3,7 +3,6 @@
 class CHle;
 
 extern RSP_INFO RSPInfo;
-extern uint32_t RdramSize;
 extern CHle * g_hle;
 
 void InitilizeRSP(RSP_INFO & Rsp_Info);
diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp
index b9484bcca..dca168238 100644
--- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp
+++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.cpp
@@ -14,6 +14,7 @@
 #include <Project64-rsp-core/cpu/RspSystem.h>
 #include <Project64-rsp-core/cpu/RspTypes.h>
 #include <float.h>
+#include <zlib/zlib.h>
 
 #pragma warning(disable : 4152) // Non-standard extension, function/data pointer conversion in expression
 
@@ -42,7 +43,9 @@ p_Recompfunc RSP_Recomp_Sc2[32];
 
 CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) :
     m_System(System),
-    m_OpCode(System.m_OpCode)
+    m_RSPRegisterHandler(System.m_RSPRegisterHandler),
+    m_OpCode(System.m_OpCode),
+    m_IMEM(System.m_IMEM)
 {
 }
 
@@ -423,13 +426,13 @@ between branches labels, and actual branches, whichever
 occurs first in code
 */
 
-void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
+void CRSPRecompiler::ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
 {
     uint32_t InstructionCount = EndPC - StartPC;
     uint32_t Count, ReorderedOps, CurrentPC;
     RSPOpcode PreviousOp, CurrentOp, RspOp;
 
-    PreviousOp.Value = *(uint32_t *)(RSPInfo.IMEM + (StartPC & 0xFFC));
+    PreviousOp.Value = *(uint32_t *)(m_IMEM + (StartPC & 0xFFC));
 
     if (IsOpcodeBranch(StartPC, PreviousOp))
     {
@@ -464,7 +467,7 @@ void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
     for (Count = 0; Count < InstructionCount; Count += 4)
     {
         CurrentPC = StartPC;
-        PreviousOp.Value = *(uint32_t *)(RSPInfo.IMEM + (CurrentPC & 0xFFC));
+        PreviousOp.Value = *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC));
         ReorderedOps = 0;
 
         for (;;)
@@ -474,13 +477,13 @@ void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
             {
                 break;
             }
-            CurrentOp.Value = *(uint32_t *)(RSPInfo.IMEM + CurrentPC);
+            CurrentOp.Value = *(uint32_t *)(m_IMEM + CurrentPC);
 
             if (CompareInstructions(CurrentPC, &PreviousOp, &CurrentOp))
             {
                 // Move current opcode up
-                *(uint32_t *)(RSPInfo.IMEM + CurrentPC - 4) = CurrentOp.Value;
-                *(uint32_t *)(RSPInfo.IMEM + CurrentPC) = PreviousOp.Value;
+                *(uint32_t *)(m_IMEM + CurrentPC - 4) = CurrentOp.Value;
+                *(uint32_t *)(m_IMEM + CurrentPC) = PreviousOp.Value;
 
                 ReorderedOps++;
 
@@ -488,7 +491,7 @@ void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC)
                 CPU_Message("Swapped %X and %X", CurrentPC - 4, CurrentPC);
 #endif
             }
-            PreviousOp.Value = *(uint32_t *)(RSPInfo.IMEM + (CurrentPC & 0xFFC));
+            PreviousOp.Value = *(uint32_t *)(m_IMEM + (CurrentPC & 0xFFC));
 
             if (IsOpcodeNop(CurrentPC) && IsOpcodeNop(CurrentPC + 4) && IsOpcodeNop(CurrentPC + 8))
             {
@@ -550,6 +553,18 @@ void CRSPRecompiler::ReOrderSubBlock(RSP_BLOCK * Block)
     ReOrderInstructions(Block->CurrPC, end);
 }
 
+void CRSPRecompiler::ResetJumpTables(void)
+{
+    extern uint32_t NoOfMaps;
+    extern uint8_t * JumpTables;
+
+    memset(JumpTables, 0, 0x1000 * MaxMaps);
+    RecompPos = RecompCode;
+    pLastPrimary = nullptr;
+    pLastSecondary = nullptr;
+    NoOfMaps = 0;
+}
+
 /*
 DetectGPRConstants
 Description:
@@ -951,7 +966,7 @@ void CRSPRecompiler::CompilerRSPBlock(void)
     free(IMEM_SAVE);
 }
 
-uint32_t CRSPRecompiler::RunCPU(uint32_t Cycles)
+void CRSPRecompiler::RunCPU(void)
 {
 #ifndef EXCEPTION_EXECUTE_HANDLER
 #define EXCEPTION_EXECUTE_HANDLER 1
@@ -1040,7 +1055,6 @@ uint32_t CRSPRecompiler::RunCPU(uint32_t Cycles)
         g_Notify->BreakPoint(__FILE__, __LINE__);
 #endif
     }
-    return Cycles;
 }
 
 void CRSPRecompiler::Branch_AddRef(uint32_t Target, uint32_t * X86Loc)
@@ -1067,3 +1081,39 @@ void CRSPRecompiler::Branch_AddRef(uint32_t Target, uint32_t * X86Loc)
         }
     }
 }
+
+void CRSPRecompiler::SetJumpTable(uint32_t End)
+{
+    extern uint32_t NoOfMaps, MapsCRC[32];
+    extern uint8_t * JumpTables;
+
+    uint32_t CRC = crc32(0L, Z_NULL, 0);
+    if (End < 0x800)
+    {
+        End = 0x800;
+    }
+
+    if (End == 0x1000 && ((m_RSPRegisterHandler->PendingSPMemAddr() & 0x0FFF) & ~7) == 0x80)
+    {
+        End = 0x800;
+    }
+
+    CRC = crc32(CRC, RSPInfo.IMEM, End);
+    for (uint32_t i = 0; i < NoOfMaps; i++)
+    {
+        if (CRC == MapsCRC[i])
+        {
+            JumpTable = (void **)(JumpTables + i * 0x1000);
+            Table = i;
+            return;
+        }
+    }
+    if (NoOfMaps == MaxMaps)
+    {
+        ResetJumpTables();
+    }
+    MapsCRC[NoOfMaps] = CRC;
+    JumpTable = (void **)(JumpTables + NoOfMaps * 0x1000);
+    Table = NoOfMaps;
+    NoOfMaps += 1;
+}
\ No newline at end of file
diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h
index 8a8de76be..cf613b0e0 100644
--- a/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h
+++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerCPU.h
@@ -6,6 +6,7 @@
 #include <Settings/Settings.h>
 
 class CRSPSystem;
+class RSPRegisterHandlerPlugin;
 
 class CRSPRecompiler
 {
@@ -27,8 +28,9 @@ class CRSPRecompiler
 public:
     CRSPRecompiler(CRSPSystem & System);
 
-    uint32_t RunCPU(uint32_t Cycles);
+    void RunCPU(void);
     void Branch_AddRef(uint32_t Target, uint32_t * X86Loc);
+    void SetJumpTable(uint32_t End);
 
 private:
     CRSPRecompiler();
@@ -38,10 +40,14 @@ private:
     void CompilerRSPBlock(void);
     void LinkBranches(RSP_BLOCK * Block);
     void ReOrderSubBlock(RSP_BLOCK * Block);
+    void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC);
+    void ResetJumpTables(void);
 
     CRSPSystem & m_System;
+    RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
     RSPOpcode & m_OpCode;
     RSP_BLOCK m_CurrentBlock;
+    uint8_t *& m_IMEM;
 };
 
 extern uint32_t CompilePC, NextInstruction, JumpTableSize;
diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp
index 6144bda49..57998b6b6 100644
--- a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp
+++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp
@@ -160,6 +160,7 @@ void CompileBranchExit(uint32_t TargetPC, uint32_t ContinuePC)
 
 CRSPRecompilerOps::CRSPRecompilerOps(CRSPSystem & System, CRSPRecompiler & Recompiler) :
     m_System(System),
+    m_RSPRegisterHandler(System.m_RSPRegisterHandler),
     m_Recompiler(Recompiler),
     m_OpCode(System.m_OpCode),
     m_Reg(System.m_Reg),
@@ -2198,31 +2199,31 @@ void CRSPRecompilerOps::Cop0_MF(void)
     switch (m_OpCode.rd)
     {
     case 0:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         PushImm32("RSPRegister_MEM_ADDR", RSPRegister_MEM_ADDR);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg");
         MoveX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt));
         break;
     case 1:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         PushImm32("RSPRegister_DRAM_ADDR", RSPRegister_DRAM_ADDR);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg");
         MoveX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt));
         break;
     case 2:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         PushImm32("RSPRegister_RD_LEN", RSPRegister_RD_LEN);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg");
         MoveX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt));
         break;
     case 3:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         PushImm32("RSPRegister_WR_LEN", RSPRegister_WR_LEN);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg");
         MoveX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt));
         break;
     case 4:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         PushImm32("RSPRegister_STATUS", RSPRegister_STATUS);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg");
         MoveX86regToVariable(x86_EAX, &m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt));
@@ -2334,35 +2335,35 @@ void CRSPRecompilerOps::Cop0_MT(void)
     switch (m_OpCode.rd)
     {
     case 0:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         MoveVariableToX86reg(&m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt), x86_EAX);
         Push(x86_EAX);
         PushImm32("RSPRegister_MEM_ADDR", RSPRegister_MEM_ADDR);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::WriteReg), "RSPRegisterHandlerPlugin::WriteReg");
         break;
     case 1:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         MoveVariableToX86reg(&m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt), x86_EAX);
         Push(x86_EAX);
         PushImm32("RSPRegister_DRAM_ADDR", RSPRegister_DRAM_ADDR);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::WriteReg), "RSPRegisterHandlerPlugin::WriteReg");
         break;
     case 2:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         MoveVariableToX86reg(&m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt), x86_EAX);
         Push(x86_EAX);
         PushImm32("RSPRegister_RD_LEN", RSPRegister_RD_LEN);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::WriteReg), "RSPRegisterHandlerPlugin::WriteReg");
         break;
     case 3:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         MoveVariableToX86reg(&m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt), x86_EAX);
         Push(x86_EAX);
         PushImm32("RSPRegister_WR_LEN", RSPRegister_WR_LEN);
         Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::WriteReg), "RSPRegisterHandlerPlugin::WriteReg");
         break;
     case 4:
-        MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX);
+        MoveConstToX86reg((uint32_t)m_RSPRegisterHandler, x86_ECX);
         MoveVariableToX86reg(&m_GPR[m_OpCode.rt].UW, GPR_Name(m_OpCode.rt), x86_EAX);
         Push(x86_EAX);
         PushImm32("RSPRegister_STATUS", RSPRegister_STATUS);
diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h
index 7e0150723..973a8577f 100644
--- a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h
+++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.h
@@ -202,6 +202,7 @@ private:
     void resampler_hle();
 
     CRSPSystem & m_System;
+    RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
     CRSPRegisters & m_Reg;
     CRSPRecompiler & m_Recompiler;
     RSPOpcode & m_OpCode;
diff --git a/Source/Project64-rsp-core/cpu/RSPCpu.cpp b/Source/Project64-rsp-core/cpu/RSPCpu.cpp
index ea47b41c6..d4778b495 100644
--- a/Source/Project64-rsp-core/cpu/RSPCpu.cpp
+++ b/Source/Project64-rsp-core/cpu/RSPCpu.cpp
@@ -19,7 +19,6 @@ void BuildRecompilerCPU(void);
 CriticalSection g_CPUCriticalSection;
 uint32_t Mfc0Count, SemaphoreExit = 0;
 RSPCpuType g_CPUCore = InterpreterCPU;
-std::unique_ptr<RSPRegisterHandlerPlugin> g_RSPRegisterHandler;
 
 void SetCPU(RSPCpuType core)
 {
@@ -180,7 +179,7 @@ uint32_t DoRspCycles(uint32_t Cycles)
     switch (g_CPUCore)
     {
     case RecompilerCPU:
-        CRSPRecompiler(RSPSystem).RunCPU(Cycles);
+        RSPSystem.RunRecompiler();
         break;
     case InterpreterCPU:
         RSPSystem.RunInterpreterCPU(Cycles);
diff --git a/Source/Project64-rsp-core/cpu/RSPCpu.h b/Source/Project64-rsp-core/cpu/RSPCpu.h
index b13222996..50d3b99ea 100644
--- a/Source/Project64-rsp-core/cpu/RSPCpu.h
+++ b/Source/Project64-rsp-core/cpu/RSPCpu.h
@@ -20,4 +20,3 @@ void Build_RSP(void);
 
 extern uint32_t Mfc0Count, SemaphoreExit;
 extern RSPCpuType g_CPUCore;
-extern std::unique_ptr<RSPRegisterHandlerPlugin> g_RSPRegisterHandler;
diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp
index 64c55c3f7..d7b87897d 100644
--- a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp
+++ b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp
@@ -58,6 +58,7 @@ uint32_t clz32(uint32_t val)
 
 RSPOp::RSPOp(CRSPSystem & System) :
     m_System(System),
+    m_RSPRegisterHandler(System.m_RSPRegisterHandler),
     m_OpCode(System.m_OpCode),
     m_Reg(System.m_Reg),
     m_MI_INTR_REG(System.m_MI_INTR_REG),
@@ -817,11 +818,11 @@ void RSPOp::Cop0_MF(void)
     }
     switch (m_OpCode.rd)
     {
-    case 0: m_GPR[m_OpCode.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_MEM_ADDR); break;
-    case 1: m_GPR[m_OpCode.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_DRAM_ADDR); break;
-    case 2: m_GPR[m_OpCode.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_RD_LEN); break;
-    case 3: m_GPR[m_OpCode.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_WR_LEN); break;
-    case 4: m_GPR[m_OpCode.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_STATUS); break;
+    case 0: m_GPR[m_OpCode.rt].UW = m_RSPRegisterHandler->ReadReg(RSPRegister_MEM_ADDR); break;
+    case 1: m_GPR[m_OpCode.rt].UW = m_RSPRegisterHandler->ReadReg(RSPRegister_DRAM_ADDR); break;
+    case 2: m_GPR[m_OpCode.rt].UW = m_RSPRegisterHandler->ReadReg(RSPRegister_RD_LEN); break;
+    case 3: m_GPR[m_OpCode.rt].UW = m_RSPRegisterHandler->ReadReg(RSPRegister_WR_LEN); break;
+    case 4: m_GPR[m_OpCode.rt].UW = m_RSPRegisterHandler->ReadReg(RSPRegister_STATUS); break;
     case 5: m_GPR[m_OpCode.rt].UW = *m_SP_DMA_FULL_REG; break;
     case 6: m_GPR[m_OpCode.rt].UW = *m_SP_DMA_BUSY_REG; break;
     case 7:
@@ -853,11 +854,11 @@ void RSPOp::Cop0_MT(void)
     }
     switch (m_OpCode.rd)
     {
-    case 0: g_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, m_GPR[m_OpCode.rt].UW); break;
-    case 1: g_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, m_GPR[m_OpCode.rt].UW); break;
-    case 2: g_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, m_GPR[m_OpCode.rt].UW); break;
-    case 3: g_RSPRegisterHandler->WriteReg(RSPRegister_WR_LEN, m_GPR[m_OpCode.rt].UW); break;
-    case 4: g_RSPRegisterHandler->WriteReg(RSPRegister_STATUS, m_GPR[m_OpCode.rt].UW); break;
+    case 0: m_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, m_GPR[m_OpCode.rt].UW); break;
+    case 1: m_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, m_GPR[m_OpCode.rt].UW); break;
+    case 2: m_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, m_GPR[m_OpCode.rt].UW); break;
+    case 3: m_RSPRegisterHandler->WriteReg(RSPRegister_WR_LEN, m_GPR[m_OpCode.rt].UW); break;
+    case 4: m_RSPRegisterHandler->WriteReg(RSPRegister_STATUS, m_GPR[m_OpCode.rt].UW); break;
     case 7: *m_SP_SEMAPHORE_REG = 0; break;
     case 8:
         *m_DPC_START_REG = m_GPR[m_OpCode.rt].UW;
diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h
index e0fbae834..23f792016 100644
--- a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h
+++ b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.h
@@ -4,6 +4,7 @@
 
 class CRSPSystem;
 class CRSPRegisters;
+class RSPRegisterHandlerPlugin;
 
 class RSPOp
 {
@@ -182,6 +183,7 @@ private:
     Func Jump_Sc2[32];
 
     CRSPSystem & m_System;
+    RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
     RSPOpcode & m_OpCode;
     CRSPRegisters & m_Reg;
     uint32_t *& m_MI_INTR_REG;
diff --git a/Source/Project64-rsp-core/cpu/RSPRegister.cpp b/Source/Project64-rsp-core/cpu/RSPRegister.cpp
index 8ec1dd145..1c9dbcba4 100644
--- a/Source/Project64-rsp-core/cpu/RSPRegister.cpp
+++ b/Source/Project64-rsp-core/cpu/RSPRegister.cpp
@@ -50,6 +50,8 @@ CRSPRegisters::CRSPRegisters() :
 void CRSPRegisters::Reset(void)
 {
     memset(m_GPR, 0, sizeof(m_GPR));
+    memset(m_Flags, 0, sizeof(m_Flags));
+    memset(m_ACCUM, 0, sizeof(m_ACCUM));
     for (size_t i = 0, n = sizeof(m_Vect) / sizeof(m_Vect[0]); i < n; i++)
     {
         m_Vect[i] = RSPVector();
diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp
index a41869463..182e6c8e4 100644
--- a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp
+++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp
@@ -1,6 +1,7 @@
 #include "RSPRegisterHandler.h"
 #include "RSPRegisters.h"
 #include <Project64-plugin-spec/Rsp.h>
+#include <Project64-rsp-core/cpu/RspSystem.h>
 #include <Settings/Settings.h>
 #include <string.h>
 
@@ -23,20 +24,20 @@ RSPRegisterHandler::RSPRegisterHandler(uint32_t * SignalProcessorInterface, uint
 {
 }
 
-RSPRegisterHandler::RSPRegisterHandler(_RSP_INFO & RSPInfo, const uint32_t & RdramSize) :
-    SP_MEM_ADDR_REG(*RSPInfo.SP_MEM_ADDR_REG),
-    SP_DRAM_ADDR_REG(*RSPInfo.SP_DRAM_ADDR_REG),
-    SP_RD_LEN_REG((LengthReg &)*RSPInfo.SP_RD_LEN_REG),
-    SP_WR_LEN_REG((LengthReg &)*RSPInfo.SP_WR_LEN_REG),
-    SP_STATUS_REG(*RSPInfo.SP_STATUS_REG),
-    SP_DMA_FULL_REG(*RSPInfo.SP_DMA_FULL_REG),
-    SP_DMA_BUSY_REG(*RSPInfo.SP_DMA_BUSY_REG),
-    SP_SEMAPHORE_REG(*RSPInfo.SP_SEMAPHORE_REG),
-    SP_PC_REG(*RSPInfo.SP_PC_REG),
-    m_Rdram(RSPInfo.RDRAM),
-    m_RdramSize(RdramSize),
-    m_IMEM(RSPInfo.IMEM),
-    m_DMEM(RSPInfo.DMEM),
+RSPRegisterHandler::RSPRegisterHandler(CRSPSystem & System) :
+    SP_MEM_ADDR_REG(*System.m_SP_MEM_ADDR_REG),
+    SP_DRAM_ADDR_REG(*System.m_SP_DRAM_ADDR_REG),
+    SP_RD_LEN_REG((LengthReg &)*System.m_SP_RD_LEN_REG),
+    SP_WR_LEN_REG((LengthReg &)*System.m_SP_WR_LEN_REG),
+    SP_STATUS_REG(*System.m_SP_STATUS_REG),
+    SP_DMA_FULL_REG(*System.m_SP_DMA_FULL_REG),
+    SP_DMA_BUSY_REG(*System.m_SP_DMA_BUSY_REG),
+    SP_SEMAPHORE_REG(*System.m_SP_SEMAPHORE_REG),
+    SP_PC_REG(*System.m_SP_PC_REG),
+    m_Rdram(System.m_RDRAM),
+    m_RdramSize(System.m_RdramSize),
+    m_IMEM(System.m_IMEM),
+    m_DMEM(System.m_DMEM),
     m_PendingSPMemAddr(0),
     m_PendingSPDramAddr(0)
 {
diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h
index 3f0c41cd9..567e39704 100644
--- a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h
+++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h
@@ -13,6 +13,7 @@ enum RSPRegister
 };
 
 struct _RSP_INFO;
+class CRSPSystem;
 
 class RSPRegisterHandler
 {
@@ -33,7 +34,7 @@ class RSPRegisterHandler
 
 public:
     RSPRegisterHandler(uint32_t * SignalProcessorInterface, uint8_t *& Rdram, const uint32_t & RdramSize, uint8_t * IMEM, uint8_t * DMEM);
-    RSPRegisterHandler(_RSP_INFO & RSPInfo, const uint32_t & RdramSize);
+    RSPRegisterHandler(CRSPSystem & System);
 
     void SP_DMA_READ(void);
     void SP_DMA_WRITE(void);
diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp
index 1a3433559..4c618935b 100644
--- a/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp
+++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp
@@ -2,10 +2,13 @@
 #include "RSPCpu.h"
 #include "RSPRegisters.h"
 #include <Project64-rsp-core/RSPInfo.h>
+#include <Project64-rsp-core/Recompiler/RspRecompilerCPU.h>
 #include <Project64-rsp-core/cpu/RspMemory.h>
+#include <Project64-rsp-core/cpu/RspSystem.h>
 
-RSPRegisterHandlerPlugin::RSPRegisterHandlerPlugin(_RSP_INFO & Info, const uint32_t & Size) :
-    RSPRegisterHandler(Info, Size)
+RSPRegisterHandlerPlugin::RSPRegisterHandlerPlugin(CRSPSystem & System) :
+    RSPRegisterHandler(System),
+    m_System(System)
 {
 }
 
@@ -38,8 +41,8 @@ void RSPRegisterHandlerPlugin::SetHalt(void)
 
 void RSPRegisterHandlerPlugin::DmaReadDone(uint32_t End)
 {
-    if (g_CPUCore == RecompilerCPU && (*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0)
+    if (g_CPUCore == RecompilerCPU && (*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0 && m_System.m_Recompiler != nullptr)
     {
-        SetJumpTable(End);
+        m_System.m_Recompiler->SetJumpTable(End);
     }
 }
diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h
index 54cbccec8..916fc0098 100644
--- a/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h
+++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h
@@ -1,11 +1,13 @@
 #pragma once
 #include "RSPRegisterHandler.h"
 
+class CRSPSystem;
+
 class RSPRegisterHandlerPlugin :
     public RSPRegisterHandler
 {
 public:
-    RSPRegisterHandlerPlugin(_RSP_INFO & RSPInfo, const uint32_t & RdramSize);
+    RSPRegisterHandlerPlugin(CRSPSystem & System);
 
     uint32_t & PendingSPMemAddr();
     uint32_t & PendingSPDramAddr();
@@ -15,4 +17,6 @@ private:
     void SetSPInterrupt(void);
     void SetHalt(void);
     void DmaReadDone(uint32_t End);
+
+    CRSPSystem & m_System;
 };
diff --git a/Source/Project64-rsp-core/cpu/RspMemory.cpp b/Source/Project64-rsp-core/cpu/RspMemory.cpp
index 280100e89..7fb633235 100644
--- a/Source/Project64-rsp-core/cpu/RspMemory.cpp
+++ b/Source/Project64-rsp-core/cpu/RspMemory.cpp
@@ -2,16 +2,12 @@
 #include <Project64-rsp-core/RSPInfo.h>
 #include <Project64-rsp-core/cpu/RSPCpu.h>
 #include <Project64-rsp-core/cpu/RSPRegisters.h>
+#include <Project64-rsp-core/cpu/RspMemory.h>
 #include <Settings/Settings.h>
 #include <stdio.h>
 #include <string.h>
 #include <zlib/zlib.h>
 
-enum
-{
-    MaxMaps = 32
-};
-
 uint32_t NoOfMaps, MapsCRC[MaxMaps];
 uint32_t Table;
 uint8_t *RecompCode, *RecompCodeSecondary, *RecompPos, *JumpTables;
@@ -72,49 +68,6 @@ void FreeMemory(void)
     RecompCodeSecondary = nullptr;
 }
 
-void ResetJumpTables(void)
-{
-    memset(JumpTables, 0, 0x1000 * MaxMaps);
-    RecompPos = RecompCode;
-    pLastPrimary = nullptr;
-    pLastSecondary = nullptr;
-    NoOfMaps = 0;
-}
-
-void SetJumpTable(uint32_t End)
-{
-    uint32_t CRC = crc32(0L, Z_NULL, 0);
-    if (End < 0x800)
-    {
-        End = 0x800;
-    }
-
-    if (End == 0x1000 && ((g_RSPRegisterHandler->PendingSPMemAddr() & 0x0FFF) & ~7) == 0x80)
-    {
-        End = 0x800;
-    }
-
-    CRC = crc32(CRC, RSPInfo.IMEM, End);
-    for (uint32_t i = 0; i < NoOfMaps; i++)
-    {
-        if (CRC == MapsCRC[i])
-        {
-            JumpTable = (void **)(JumpTables + i * 0x1000);
-            Table = i;
-            return;
-        }
-    }
-    //DisplayError("%X %X",NoOfMaps,CRC);
-    if (NoOfMaps == MaxMaps)
-    {
-        ResetJumpTables();
-    }
-    MapsCRC[NoOfMaps] = CRC;
-    JumpTable = (void **)(JumpTables + NoOfMaps * 0x1000);
-    Table = NoOfMaps;
-    NoOfMaps += 1;
-}
-
 void RSP_LW_IMEM(uint32_t Addr, uint32_t * Value)
 {
     if ((Addr & 0x3) != 0)
diff --git a/Source/Project64-rsp-core/cpu/RspMemory.h b/Source/Project64-rsp-core/cpu/RspMemory.h
index 7fa2bbe62..c7dfd802c 100644
--- a/Source/Project64-rsp-core/cpu/RspMemory.h
+++ b/Source/Project64-rsp-core/cpu/RspMemory.h
@@ -2,13 +2,16 @@
 
 #include <Project64-rsp-core/cpu/RspTypes.h>
 
+enum
+{
+    MaxMaps = 32
+};
+
 int AllocateMemory(void);
 void FreeMemory(void);
-void SetJumpTable(uint32_t End);
 
 extern uint8_t *RecompCode, *RecompCodeSecondary, *RecompPos;
 extern void ** JumpTable;
 extern uint32_t Table;
 
 void RSP_LW_IMEM(uint32_t Addr, uint32_t * Value);
-void RSP_SWV_DMEM(uint32_t Addr, uint8_t vect, uint8_t element);
diff --git a/Source/Project64-rsp-core/cpu/RspSystem.cpp b/Source/Project64-rsp-core/cpu/RspSystem.cpp
index 431f85300..4ae85d7d3 100644
--- a/Source/Project64-rsp-core/cpu/RspSystem.cpp
+++ b/Source/Project64-rsp-core/cpu/RspSystem.cpp
@@ -1,13 +1,18 @@
 #include <Project64-rsp-core/RSPDebugger.h>
 #include <Project64-rsp-core/RSPInfo.h>
+#include <Project64-rsp-core/Recompiler/RspRecompilerCPU.h>
+#include <Project64-rsp-core/Settings/RspSettings.h>
 #include <Project64-rsp-core/cpu/RSPCpu.h>
 #include <Project64-rsp-core/cpu/RSPInterpreterCPU.h>
 #include <Project64-rsp-core/cpu/RSPRegisters.h>
 #include <Project64-rsp-core/cpu/RspSystem.h>
+#include <Settings/Settings.h>
 
 CRSPSystem RSPSystem;
 
 CRSPSystem::CRSPSystem() :
+    m_Recompiler(nullptr),
+    m_RSPRegisterHandler(nullptr),
     m_Op(*this),
     m_HEADER(nullptr),
     m_RDRAM(nullptr),
@@ -32,8 +37,19 @@ CRSPSystem::CRSPSystem() :
     m_DPC_PIPEBUSY_REG(nullptr),
     m_DPC_TMEM_REG(nullptr),
     CheckInterrupts(nullptr),
-    ProcessRdpList(nullptr)
+    ProcessRdpList(nullptr),
+    m_RdramSize(0)
 {
+    m_OpCode.Value = 0;
+}
+
+CRSPSystem::~CRSPSystem()
+{
+    if (m_RSPRegisterHandler != nullptr)
+    {
+        delete m_RSPRegisterHandler;
+        m_RSPRegisterHandler = nullptr;
+    }
 }
 
 void CRSPSystem::Reset(RSP_INFO & Info)
@@ -64,6 +80,30 @@ void CRSPSystem::Reset(RSP_INFO & Info)
     m_DPC_TMEM_REG = Info.DPC_TMEM_REG;
     CheckInterrupts = Info.CheckInterrupts;
     ProcessRdpList = Info.ProcessRdpList;
+
+    m_RdramSize = Set_AllocatedRdramSize != 0 ? GetSystemSetting(Set_AllocatedRdramSize) : 0;
+    if (m_RdramSize == 0)
+    {
+        m_RdramSize = 0x00400000;
+    }
+    m_RSPRegisterHandler = new RSPRegisterHandlerPlugin(*this);
+}
+
+void CRSPSystem::RomClosed(void)
+{
+    if (m_RSPRegisterHandler != nullptr)
+    {
+        delete m_RSPRegisterHandler;
+        m_RSPRegisterHandler = nullptr;
+    }
+}
+
+void CRSPSystem::RunRecompiler(void)
+{
+    CRSPRecompiler Recompiler(RSPSystem);
+    m_Recompiler = &Recompiler;
+    Recompiler.RunCPU();
+    m_Recompiler = nullptr;
 }
 
 uint32_t CRSPSystem::RunInterpreterCPU(uint32_t Cycles)
diff --git a/Source/Project64-rsp-core/cpu/RspSystem.h b/Source/Project64-rsp-core/cpu/RspSystem.h
index f72357987..cdc02a344 100644
--- a/Source/Project64-rsp-core/cpu/RspSystem.h
+++ b/Source/Project64-rsp-core/cpu/RspSystem.h
@@ -5,6 +5,8 @@
 #include <Project64-rsp-core/cpu/RspTypes.h>
 #include <stdint.h>
 
+class RSPRegisterHandlerPlugin;
+
 class CRSPSystem
 {
     friend class RSPOp;
@@ -12,16 +14,27 @@ class CRSPSystem
     friend class CRSPRecompiler;
     friend class RSPDebuggerUI;
     friend class CRDPLog;
+    friend class RSPRegisterHandler;
+    friend class RSPRegisterHandlerPlugin;
+
     friend void UpdateRSPRegistersScreen(void);
 
 public:
     CRSPSystem();
+    ~CRSPSystem();
 
     void Reset(RSP_INFO & Info);
+    void RomClosed(void);
 
+    void RunRecompiler(void);
     uint32_t RunInterpreterCPU(uint32_t Cycles);
 
 private:
+    CRSPSystem(const CRSPSystem &);
+    CRSPSystem & operator=(const CRSPSystem &);
+
+    CRSPRecompiler * m_Recompiler;
+    RSPRegisterHandlerPlugin * m_RSPRegisterHandler;
     CRSPRegisters m_Reg;
     RSPOp m_Op;
     RSPOpcode m_OpCode;
@@ -47,6 +60,7 @@ private:
     uint32_t * m_DPC_BUFBUSY_REG;
     uint32_t * m_DPC_PIPEBUSY_REG;
     uint32_t * m_DPC_TMEM_REG;
+    uint32_t m_RdramSize;
     void (*CheckInterrupts)(void);
     void (*ProcessRdpList)(void);
 };