diff --git a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp index d9e43c117..3f8197401 100644 --- a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp +++ b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp @@ -172,6 +172,10 @@ void SPRegistersHandler::SetHalt(void) { } +void SPRegistersHandler::DmaReadDone(uint32_t /*End*/) +{ +} + void SPRegistersHandler::SystemReset(void) { SP_RD_LEN_REG = 0x00000FF8; diff --git a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h index 50b23b120..83843f3d4 100644 --- a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h +++ b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h @@ -70,6 +70,7 @@ private: void ClearSPInterrupt(void); void SetSPInterrupt(void); void SetHalt(void); + void DmaReadDone(uint32_t End); void SystemReset(void); uint8_t m_IMEM[0x1000]; diff --git a/Source/Project64-plugin-spec/Rsp.h b/Source/Project64-plugin-spec/Rsp.h index 3133bea28..32faacc71 100644 --- a/Source/Project64-plugin-spec/Rsp.h +++ b/Source/Project64-plugin-spec/Rsp.h @@ -1,7 +1,7 @@ #pragma once #include "Base.h" -typedef struct +typedef struct _RSP_INFO { void * hInst; int MemoryBswaped; // If this is set to TRUE, then the memory has been pre-bswap'd on a DWORD (32-bit) boundary diff --git a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj index 9676ddf31..a905a6524 100644 --- a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj +++ b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj @@ -42,7 +42,6 @@ - @@ -50,6 +49,7 @@ + @@ -66,7 +66,6 @@ - @@ -74,6 +73,7 @@ + diff --git a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters index 3564c5bc3..568da679b 100644 --- a/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters +++ b/Source/Project64-rsp-core/Project64-rsp-core.vcxproj.filters @@ -90,15 +90,15 @@ Source Files\Recompiler - - Source Files\cpu - Source Files\cpu Source Files\cpu + + Source Files\cpu + @@ -152,14 +152,14 @@ Header Files\Recompiler - - Header Files\cpu - Header Files\cpu Header Files\cpu + + Header Files\cpu + \ No newline at end of file diff --git a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp index 09e36baa4..4d149061d 100644 --- a/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp +++ b/Source/Project64-rsp-core/Recompiler/RspRecompilerOps.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -2102,7 +2101,7 @@ void Compile_Cop0_MF(void) } else { - CompilerWarning("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); BreakPoint(); } return; @@ -2110,11 +2109,15 @@ void Compile_Cop0_MF(void) switch (RSPOpC.rd) { case 0: - MoveVariableToX86reg(RSPInfo.SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG", x86_EAX); + MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX); + PushImm32("RSPRegister_MEM_ADDR", RSPRegister_MEM_ADDR); + Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg"); 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); + MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX); + PushImm32("RSPRegister_DRAM_ADDR", RSPRegister_DRAM_ADDR); + Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg"); MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); break; case 5: @@ -2126,32 +2129,10 @@ void Compile_Cop0_MF(void) MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); break; case 4: - MoveVariableToX86reg(&RSP_MfStatusCount, "RSP_MfStatusCount", x86_ECX); - MoveVariableToX86reg(RSPInfo.SP_STATUS_REG, "SP_STATUS_REG", x86_EAX); - if (Mfc0Count != 0) - { - CompConstToX86reg(x86_ECX, Mfc0Count); - JbLabel8("label", 10); - MoveConstToVariable(0, &RSP_Running, "RSP_Running"); - } - IncX86reg(x86_ECX); + MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX); + PushImm32("RSPRegister_STATUS", RSPRegister_STATUS); + Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::ReadReg), "RSPRegisterHandlerPlugin::ReadReg"); MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt)); - MoveX86regToVariable(x86_ECX, &RSP_MfStatusCount, "RSP_MfStatusCount"); - if (NextInstruction == RSPPIPELINE_NORMAL) - { - MoveConstToVariable(CompilePC + 4, PrgCount, "RSP PC"); - Ret(); - NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK; - } - else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) - { - NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; - } - else - { - CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); - BreakPoint(); - } break; case 7: if (AudioHle || GraphicsHle || SemaphoreExit == 0) @@ -2242,7 +2223,7 @@ void Compile_Cop0_MT(void) } else { - CompilerWarning("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction); + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); BreakPoint(); } } @@ -2250,22 +2231,54 @@ void Compile_Cop0_MT(void) switch (RSPOpC.rd) { case 0: + MoveConstToX86reg((uint32_t)(g_RSPRegisterHandler.get()), x86_ECX); MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX); - MoveX86regToVariable(x86_EAX, RSPInfo.SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); + 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); MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX); - MoveX86regToVariable(x86_EAX, RSPInfo.SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); + 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); MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX); - MoveX86regToVariable(x86_EAX, RSPInfo.SP_RD_LEN_REG, "SP_RD_LEN_REG"); - Call_Direct(SP_DMA_READ, "SP_DMA_READ"); + 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); MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX); - MoveX86regToVariable(x86_EAX, RSPInfo.SP_WR_LEN_REG, "SP_WR_LEN_REG"); - Call_Direct(SP_DMA_WRITE, "SP_DMA_WRITE"); + 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); + MoveVariableToX86reg(&RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt), x86_EAX); + Push(x86_EAX); + PushImm32("RSPRegister_STATUS", RSPRegister_STATUS); + Call_Direct(AddressOf(&RSPRegisterHandlerPlugin::WriteReg), "RSPRegisterHandlerPlugin::WriteReg"); + if (NextInstruction == RSPPIPELINE_NORMAL) + { + MoveConstToVariable(CompilePC + 4, PrgCount, "RSP PC"); + Ret(); + NextInstruction = RSPPIPELINE_FINISH_BLOCK; + } + else if (NextInstruction == RSPPIPELINE_DELAY_SLOT) + { + NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT; + } + else + { + CompilerWarning(stdstr_f("MF error\nWeird Delay Slot.\n\nNextInstruction = %X\nEmulation will now stop", NextInstruction).c_str()); + BreakPoint(); + } break; case 7: MoveConstToVariable(0, RSPInfo.SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG"); diff --git a/Source/Project64-rsp-core/Recompiler/X86.cpp b/Source/Project64-rsp-core/Recompiler/X86.cpp index ce67ee8cf..5cf821b78 100644 --- a/Source/Project64-rsp-core/Recompiler/X86.cpp +++ b/Source/Project64-rsp-core/Recompiler/X86.cpp @@ -3320,3 +3320,15 @@ void XorX86RegToVariable(void * Variable, char * VariableName, int x86reg) } PUTDSTPTR(RecompPos, Variable); } + +void * GetAddressOf_(int value, ...) +{ + void * Address; + + va_list ap; + va_start(ap, value); + Address = va_arg(ap, void *); + va_end(ap); + + return Address; +} diff --git a/Source/Project64-rsp-core/Recompiler/X86.h b/Source/Project64-rsp-core/Recompiler/X86.h index e50b99331..f2e585b94 100644 --- a/Source/Project64-rsp-core/Recompiler/X86.h +++ b/Source/Project64-rsp-core/Recompiler/X86.h @@ -268,3 +268,6 @@ void SseShuffleReg(int Dest, int Source, uint8_t Immed); void x86_SetBranch32b(void * Jumpuint8_t, void * Destination); void x86_SetBranch8b(void * Jumpuint8_t, void * Destination); + +void * GetAddressOf_(int32_t value, ...); +#define AddressOf(Addr) GetAddressOf_(5, (Addr)) diff --git a/Source/Project64-rsp-core/cpu/RSPCpu.cpp b/Source/Project64-rsp-core/cpu/RSPCpu.cpp index edc8373ff..636bffb59 100644 --- a/Source/Project64-rsp-core/cpu/RSPCpu.cpp +++ b/Source/Project64-rsp-core/cpu/RSPCpu.cpp @@ -4,6 +4,9 @@ #include #include #include +#include + +class RSPRegisterHandler; UDWORD EleSpec[16], Indx[16]; RSPOpcode RSPOpC; @@ -24,6 +27,7 @@ void BuildRecompilerCPU(void); CriticalSection g_CPUCriticalSection; uint32_t Mfc0Count, SemaphoreExit = 0; RSPCpuType g_CPUCore = InterpreterCPU; +std::unique_ptr g_RSPRegisterHandler; void SetCPU(RSPCpuType core) { diff --git a/Source/Project64-rsp-core/cpu/RSPCpu.h b/Source/Project64-rsp-core/cpu/RSPCpu.h index 2e947e67a..db901c289 100644 --- a/Source/Project64-rsp-core/cpu/RSPCpu.h +++ b/Source/Project64-rsp-core/cpu/RSPCpu.h @@ -1,5 +1,7 @@ #include "RSPOpcode.h" +#include "RSPRegisterHandlerPlugin.h" #include "RspTypes.h" +#include enum RSPCpuType { @@ -26,4 +28,5 @@ void SetCPU(RSPCpuType core); void Build_RSP(void); extern uint32_t Mfc0Count, SemaphoreExit; -extern RSPCpuType g_CPUCore; \ No newline at end of file +extern RSPCpuType g_CPUCore; +extern std::unique_ptr g_RSPRegisterHandler; diff --git a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp index 053f5f64a..7b0b3b113 100644 --- a/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp +++ b/Source/Project64-rsp-core/cpu/RSPInterpreterOps.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -376,11 +375,13 @@ void RSP_Cop0_MF(void) g_RSPDebugger->RDP_LogMF0(*PrgCount, RSPOpC.rd); switch (RSPOpC.rd) { - case 0: RSP_GPR[RSPOpC.rt].UW = *RSPInfo.SP_MEM_ADDR_REG; break; - case 1: RSP_GPR[RSPOpC.rt].UW = *RSPInfo.SP_DRAM_ADDR_REG; break; + case 0: RSP_GPR[RSPOpC.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_MEM_ADDR); break; + case 1: RSP_GPR[RSPOpC.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_DRAM_ADDR); break; + case 2: RSP_GPR[RSPOpC.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_RD_LEN); break; + case 3: RSP_GPR[RSPOpC.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_WR_LEN); break; case 4: RSP_MfStatusCount += 1; - RSP_GPR[RSPOpC.rt].UW = *RSPInfo.SP_STATUS_REG; + RSP_GPR[RSPOpC.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_STATUS); if (Mfc0Count != 0 && RSP_MfStatusCount > Mfc0Count) { RSP_Running = false; @@ -389,16 +390,8 @@ void RSP_Cop0_MF(void) case 5: RSP_GPR[RSPOpC.rt].UW = *RSPInfo.SP_DMA_FULL_REG; break; case 6: RSP_GPR[RSPOpC.rt].UW = *RSPInfo.SP_DMA_BUSY_REG; break; case 7: - if (AudioHle || GraphicsHle || SemaphoreExit == 0) - { - RSP_GPR[RSPOpC.rt].W = 0; - } - else - { - RSP_GPR[RSPOpC.rt].W = *RSPInfo.SP_SEMAPHORE_REG; - *RSPInfo.SP_SEMAPHORE_REG = 1; - RSP_Running = false; - } + RSP_GPR[RSPOpC.rt].W = *RSPInfo.SP_SEMAPHORE_REG; + *RSPInfo.SP_SEMAPHORE_REG = 1; break; case 8: RSP_GPR[RSPOpC.rt].UW = *RSPInfo.DPC_START_REG; break; case 9: RSP_GPR[RSPOpC.rt].UW = *RSPInfo.DPC_END_REG; break; @@ -418,121 +411,11 @@ void RSP_Cop0_MT(void) } switch (RSPOpC.rd) { - case 0: *RSPInfo.SP_MEM_ADDR_REG = RSP_GPR[RSPOpC.rt].UW; break; - case 1: *RSPInfo.SP_DRAM_ADDR_REG = RSP_GPR[RSPOpC.rt].UW; break; - case 2: - *RSPInfo.SP_RD_LEN_REG = RSP_GPR[RSPOpC.rt].UW; - SP_DMA_READ(); - break; - case 3: - *RSPInfo.SP_WR_LEN_REG = RSP_GPR[RSPOpC.rt].UW; - SP_DMA_WRITE(); - break; - case 4: - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_HALT) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_HALT; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_HALT) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_HALT; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_BROKE) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_BROKE; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_INTR) != 0) - { - *RSPInfo.MI_INTR_REG &= ~MI_INTR_SP; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_INTR) != 0) - { - *RSPInfo.MI_INTR_REG |= MI_INTR_SP; - RSPInfo.CheckInterrupts(); - RSP_Running = false; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SSTEP) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SSTEP; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SSTEP) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SSTEP; - RSP_NextInstruction = RSPPIPELINE_SINGLE_STEP; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_INTR_BREAK) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_INTR_BREAK) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_INTR_BREAK; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG0) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG0; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG0) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG0; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG1) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG1; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG1) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG1; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG2) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG2; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG2) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG2; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG3) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG3; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG3) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG3; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG4) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG4; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG4) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG4; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG5) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG5; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG5) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG5; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG6) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG6; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG6) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG6; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_CLR_SIG7) != 0) - { - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG7; - } - if ((RSP_GPR[RSPOpC.rt].W & SP_SET_SIG7) != 0) - { - *RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG7; - } - break; + case 0: g_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, RSP_GPR[RSPOpC.rt].UW); break; + case 1: g_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, RSP_GPR[RSPOpC.rt].UW); break; + case 2: g_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, RSP_GPR[RSPOpC.rt].UW); break; + case 3: g_RSPRegisterHandler->WriteReg(RSPRegister_WR_LEN, RSP_GPR[RSPOpC.rt].UW); break; + case 4: g_RSPRegisterHandler->WriteReg(RSPRegister_STATUS, RSP_GPR[RSPOpC.rt].UW); break; case 7: *RSPInfo.SP_SEMAPHORE_REG = 0; break; case 8: *RSPInfo.DPC_START_REG = RSP_GPR[RSPOpC.rt].UW; diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp index 0808adf1c..c59ab84dc 100644 --- a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp +++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.cpp @@ -19,8 +19,26 @@ RSPRegisterHandler::RSPRegisterHandler(uint32_t * SignalProcessorInterface, uint m_IMEM(IMEM), m_DMEM(DMEM), m_PendingSPMemAddr(0), - m_PendingSPDramAddr(0), - m_ExecutedDMARead(false) + m_PendingSPDramAddr(0) +{ +} + +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(*RSPInfo.SP_RD_LEN_REG), + SP_WR_LEN_REG(*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), + m_PendingSPMemAddr(0), + m_PendingSPDramAddr(0) { } @@ -109,11 +127,11 @@ void RSPRegisterHandler::SP_DMA_READ() SP_DMA_BUSY_REG = 0; SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; - m_ExecutedDMARead = true; SP_MEM_ADDR_REG = (Pos & 0xFFF) | (m_PendingSPMemAddr & 0x1000); SP_DRAM_ADDR_REG = ReadPos; SP_RD_LEN_REG = (SP_RD_LEN_REG & 0xFF800000) | 0x00000FF8; SP_WR_LEN_REG = (SP_RD_LEN_REG & 0xFF800000) | 0x00000FF8; + DmaReadDone(Pos); } void RSPRegisterHandler::SP_DMA_WRITE() @@ -181,7 +199,6 @@ void RSPRegisterHandler::SP_DMA_WRITE() SP_DMA_BUSY_REG = 0; SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; - m_ExecutedDMARead = true; SP_MEM_ADDR_REG = (Pos & 0xFFF) | (m_PendingSPMemAddr & 0x1000); SP_DRAM_ADDR_REG = WritePos; SP_RD_LEN_REG = (SP_WR_LEN_REG & 0xFF800000) | 0x00000FF8; diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h index ac85b22c8..59c9f7e33 100644 --- a/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h +++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandler.h @@ -18,6 +18,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); void SP_DMA_READ(void); void SP_DMA_WRITE(void); @@ -29,6 +30,7 @@ protected: virtual void ClearSPInterrupt(void) = 0; virtual void SetSPInterrupt(void) = 0; virtual void SetHalt(void) = 0; + virtual void DmaReadDone(uint32_t End) = 0; uint32_t & SP_MEM_ADDR_REG; uint32_t & SP_DRAM_ADDR_REG; @@ -45,5 +47,4 @@ protected: uint8_t * m_DMEM; uint32_t m_PendingSPMemAddr; uint32_t m_PendingSPDramAddr; - bool m_ExecutedDMARead; }; diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp new file mode 100644 index 000000000..1a3433559 --- /dev/null +++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.cpp @@ -0,0 +1,45 @@ +#include "RSPRegisterHandlerPlugin.h" +#include "RSPCpu.h" +#include "RSPRegisters.h" +#include +#include + +RSPRegisterHandlerPlugin::RSPRegisterHandlerPlugin(_RSP_INFO & Info, const uint32_t & Size) : + RSPRegisterHandler(Info, Size) +{ +} + +uint32_t & RSPRegisterHandlerPlugin::PendingSPMemAddr() +{ + return m_PendingSPMemAddr; +} + +uint32_t & RSPRegisterHandlerPlugin::PendingSPDramAddr() +{ + return m_PendingSPDramAddr; +} + +void RSPRegisterHandlerPlugin::ClearSPInterrupt(void) +{ + *RSPInfo.MI_INTR_REG &= ~MI_INTR_SP; +} + +void RSPRegisterHandlerPlugin::SetSPInterrupt(void) +{ + *RSPInfo.MI_INTR_REG |= MI_INTR_SP; + RSPInfo.CheckInterrupts(); + RSP_Running = false; +} + +void RSPRegisterHandlerPlugin::SetHalt(void) +{ + RSP_Running = false; +} + +void RSPRegisterHandlerPlugin::DmaReadDone(uint32_t End) +{ + if (g_CPUCore == RecompilerCPU && (*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0) + { + SetJumpTable(End); + } +} diff --git a/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h new file mode 100644 index 000000000..54cbccec8 --- /dev/null +++ b/Source/Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h @@ -0,0 +1,18 @@ +#pragma once +#include "RSPRegisterHandler.h" + +class RSPRegisterHandlerPlugin : + public RSPRegisterHandler +{ +public: + RSPRegisterHandlerPlugin(_RSP_INFO & RSPInfo, const uint32_t & RdramSize); + + uint32_t & PendingSPMemAddr(); + uint32_t & PendingSPDramAddr(); + +private: + void ClearSPInterrupt(void); + void SetSPInterrupt(void); + void SetHalt(void); + void DmaReadDone(uint32_t End); +}; diff --git a/Source/Project64-rsp-core/cpu/RspDma.cpp b/Source/Project64-rsp-core/cpu/RspDma.cpp deleted file mode 100644 index 3ad4c943f..000000000 --- a/Source/Project64-rsp-core/cpu/RspDma.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include - -#include "RSPCpu.h" -#include "RSPRegisters.h" -#include "RspMemory.h" -#include -#include - -// #define RSP_SAFE_DMA // Unoptimized DMA transfers - -void SP_DMA_READ(void) -{ - uint32_t i, j, Length, Skip, Count, End, addr; - uint8_t *Dest, *Source; - - addr = (*RSPInfo.SP_DRAM_ADDR_REG) & 0x00FFFFFF; - - if (addr > 0x7FFFFF) - { - g_Notify->DisplayError("SP DMA READ\nSP_DRAM_ADDR_REG not in RDRAM space"); - return; - } - - if ((*RSPInfo.SP_RD_LEN_REG & 0xFFF) + 1 + (*RSPInfo.SP_MEM_ADDR_REG & 0xFFF) > 0x1000) - { - g_Notify->DisplayError("SP DMA READ\nCould not fit copy in memory segment"); - return; - } - - Length = ((*RSPInfo.SP_RD_LEN_REG & 0xFFF) | 7) + 1; - Skip = (*RSPInfo.SP_RD_LEN_REG >> 20) + Length; - Count = ((*RSPInfo.SP_RD_LEN_REG >> 12) & 0xFF) + 1; - End = ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7) + (((Count - 1) * Skip) + Length); - Dest = ((*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0 ? RSPInfo.IMEM : RSPInfo.DMEM) + ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7); - Source = RSPInfo.RDRAM + (addr & ~7); - -#if defined(RSP_SAFE_DMA) - for (j = 0; j < Count; j++) - { - for (i = 0; i < Length; i++) - { - *(uint8_t *)(((size_t)Dest + j * Length + i) ^ 3) = *(uint8_t *)(((size_t)Source + j * Skip + i) ^ 3); - } - } -#else - if ((Skip & 0x3) == 0) - { - for (j = 0; j < Count; j++) - { - memcpy(Dest, Source, Length); - Source += Skip; - Dest += Length; - } - } - else - { - for (j = 0; j < Count; j++) - { - for (i = 0; i < Length; i++) - { - *(uint8_t *)(((size_t)Dest + i) ^ 3) = *(uint8_t *)(((size_t)Source + i) ^ 3); - } - Source += Skip; - Dest += Length; - } - } -#endif - - // TODO: Could this be a problem DMEM to IMEM? - if (g_CPUCore == RecompilerCPU && (*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0) - { - SetJumpTable(End); - } - - *RSPInfo.SP_DMA_BUSY_REG = 0; - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; -} - -void SP_DMA_WRITE(void) -{ - uint32_t i, j, Length, Skip, Count, addr; - uint8_t *Dest, *Source; - - addr = (*RSPInfo.SP_DRAM_ADDR_REG) & 0x00FFFFFF; - - if (addr > 0x7FFFFF) - { - g_Notify->DisplayError("SP DMA WRITE\nSP_DRAM_ADDR_REG not in RDRAM space"); - return; - } - - if ((*RSPInfo.SP_WR_LEN_REG & 0xFFF) + 1 + (*RSPInfo.SP_MEM_ADDR_REG & 0xFFF) > 0x1000) - { - g_Notify->DisplayError("SP DMA WRITE\nCould not fit copy in memory segment"); - return; - } - - Length = ((*RSPInfo.SP_WR_LEN_REG & 0xFFF) | 7) + 1; - Skip = (*RSPInfo.SP_WR_LEN_REG >> 20) + Length; - Count = ((*RSPInfo.SP_WR_LEN_REG >> 12) & 0xFF) + 1; - Dest = RSPInfo.RDRAM + (addr & ~7); - Source = ((*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0 ? RSPInfo.IMEM : RSPInfo.DMEM) + ((*RSPInfo.SP_MEM_ADDR_REG & 0xFFF) & ~7); - -#if defined(RSP_SAFE_DMA) - for (j = 0; j < Count; j++) - { - for (i = 0; i < Length; i++) - { - *(uint8_t *)(((size_t)Dest + j * Skip + i) ^ 3) = *(uint8_t *)(((size_t)Source + j * Length + i) ^ 3); - } - } -#else - if ((Skip & 0x3) == 0) - { - for (j = 0; j < Count; j++) - { - memcpy(Dest, Source, Length); - Source += Length; - Dest += Skip; - } - } - else - { - for (j = 0; j < Count; j++) - { - for (i = 0; i < Length; i++) - { - *(uint8_t *)(((size_t)Dest + i) ^ 3) = *(uint8_t *)(((size_t)Source + i) ^ 3); - } - Source += Length; - Dest += Skip; - } - } -#endif - *RSPInfo.SP_DMA_BUSY_REG = 0; - *RSPInfo.SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; -} diff --git a/Source/Project64-rsp-core/cpu/RspDma.h b/Source/Project64-rsp-core/cpu/RspDma.h deleted file mode 100644 index be1c33f1d..000000000 --- a/Source/Project64-rsp-core/cpu/RspDma.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -void SP_DMA_READ(void); -void SP_DMA_WRITE(void); diff --git a/Source/Project64-rsp-core/cpu/RspMemory.cpp b/Source/Project64-rsp-core/cpu/RspMemory.cpp index 4f0020d52..dbdb05d9f 100644 --- a/Source/Project64-rsp-core/cpu/RspMemory.cpp +++ b/Source/Project64-rsp-core/cpu/RspMemory.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -85,7 +86,7 @@ void SetJumpTable(uint32_t End) End = 0x800; } - if (End == 0x1000 && ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7) == 0x80) + if (End == 0x1000 && ((g_RSPRegisterHandler->PendingSPMemAddr() & 0x0FFF) & ~7) == 0x80) { End = 0x800; } diff --git a/Source/Project64-rsp/Main.cpp b/Source/Project64-rsp/Main.cpp index 10e356cbb..b708c2630 100644 --- a/Source/Project64-rsp/Main.cpp +++ b/Source/Project64-rsp/Main.cpp @@ -491,6 +491,7 @@ EXPORT void RomOpen(void) { RdramSize = 0x00400000; } + g_RSPRegisterHandler.reset(new RSPRegisterHandlerPlugin(RSPInfo, RdramSize)); } /* @@ -507,6 +508,7 @@ EXPORT void RomClosed(void) StopTimer(); GenerateTimerResults(); } + g_RSPRegisterHandler.reset(nullptr); ClearAllx86Code(); StopRDPLog(); StopCPULog();