Rsp: Use RSP Register Handler
This commit is contained in:
parent
bd1ec4ff0f
commit
ac3e0f83d1
|
@ -172,6 +172,10 @@ void SPRegistersHandler::SetHalt(void)
|
|||
{
|
||||
}
|
||||
|
||||
void SPRegistersHandler::DmaReadDone(uint32_t /*End*/)
|
||||
{
|
||||
}
|
||||
|
||||
void SPRegistersHandler::SystemReset(void)
|
||||
{
|
||||
SP_RD_LEN_REG = 0x00000FF8;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
void SP_DMA_READ(void);
|
||||
void SP_DMA_WRITE(void);
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue