Rsp: Use RSP Register Handler

This commit is contained in:
zilmar 2023-09-28 11:52:06 +09:30
parent bd1ec4ff0f
commit ac3e0f83d1
19 changed files with 188 additions and 324 deletions

View File

@ -172,6 +172,10 @@ void SPRegistersHandler::SetHalt(void)
{
}
void SPRegistersHandler::DmaReadDone(uint32_t /*End*/)
{
}
void SPRegistersHandler::SystemReset(void)
{
SP_RD_LEN_REG = 0x00000FF8;

View File

@ -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];

View File

@ -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

View File

@ -42,7 +42,6 @@
<ItemGroup>
<ClCompile Include="cpu\RspClamp.cpp" />
<ClCompile Include="cpu\RSPCpu.cpp" />
<ClCompile Include="cpu\RspDma.cpp" />
<ClCompile Include="cpu\RSPiInstruction.cpp" />
<ClCompile Include="cpu\RSPInterpreterCPU.cpp" />
<ClCompile Include="cpu\RSPInterpreterOps.cpp" />
@ -50,6 +49,7 @@
<ClCompile Include="cpu\RspMemory.cpp" />
<ClCompile Include="cpu\RSPRegister.cpp" />
<ClCompile Include="cpu\RSPRegisterHandler.cpp" />
<ClCompile Include="cpu\RSPRegisterHandlerPlugin.cpp" />
<ClCompile Include="cpu\RspTypes.cpp" />
<ClCompile Include="Recompiler\Mmx.cpp" />
<ClCompile Include="Recompiler\RspProfiling.cpp" />
@ -66,7 +66,6 @@
<ItemGroup>
<ClInclude Include="cpu\RspClamp.h" />
<ClInclude Include="cpu\RSPCpu.h" />
<ClInclude Include="cpu\RspDma.h" />
<ClInclude Include="cpu\RSPInstruction.h" />
<ClInclude Include="cpu\RSPInterpreterCPU.h" />
<ClInclude Include="cpu\RSPInterpreterOps.h" />
@ -74,6 +73,7 @@
<ClInclude Include="cpu\RspMemory.h" />
<ClInclude Include="cpu\RSPOpcode.h" />
<ClInclude Include="cpu\RSPRegisterHandler.h" />
<ClInclude Include="cpu\RSPRegisterHandlerPlugin.h" />
<ClInclude Include="cpu\RSPRegisters.h" />
<ClInclude Include="cpu\RspTypes.h" />
<ClInclude Include="Recompiler\RspProfiling.h" />

View File

@ -90,15 +90,15 @@
<ClCompile Include="Recompiler\RspProfiling.cpp">
<Filter>Source Files\Recompiler</Filter>
</ClCompile>
<ClCompile Include="cpu\RspDma.cpp">
<Filter>Source Files\cpu</Filter>
</ClCompile>
<ClCompile Include="cpu\RspClamp.cpp">
<Filter>Source Files\cpu</Filter>
</ClCompile>
<ClCompile Include="cpu\RSPRegisterHandler.cpp">
<Filter>Source Files\cpu</Filter>
</ClCompile>
<ClCompile Include="cpu\RSPRegisterHandlerPlugin.cpp">
<Filter>Source Files\cpu</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cpu\RSPInstruction.h">
@ -152,14 +152,14 @@
<ClInclude Include="Recompiler\RspProfiling.h">
<Filter>Header Files\Recompiler</Filter>
</ClInclude>
<ClInclude Include="cpu\RspDma.h">
<Filter>Header Files\cpu</Filter>
</ClInclude>
<ClInclude Include="cpu\RspClamp.h">
<Filter>Header Files\cpu</Filter>
</ClInclude>
<ClInclude Include="cpu\RSPRegisterHandler.h">
<Filter>Header Files\cpu</Filter>
</ClInclude>
<ClInclude Include="cpu\RSPRegisterHandlerPlugin.h">
<Filter>Header Files\cpu</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -9,7 +9,6 @@
#include <Project64-rsp-core/cpu/RSPInterpreterCPU.h>
#include <Project64-rsp-core/cpu/RSPInterpreterOps.h>
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <Project64-rsp-core/cpu/RspDma.h>
#include <Project64-rsp-core/cpu/RspLog.h>
#include <Project64-rsp-core/cpu/RspMemory.h>
#include <Project64-rsp-core/cpu/RspTypes.h>
@ -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");

View File

@ -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;
}

View File

@ -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))

View File

@ -4,6 +4,9 @@
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/Settings/RspSettings.h>
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <memory>
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<RSPRegisterHandlerPlugin> g_RSPRegisterHandler;
void SetCPU(RSPCpuType core)
{

View File

@ -1,5 +1,7 @@
#include "RSPOpcode.h"
#include "RSPRegisterHandlerPlugin.h"
#include "RspTypes.h"
#include <memory>
enum RSPCpuType
{
@ -27,3 +29,4 @@ void Build_RSP(void);
extern uint32_t Mfc0Count, SemaphoreExit;
extern RSPCpuType g_CPUCore;
extern std::unique_ptr<RSPRegisterHandlerPlugin> g_RSPRegisterHandler;

View File

@ -7,7 +7,6 @@
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/Settings/RspSettings.h>
#include <Project64-rsp-core/cpu/RspClamp.h>
#include <Project64-rsp-core/cpu/RspDma.h>
#include <Settings/Settings.h>
#include <algorithm>
#include <float.h>
@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -0,0 +1,45 @@
#include "RSPRegisterHandlerPlugin.h"
#include "RSPCpu.h"
#include "RSPRegisters.h"
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/cpu/RspMemory.h>
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);
}
}

View File

@ -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);
};

View File

@ -1,139 +0,0 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "RSPCpu.h"
#include "RSPRegisters.h"
#include "RspMemory.h"
#include <Project64-rsp-core/RSPInfo.h>
#include <Settings/Settings.h>
// #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;
}

View File

@ -1,4 +0,0 @@
#pragma once
void SP_DMA_READ(void);
void SP_DMA_WRITE(void);

View File

@ -1,5 +1,6 @@
#include <Common/MemoryManagement.h>
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/cpu/RSPCpu.h>
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <Settings/Settings.h>
#include <stdio.h>
@ -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;
}

View File

@ -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();