RSP: Be able to compile sections based off tasks
This commit is contained in:
parent
3340c032c3
commit
c098a6a464
|
@ -1,15 +1,25 @@
|
||||||
#include <Project64-rsp-core/Hle/HleTask.h>
|
#include <Project64-rsp-core/Hle/HleTask.h>
|
||||||
|
#include <Project64-rsp-core/cpu/RSPRegisterHandlerPlugin.h>
|
||||||
|
#include <Project64-rsp-core/cpu/RspMemory.h>
|
||||||
#include <Project64-rsp-core/cpu/RspSystem.h>
|
#include <Project64-rsp-core/cpu/RspSystem.h>
|
||||||
#include <zlib/zlib.h>
|
#include <zlib/zlib.h>
|
||||||
|
|
||||||
CHleTask::CHleTask(CRSPSystem & System) :
|
CHleTask::CHleTask(CRSPSystem & System) :
|
||||||
|
CGPRRegisters(System.m_Reg.m_GPR),
|
||||||
m_hle(System),
|
m_hle(System),
|
||||||
m_System(System),
|
m_System(System),
|
||||||
|
m_Recompiler(System.m_Recompiler),
|
||||||
|
m_RSPRegisterHandler(System.m_RSPRegisterHandler),
|
||||||
|
m_MI_INTR_REG(System.m_MI_INTR_REG),
|
||||||
m_SP_STATUS_REG(System.m_SP_STATUS_REG),
|
m_SP_STATUS_REG(System.m_SP_STATUS_REG),
|
||||||
|
m_SP_DMA_FULL_REG(System.m_SP_DMA_FULL_REG),
|
||||||
|
m_SP_DMA_BUSY_REG(System.m_SP_DMA_BUSY_REG),
|
||||||
m_SP_PC_REG(System.m_SP_PC_REG),
|
m_SP_PC_REG(System.m_SP_PC_REG),
|
||||||
|
m_SP_SEMAPHORE_REG(System.m_SP_SEMAPHORE_REG),
|
||||||
m_DPC_STATUS_REG(System.m_DPC_STATUS_REG),
|
m_DPC_STATUS_REG(System.m_DPC_STATUS_REG),
|
||||||
m_DMEM(System.m_DMEM),
|
m_DMEM(System.m_DMEM),
|
||||||
m_IMEM(System.m_IMEM),
|
m_IMEM(System.m_IMEM),
|
||||||
|
m_UcodeCRC(0),
|
||||||
CheckInterrupts(System.CheckInterrupts),
|
CheckInterrupts(System.CheckInterrupts),
|
||||||
ProcessDList(System.ProcessDList)
|
ProcessDList(System.ProcessDList)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +40,200 @@ bool CHleTask::IsHleTask(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHleTask::SetupCommandList(TASK_INFO & TaskInfo)
|
||||||
|
{
|
||||||
|
uint32_t JumpTableLength = 0x7E, JumpTablePos = 0x10;
|
||||||
|
if ((HLETaskType)(TaskInfo.Type) == HLETaskType::Audio)
|
||||||
|
{
|
||||||
|
if (*((uint32_t *)&m_DMEM[0]) == 0x00000001 && *((uint32_t *)&m_DMEM[0x30]) == 0xf0000f00)
|
||||||
|
{
|
||||||
|
JumpTableLength = 0x10;
|
||||||
|
JumpTablePos = 0x10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t JumpTableCRC = crc32(0L, m_IMEM + JumpTablePos, JumpTableLength << 1);
|
||||||
|
TaskFunctionMap::iterator itr = m_FunctionMap.find(JumpTableCRC);
|
||||||
|
if (itr != m_FunctionMap.end())
|
||||||
|
{
|
||||||
|
m_TaskFunctions = &itr->second;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_FunctionMap.size() > 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
m_TaskFunctions = nullptr;
|
||||||
|
|
||||||
|
memset(&m_Recompiler.m_CurrentBlock, 0, sizeof(m_Recompiler.m_CurrentBlock));
|
||||||
|
m_Recompiler.BuildBranchLabels();
|
||||||
|
TaskFunctions JumpFunctions;
|
||||||
|
for (uint32_t i = 0, n = JumpTableLength; i < n; i++)
|
||||||
|
{
|
||||||
|
uint16_t FuncAddress = *((uint16_t *)(m_DMEM + (((i << 1) + JumpTablePos) ^ 2)));
|
||||||
|
if (FuncAddress != 0x1118)
|
||||||
|
{
|
||||||
|
m_Recompiler.CompileHLETask(FuncAddress);
|
||||||
|
void * FuncPtr = *(JumpTable + ((FuncAddress & 0xFFF) >> 2));
|
||||||
|
JumpFunctions.emplace_back(TaskFunctionAddress(FuncAddress, FuncPtr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JumpFunctions.emplace_back(TaskFunctionAddress(FuncAddress, nullptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_Recompiler.LinkBranches(&m_Recompiler.m_CurrentBlock);
|
||||||
|
m_FunctionMap[JumpTableCRC] = JumpFunctions;
|
||||||
|
itr = m_FunctionMap.find(JumpTableCRC);
|
||||||
|
if (itr == m_FunctionMap.end())
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_TaskFunctions = &itr->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHleTask::ExecuteTask_1a13a51a(TASK_INFO & TaskInfo)
|
||||||
|
{
|
||||||
|
*((uint32_t *)(m_DMEM + 0x320)) = 0;
|
||||||
|
GPR_T8 = 0x360;
|
||||||
|
GPR_S7 = 0xF90;
|
||||||
|
if ((*m_DPC_STATUS_REG & 1) != 0 || *m_SP_SEMAPHORE_REG != 0 || *m_SP_DMA_FULL_REG != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, 0x380);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, TaskInfo.DataPtr);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, 0x13F);
|
||||||
|
if (*m_SP_DMA_BUSY_REG != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*m_SP_SEMAPHORE_REG = 0;
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
*m_SP_PC_REG = 0x0E4;
|
||||||
|
RSPSystem.SyncSystem()->ExecuteOps(200, *m_SP_PC_REG);
|
||||||
|
RSPSystem.BasicSyncCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
GPR_GP = TaskInfo.DataPtr;
|
||||||
|
GPR_K1 = TaskInfo.DataSize;
|
||||||
|
GPR_SP = 0x380;
|
||||||
|
GPR_S8 = 0x140;
|
||||||
|
static uint32_t TaskCount = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
GPR_K0 = *((uint32_t *)(m_DMEM + GPR_SP));
|
||||||
|
GPR_T9 = *((uint32_t *)(m_DMEM + GPR_SP + 4));
|
||||||
|
|
||||||
|
uint32_t Index = (GPR_K0 >> 0x18) & 0x7F;
|
||||||
|
GPR_GP += 8;
|
||||||
|
GPR_K1 -= 8;
|
||||||
|
GPR_SP += 8;
|
||||||
|
GPR_S8 -= 8;
|
||||||
|
if (Index >= m_TaskFunctions->size())
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
TaskFunctionAddress FunctionAddress = (*m_TaskFunctions)[Index];
|
||||||
|
*m_SP_PC_REG = FunctionAddress.first;
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
RSPSystem.SyncSystem()->ExecuteOps(0x10000, 0x118);
|
||||||
|
}
|
||||||
|
#if defined(_M_IX86) && defined(_MSC_VER)
|
||||||
|
void * Block = FunctionAddress.second;
|
||||||
|
_asm {
|
||||||
|
pushad
|
||||||
|
call Block
|
||||||
|
popad
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
#endif
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
RSPSystem.BasicSyncCheck();
|
||||||
|
RSPSystem.SyncSystem()->ExecuteOps(2, (uint32_t)-1);
|
||||||
|
}
|
||||||
|
if (GPR_S8 == 0)
|
||||||
|
{
|
||||||
|
if (GPR_K1 <= 0)
|
||||||
|
{
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_STATUS, 0x4000);
|
||||||
|
RSPSystem.m_Op.Special_BREAK();
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
*m_SP_PC_REG = 0x144;
|
||||||
|
RSPSystem.SyncSystem()->ExecuteOps(100, 0x144);
|
||||||
|
RSPSystem.BasicSyncCheck();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint32_t ReadLen = (GPR_K1 > 0x140) ? 0x140 : GPR_K1;
|
||||||
|
GPR_S8 = ReadLen;
|
||||||
|
if (*m_SP_SEMAPHORE_REG != 0 || *m_SP_DMA_FULL_REG != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, 0x380);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, GPR_GP);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, ReadLen - 1);
|
||||||
|
GPR_SP = 0x380;
|
||||||
|
if (*m_SP_DMA_BUSY_REG != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
*m_SP_SEMAPHORE_REG = 0;
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
*m_SP_PC_REG = 0x0E4;
|
||||||
|
RSPSystem.SyncSystem()->ExecuteOps(400, 0x0E4);
|
||||||
|
RSPSystem.BasicSyncCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TaskCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHleTask::SetupTask(TASK_INFO & TaskInfo)
|
||||||
|
{
|
||||||
|
if (TaskInfo.Flags != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
if (*m_SP_DMA_FULL_REG != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, 0);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, TaskInfo.UcodeData);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, TaskInfo.UcodeDataSize);
|
||||||
|
if (*m_SP_DMA_BUSY_REG != 0 || (*m_SP_STATUS_REG & 0x80) != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_MEM_ADDR, 0x1080);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_DRAM_ADDR, TaskInfo.Ucode);
|
||||||
|
m_RSPRegisterHandler->WriteReg(RSPRegister_RD_LEN, 0x0F7F);
|
||||||
|
if (*m_SP_DMA_BUSY_REG != 0 || (*m_SP_STATUS_REG & 0x80) != 0)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
*m_SP_SEMAPHORE_REG = 0;
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
*m_SP_PC_REG = 0x80;
|
||||||
|
RSPSystem.SyncSystem()->ExecuteOps(200, 0x080);
|
||||||
|
RSPSystem.BasicSyncCheck();
|
||||||
|
}
|
||||||
|
SetupCommandList(TaskInfo);
|
||||||
|
}
|
||||||
|
|
||||||
bool CHleTask::ProcessHleTask(void)
|
bool CHleTask::ProcessHleTask(void)
|
||||||
{
|
{
|
||||||
TASK_INFO & TaskInfo = *((TASK_INFO *)(m_DMEM + 0xFC0));
|
TASK_INFO & TaskInfo = *((TASK_INFO *)(m_DMEM + 0xFC0));
|
||||||
|
@ -37,18 +241,18 @@ bool CHleTask::ProcessHleTask(void)
|
||||||
|
|
||||||
if (((HLETaskType)TaskInfo.Type) == HLETaskType::Video && GraphicsHle && TaskInfo.DataPtr != 0)
|
if (((HLETaskType)TaskInfo.Type) == HLETaskType::Video && GraphicsHle && TaskInfo.DataPtr != 0)
|
||||||
{
|
{
|
||||||
if (ProcessDList != nullptr)
|
if (ProcessDList == nullptr)
|
||||||
{
|
{
|
||||||
ProcessDList();
|
return false;
|
||||||
}
|
}
|
||||||
|
ProcessDList();
|
||||||
*m_SP_STATUS_REG |= (0x0203);
|
*m_SP_STATUS_REG |= (0x0203);
|
||||||
if ((*m_SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
|
if ((*m_SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
|
||||||
{
|
{
|
||||||
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
|
*m_MI_INTR_REG |= MI_INTR_SP;
|
||||||
RSPInfo.CheckInterrupts();
|
CheckInterrupts();
|
||||||
}
|
}
|
||||||
|
*m_DPC_STATUS_REG &= ~0x0002;
|
||||||
*RSPInfo.DPC_STATUS_REG &= ~0x0002;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (TaskInfo.Type == 7)
|
else if (TaskInfo.Type == 7)
|
||||||
|
@ -56,6 +260,30 @@ bool CHleTask::ProcessHleTask(void)
|
||||||
RSPInfo.ShowCFB();
|
RSPInfo.ShowCFB();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CRSPSettings::CPUMethod() == RSPCpuMethod::RecompilerTasks)
|
||||||
|
{
|
||||||
|
if (SyncCPU)
|
||||||
|
{
|
||||||
|
RSPSystem.SetupSyncCPU();
|
||||||
|
}
|
||||||
|
SetupTask(TaskInfo);
|
||||||
|
uint32_t UcodeSize = TaskInfo.UcodeSize;
|
||||||
|
if (UcodeSize < 0x4 || TaskInfo.UcodeSize > 0x0F80)
|
||||||
|
{
|
||||||
|
UcodeSize = 0x0F80;
|
||||||
|
}
|
||||||
|
m_UcodeCRC = crc32(0L, m_IMEM + 0x80, UcodeSize);
|
||||||
|
if (m_UcodeCRC == 0x1a13a51a)
|
||||||
|
{
|
||||||
|
ExecuteTask_1a13a51a(TaskInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (CRSPSettings::CPUMethod() == RSPCpuMethod::HighLevelEmulation && m_hle.try_fast_audio_dispatching())
|
if (CRSPSettings::CPUMethod() == RSPCpuMethod::HighLevelEmulation && m_hle.try_fast_audio_dispatching())
|
||||||
{
|
{
|
||||||
*m_SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
|
*m_SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
|
||||||
|
|
|
@ -1,14 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Project64-rsp-core/Hle/hle.h>
|
#include <Project64-rsp-core/Hle/hle.h>
|
||||||
|
#include <Project64-rsp-core/cpu/RSPRegisters.h>
|
||||||
#include <Project64-rsp-core/cpu/RspTypes.h>
|
#include <Project64-rsp-core/cpu/RspTypes.h>
|
||||||
|
#include <map>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class CRSPSystem;
|
class CRSPSystem;
|
||||||
class RSPRegisterHandlerPlugin;
|
class RSPRegisterHandlerPlugin;
|
||||||
|
class CRSPRecompiler;
|
||||||
class CHle;
|
class CHle;
|
||||||
|
|
||||||
class CHleTask
|
class CHleTask :
|
||||||
|
private CGPRRegisters
|
||||||
{
|
{
|
||||||
|
typedef std::pair<uint32_t, void *> TaskFunctionAddress;
|
||||||
|
typedef std::vector<TaskFunctionAddress> TaskFunctions;
|
||||||
|
typedef std::map<uint32_t, TaskFunctions> TaskFunctionMap;
|
||||||
|
|
||||||
struct TASK_INFO
|
struct TASK_INFO
|
||||||
{
|
{
|
||||||
uint32_t Type;
|
uint32_t Type;
|
||||||
|
@ -46,14 +55,27 @@ private:
|
||||||
CHleTask(const CHleTask & copy);
|
CHleTask(const CHleTask & copy);
|
||||||
CHleTask & operator=(const CHleTask & rhs);
|
CHleTask & operator=(const CHleTask & rhs);
|
||||||
|
|
||||||
|
void SetupCommandList(TASK_INFO & TaskInfo);
|
||||||
|
void ExecuteTask_1a13a51a(TASK_INFO & TaskInfo);
|
||||||
|
void SetupTask(TASK_INFO & TaskInfo);
|
||||||
|
|
||||||
void (*&CheckInterrupts)(void);
|
void (*&CheckInterrupts)(void);
|
||||||
void (*&ProcessDList)(void);
|
void (*&ProcessDList)(void);
|
||||||
|
|
||||||
CHle m_hle;
|
CHle m_hle;
|
||||||
|
TaskFunctionMap m_FunctionMap;
|
||||||
|
const TaskFunctions * m_TaskFunctions;
|
||||||
CRSPSystem & m_System;
|
CRSPSystem & m_System;
|
||||||
|
CRSPRecompiler & m_Recompiler;
|
||||||
|
RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
|
||||||
|
uint32_t *& m_MI_INTR_REG;
|
||||||
uint32_t *& m_SP_STATUS_REG;
|
uint32_t *& m_SP_STATUS_REG;
|
||||||
|
uint32_t *& m_SP_DMA_FULL_REG;
|
||||||
|
uint32_t *& m_SP_DMA_BUSY_REG;
|
||||||
uint32_t *& m_SP_PC_REG;
|
uint32_t *& m_SP_PC_REG;
|
||||||
|
uint32_t *& m_SP_SEMAPHORE_REG;
|
||||||
uint32_t *& m_DPC_STATUS_REG;
|
uint32_t *& m_DPC_STATUS_REG;
|
||||||
uint8_t *& m_DMEM;
|
uint8_t *& m_DMEM;
|
||||||
uint8_t *& m_IMEM;
|
uint8_t *& m_IMEM;
|
||||||
|
uint32_t m_UcodeCRC;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,7 @@ p_Recompfunc RSP_Recomp_Sc2[32];
|
||||||
|
|
||||||
CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) :
|
CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) :
|
||||||
m_System(System),
|
m_System(System),
|
||||||
|
m_RecompilerOps(System, *this),
|
||||||
m_RSPRegisterHandler(System.m_RSPRegisterHandler),
|
m_RSPRegisterHandler(System.m_RSPRegisterHandler),
|
||||||
m_CompilePC(0),
|
m_CompilePC(0),
|
||||||
m_OpCode(System.m_OpCode),
|
m_OpCode(System.m_OpCode),
|
||||||
|
@ -718,7 +719,7 @@ sections as well as set the jump table to points
|
||||||
within a block that are safe.
|
within a block that are safe.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void BuildBranchLabels(void)
|
void CRSPRecompiler::BuildBranchLabels(void)
|
||||||
{
|
{
|
||||||
RSPOpcode RspOp;
|
RSPOpcode RspOp;
|
||||||
uint32_t i, Dest;
|
uint32_t i, Dest;
|
||||||
|
@ -810,8 +811,6 @@ void CRSPRecompiler::CompilerLinkBlocks(void)
|
||||||
|
|
||||||
void CRSPRecompiler::CompilerRSPBlock(void)
|
void CRSPRecompiler::CompilerRSPBlock(void)
|
||||||
{
|
{
|
||||||
CRSPRecompilerOps RecompilerOps(RSPSystem, *this);
|
|
||||||
|
|
||||||
uint8_t * IMEM_SAVE = (uint8_t *)malloc(0x1000);
|
uint8_t * IMEM_SAVE = (uint8_t *)malloc(0x1000);
|
||||||
const size_t X86BaseAddress = (size_t)RecompPos;
|
const size_t X86BaseAddress = (size_t)RecompPos;
|
||||||
m_NextInstruction = RSPPIPELINE_NORMAL;
|
m_NextInstruction = RSPPIPELINE_NORMAL;
|
||||||
|
@ -877,7 +876,7 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
||||||
|
|
||||||
if (Compiler.bSections)
|
if (Compiler.bSections)
|
||||||
{
|
{
|
||||||
if (RecompilerOps.RSP_DoSections())
|
if (m_RecompilerOps.RSP_DoSections())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -898,7 +897,7 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])();
|
(m_RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_NextInstruction)
|
switch (m_NextInstruction)
|
||||||
|
@ -910,6 +909,10 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
||||||
m_NextInstruction = RSPPIPELINE_DELAY_SLOT;
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT;
|
||||||
m_CompilePC += 4;
|
m_CompilePC += 4;
|
||||||
break;
|
break;
|
||||||
|
case RSPPIPELINE_DO_DELAY_SLOT_TASK_EXIT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_TASK_EXIT;
|
||||||
|
m_CompilePC += 4;
|
||||||
|
break;
|
||||||
case RSPPIPELINE_DELAY_SLOT:
|
case RSPPIPELINE_DELAY_SLOT:
|
||||||
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE;
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE;
|
||||||
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
||||||
|
@ -918,6 +921,10 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
||||||
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE;
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE;
|
||||||
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
||||||
break;
|
break;
|
||||||
|
case RSPPIPELINE_DELAY_SLOT_TASK_EXIT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_TASK_EXIT_DONE;
|
||||||
|
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
||||||
|
break;
|
||||||
case RSPPIPELINE_FINISH_SUB_BLOCK:
|
case RSPPIPELINE_FINISH_SUB_BLOCK:
|
||||||
m_NextInstruction = RSPPIPELINE_NORMAL;
|
m_NextInstruction = RSPPIPELINE_NORMAL;
|
||||||
m_CompilePC += 8;
|
m_CompilePC += 8;
|
||||||
|
@ -940,7 +947,9 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
||||||
CompilerLinkBlocks();
|
CompilerLinkBlocks();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RSPPIPELINE_FINISH_TASK_SUB_BLOCK:
|
||||||
|
m_NextInstruction = RSPPIPELINE_FINISH_BLOCK;
|
||||||
|
break;
|
||||||
case RSPPIPELINE_FINISH_BLOCK: break;
|
case RSPPIPELINE_FINISH_BLOCK: break;
|
||||||
default:
|
default:
|
||||||
g_Notify->DisplayError(stdstr_f("RSP main loop\n\nWTF m_NextInstruction = %d", m_NextInstruction).c_str());
|
g_Notify->DisplayError(stdstr_f("RSP main loop\n\nWTF m_NextInstruction = %d", m_NextInstruction).c_str());
|
||||||
|
@ -1059,6 +1068,126 @@ void CRSPRecompiler::RunCPU(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CRSPRecompiler::CompileHLETask(uint32_t Address)
|
||||||
|
{
|
||||||
|
uint32_t EndPC = 0x1000;
|
||||||
|
m_CompilePC = (Address & 0xFFF);
|
||||||
|
m_NextInstruction = RSPPIPELINE_NORMAL;
|
||||||
|
|
||||||
|
m_CurrentBlock.StartPC = Address;
|
||||||
|
m_CurrentBlock.CurrPC = Address;
|
||||||
|
|
||||||
|
CPU_Message("====== Block %d ======", BlockID++);
|
||||||
|
CPU_Message("x86 code at: %X", RecompPos);
|
||||||
|
CPU_Message("Jump table: %X", Table);
|
||||||
|
CPU_Message("Start of block: %X", m_CurrentBlock.StartPC);
|
||||||
|
CPU_Message("====== Recompiled code ======");
|
||||||
|
|
||||||
|
*(JumpTable + (m_CompilePC >> 2)) = RecompPos;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (m_NextInstruction == RSPPIPELINE_NORMAL && IsJumpLabel(m_CompilePC))
|
||||||
|
{
|
||||||
|
// Jumps come around twice
|
||||||
|
if (NULL == *(JumpTable + (m_CompilePC >> 2)))
|
||||||
|
{
|
||||||
|
CPU_Message("***** Adding jump table entry for PC: %04X at X86: %08X *****", m_CompilePC, RecompPos);
|
||||||
|
CPU_Message("");
|
||||||
|
*(JumpTable + (m_CompilePC >> 2)) = RecompPos;
|
||||||
|
|
||||||
|
// Reorder from here to next label or branch
|
||||||
|
m_CurrentBlock.CurrPC = m_CompilePC;
|
||||||
|
ReOrderSubBlock(&m_CurrentBlock);
|
||||||
|
}
|
||||||
|
else if (m_NextInstruction != RSPPIPELINE_DELAY_SLOT_DONE)
|
||||||
|
{
|
||||||
|
|
||||||
|
// We could link the blocks here, but performance-wise it might be better to just let it run
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef X86_RECOMP_VERBOSE
|
||||||
|
if (!IsOpcodeNop(m_CompilePC))
|
||||||
|
{
|
||||||
|
CPU_Message("X86 Address: %08X", RecompPos);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
RSP_LW_IMEM(m_CompilePC, &m_OpCode.Value);
|
||||||
|
(m_RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])();
|
||||||
|
|
||||||
|
switch (m_NextInstruction)
|
||||||
|
{
|
||||||
|
case RSPPIPELINE_NORMAL:
|
||||||
|
m_CompilePC += 4;
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_DO_DELAY_SLOT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT;
|
||||||
|
m_CompilePC += 4;
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_DO_DELAY_SLOT_EXIT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT;
|
||||||
|
m_CompilePC += 4;
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_DO_DELAY_SLOT_TASK_EXIT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_TASK_EXIT;
|
||||||
|
m_CompilePC += 4;
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_DELAY_SLOT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_DONE;
|
||||||
|
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_DELAY_SLOT_EXIT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_EXIT_DONE;
|
||||||
|
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_DELAY_SLOT_TASK_EXIT:
|
||||||
|
m_NextInstruction = RSPPIPELINE_DELAY_SLOT_TASK_EXIT_DONE;
|
||||||
|
m_CompilePC = (m_CompilePC - 4 & 0xFFC);
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_FINISH_SUB_BLOCK:
|
||||||
|
m_NextInstruction = RSPPIPELINE_NORMAL;
|
||||||
|
m_CompilePC += 8;
|
||||||
|
if (m_CompilePC >= 0x1000)
|
||||||
|
{
|
||||||
|
m_NextInstruction = RSPPIPELINE_FINISH_BLOCK;
|
||||||
|
}
|
||||||
|
else if (NULL == *(JumpTable + (m_CompilePC >> 2)))
|
||||||
|
{
|
||||||
|
// This is for the new block being compiled now
|
||||||
|
CPU_Message("***** Continuing static SubBlock (jump table entry added for PC: %04X at X86: %08X) *****", m_CompilePC, RecompPos);
|
||||||
|
*(JumpTable + (m_CompilePC >> 2)) = RecompPos;
|
||||||
|
|
||||||
|
m_CurrentBlock.CurrPC = m_CompilePC;
|
||||||
|
// Reorder from after delay to next label or branch
|
||||||
|
ReOrderSubBlock(&m_CurrentBlock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CompilerLinkBlocks();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RSPPIPELINE_FINISH_BLOCK: break;
|
||||||
|
case RSPPIPELINE_FINISH_TASK_SUB_BLOCK:
|
||||||
|
m_NextInstruction = RSPPIPELINE_FINISH_BLOCK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_Notify->DisplayError(stdstr_f("RSP main loop\n\nWTF m_NextInstruction = %d", m_NextInstruction).c_str());
|
||||||
|
m_CompilePC += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CompilePC >= EndPC && *m_System.m_SP_PC_REG != 0 && EndPC != *m_System.m_SP_PC_REG)
|
||||||
|
{
|
||||||
|
m_CompilePC = 0;
|
||||||
|
EndPC = *m_System.m_SP_PC_REG;
|
||||||
|
}
|
||||||
|
} while (m_NextInstruction != RSPPIPELINE_FINISH_BLOCK && (m_CompilePC < EndPC || m_NextInstruction == RSPPIPELINE_DELAY_SLOT || m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE));
|
||||||
|
if (m_CompilePC >= EndPC)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
CPU_Message("===== End of recompiled code =====");
|
||||||
|
}
|
||||||
|
|
||||||
void CRSPRecompiler::Branch_AddRef(uint32_t Target, uint32_t * X86Loc)
|
void CRSPRecompiler::Branch_AddRef(uint32_t Target, uint32_t * X86Loc)
|
||||||
{
|
{
|
||||||
if (m_CurrentBlock.ResolveCount >= 150)
|
if (m_CurrentBlock.ResolveCount >= 150)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Project64-rsp-core/Recompiler/RspRecompilerOps.h>
|
||||||
#include <Project64-rsp-core/Settings/RspSettings.h>
|
#include <Project64-rsp-core/Settings/RspSettings.h>
|
||||||
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
||||||
#include <Project64-rsp-core/cpu/RspPipelineStage.h>
|
#include <Project64-rsp-core/cpu/RspPipelineStage.h>
|
||||||
|
@ -12,6 +13,7 @@ class RSPRegisterHandlerPlugin;
|
||||||
class CRSPRecompiler
|
class CRSPRecompiler
|
||||||
{
|
{
|
||||||
friend class CRSPRecompilerOps;
|
friend class CRSPRecompilerOps;
|
||||||
|
friend class CHleTask;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -38,15 +40,18 @@ private:
|
||||||
CRSPRecompiler(const CRSPRecompiler &);
|
CRSPRecompiler(const CRSPRecompiler &);
|
||||||
CRSPRecompiler & operator=(const CRSPRecompiler &);
|
CRSPRecompiler & operator=(const CRSPRecompiler &);
|
||||||
|
|
||||||
|
void BuildBranchLabels(void);
|
||||||
void BuildRecompilerCPU(void);
|
void BuildRecompilerCPU(void);
|
||||||
void CompilerLinkBlocks(void);
|
void CompilerLinkBlocks(void);
|
||||||
void CompilerRSPBlock(void);
|
void CompilerRSPBlock(void);
|
||||||
|
void CompileHLETask(uint32_t Address);
|
||||||
void LinkBranches(RSP_BLOCK * Block);
|
void LinkBranches(RSP_BLOCK * Block);
|
||||||
void ReOrderSubBlock(RSP_BLOCK * Block);
|
void ReOrderSubBlock(RSP_BLOCK * Block);
|
||||||
void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC);
|
void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC);
|
||||||
void ResetJumpTables(void);
|
void ResetJumpTables(void);
|
||||||
|
|
||||||
CRSPSystem & m_System;
|
CRSPSystem & m_System;
|
||||||
|
CRSPRecompilerOps m_RecompilerOps;
|
||||||
RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
|
RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
|
||||||
RSPOpcode & m_OpCode;
|
RSPOpcode & m_OpCode;
|
||||||
uint32_t m_CompilePC;
|
uint32_t m_CompilePC;
|
||||||
|
|
|
@ -168,6 +168,10 @@ void CRSPRecompilerOps::J(void)
|
||||||
{
|
{
|
||||||
CPU_Message(" %X %s", m_CompilePC, RSPInstruction(m_CompilePC, m_OpCode.Value).NameAndParam().c_str());
|
CPU_Message(" %X %s", m_CompilePC, RSPInstruction(m_CompilePC, m_OpCode.Value).NameAndParam().c_str());
|
||||||
m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT;
|
m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT;
|
||||||
|
if (CRSPSettings::CPUMethod() == RSPCpuMethod::RecompilerTasks && m_OpCode.Value == EndHleTaskOp::J_0x1118)
|
||||||
|
{
|
||||||
|
m_NextInstruction = RSPPIPELINE_DO_DELAY_SLOT_TASK_EXIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE)
|
else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_DONE)
|
||||||
{
|
{
|
||||||
|
@ -175,10 +179,10 @@ void CRSPRecompilerOps::J(void)
|
||||||
m_Recompiler.Branch_AddRef((m_OpCode.target << 2) & 0xFFC, (uint32_t *)(RecompPos - 4));
|
m_Recompiler.Branch_AddRef((m_OpCode.target << 2) & 0xFFC, (uint32_t *)(RecompPos - 4));
|
||||||
m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK;
|
m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK;
|
||||||
}
|
}
|
||||||
else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE)
|
else if (m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE || m_NextInstruction == RSPPIPELINE_DELAY_SLOT_TASK_EXIT_DONE)
|
||||||
{
|
{
|
||||||
MoveConstToVariable((m_OpCode.target << 2) & 0xFFC, m_System.m_SP_PC_REG, "RSP PC");
|
MoveConstToVariable((m_OpCode.target << 2) & 0xFFC, m_System.m_SP_PC_REG, "RSP PC");
|
||||||
m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK;
|
m_NextInstruction = m_NextInstruction == RSPPIPELINE_DELAY_SLOT_EXIT_DONE ? RSPPIPELINE_FINISH_SUB_BLOCK : RSPPIPELINE_FINISH_TASK_SUB_BLOCK;
|
||||||
Ret();
|
Ret();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1494,17 +1498,14 @@ void CRSPRecompilerOps::Special_JR(void)
|
||||||
TestX86RegToX86Reg(x86_EAX, x86_EAX);
|
TestX86RegToX86Reg(x86_EAX, x86_EAX);
|
||||||
JeLabel8("Null", 0);
|
JeLabel8("Null", 0);
|
||||||
Jump = RecompPos - 1;
|
Jump = RecompPos - 1;
|
||||||
|
|
||||||
// Before we branch quickly update our stats
|
|
||||||
/*if (m_CompilePC == 0x080) {
|
|
||||||
Pushad();
|
|
||||||
Call_Direct((void *)UpdateAudioTimer, "UpdateAudioTimer");
|
|
||||||
Popad();
|
|
||||||
}*/
|
|
||||||
JumpX86Reg(x86_EAX);
|
JumpX86Reg(x86_EAX);
|
||||||
|
|
||||||
x86_SetBranch8b(Jump, RecompPos);
|
x86_SetBranch8b(Jump, RecompPos);
|
||||||
CPU_Message(" Null:");
|
CPU_Message(" Null:");
|
||||||
|
if (CRSPSettings::CPUMethod() == RSPCpuMethod::HighLevelEmulation)
|
||||||
|
{
|
||||||
|
BreakPoint();
|
||||||
|
}
|
||||||
Ret();
|
Ret();
|
||||||
ChangedPC = false;
|
ChangedPC = false;
|
||||||
m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK;
|
m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
// Opcode functions
|
#pragma once
|
||||||
#include <Project64-rsp-core/cpu/RSPInterpreterOps.h>
|
#include <Project64-rsp-core/cpu/RSPInterpreterOps.h>
|
||||||
|
|
||||||
class CRSPSystem;
|
class CRSPSystem;
|
||||||
class CRSPRegisters;
|
class CRSPRegisters;
|
||||||
|
class CRSPRecompiler;
|
||||||
|
|
||||||
class CRSPRecompilerOps
|
class CRSPRecompilerOps
|
||||||
{
|
{
|
||||||
|
@ -11,6 +12,11 @@ class CRSPRecompilerOps
|
||||||
HIT_BRANCH = 0x2,
|
HIT_BRANCH = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EndHleTaskOp
|
||||||
|
{
|
||||||
|
J_0x1118 = 0x09000446
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRSPRecompilerOps(CRSPSystem & System, CRSPRecompiler & Recompiler);
|
CRSPRecompilerOps(CRSPSystem & System, CRSPRecompiler & Recompiler);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ RSPCpuMethod CRSPSettings::m_CPUMethod = RSPCpuMethod::Interpreter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t Set_AudioHle = 0, Set_GraphicsHle = 0, Set_MultiThreaded = 0, Set_AllocatedRdramSize = 0, Set_DirectoryLog = 0;
|
uint16_t Set_AudioHle = 0, Set_GraphicsHle = 0, Set_MultiThreaded = 0, Set_AllocatedRdramSize = 0, Set_DirectoryLog = 0;
|
||||||
bool GraphicsHle = true, AudioHle, ConditionalMove, HleAlistTask = false, RspMultiThreaded = false;
|
bool GraphicsHle = true, AudioHle, ConditionalMove, SyncCPU = false, HleAlistTask = false, RspMultiThreaded = false;
|
||||||
bool DebuggingEnabled = false, Profiling, IndvidualBlock, ShowErrors, BreakOnStart = false, LogRDP = false, LogX86Code = false;
|
bool DebuggingEnabled = false, Profiling, IndvidualBlock, ShowErrors, BreakOnStart = false, LogRDP = false, LogX86Code = false;
|
||||||
|
|
||||||
void CRSPSettings::EnableDebugging(bool Enabled)
|
void CRSPSettings::EnableDebugging(bool Enabled)
|
||||||
|
@ -40,6 +40,7 @@ void CRSPSettings::InitializeRspSetting(void)
|
||||||
RegisterSetting(Set_IndvidualBlock, Data_DWORD_General, "Individual Block", NULL, IndvidualBlock, NULL);
|
RegisterSetting(Set_IndvidualBlock, Data_DWORD_General, "Individual Block", NULL, IndvidualBlock, NULL);
|
||||||
RegisterSetting(Set_ShowErrors, Data_DWORD_General, "Show Errors", NULL, ShowErrors, NULL);
|
RegisterSetting(Set_ShowErrors, Data_DWORD_General, "Show Errors", NULL, ShowErrors, NULL);
|
||||||
RegisterSetting(Set_HleAlistTask, Data_DWORD_General, "Hle Alist Task", NULL, HleAlistTask, NULL);
|
RegisterSetting(Set_HleAlistTask, Data_DWORD_General, "Hle Alist Task", NULL, HleAlistTask, NULL);
|
||||||
|
RegisterSetting(Set_SyncCPU, Data_DWORD_General, "Sync CPU", NULL, SyncCPU, NULL);
|
||||||
|
|
||||||
// Compiler settings
|
// Compiler settings
|
||||||
RegisterSetting(Set_CheckDest, Data_DWORD_General, "Check Destination Vector", NULL, Compiler.bDest, NULL);
|
RegisterSetting(Set_CheckDest, Data_DWORD_General, "Check Destination Vector", NULL, Compiler.bDest, NULL);
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
extern uint16_t Set_AudioHle, Set_GraphicsHle, Set_AllocatedRdramSize, Set_DirectoryLog;
|
extern uint16_t Set_AudioHle, Set_GraphicsHle, Set_AllocatedRdramSize, Set_DirectoryLog;
|
||||||
extern bool GraphicsHle, AudioHle, ConditionalMove, HleAlistTask, RspMultiThreaded;
|
extern bool GraphicsHle, AudioHle, ConditionalMove, SyncCPU, HleAlistTask, RspMultiThreaded;
|
||||||
extern bool DebuggingEnabled, Profiling, IndvidualBlock, ShowErrors, BreakOnStart, LogRDP, LogX86Code;
|
extern bool DebuggingEnabled, Profiling, IndvidualBlock, ShowErrors, BreakOnStart, LogRDP, LogX86Code;
|
||||||
|
|
||||||
enum class RSPCpuMethod
|
enum class RSPCpuMethod
|
||||||
{
|
{
|
||||||
Interpreter = 0,
|
Interpreter = 0,
|
||||||
Recompiler = 1,
|
Recompiler = 1,
|
||||||
HighLevelEmulation = 2,
|
RecompilerTasks = 2,
|
||||||
|
HighLevelEmulation = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
class CRSPSettings
|
class CRSPSettings
|
||||||
|
|
|
@ -10,6 +10,7 @@ enum
|
||||||
Set_IndvidualBlock,
|
Set_IndvidualBlock,
|
||||||
Set_ShowErrors,
|
Set_ShowErrors,
|
||||||
Set_HleAlistTask,
|
Set_HleAlistTask,
|
||||||
|
Set_SyncCPU,
|
||||||
|
|
||||||
// Compiler settings
|
// Compiler settings
|
||||||
Set_CheckDest,
|
Set_CheckDest,
|
||||||
|
|
|
@ -112,6 +112,7 @@ uint32_t DoRspCycles(uint32_t Cycles)
|
||||||
RSPSystem.RunRecompiler();
|
RSPSystem.RunRecompiler();
|
||||||
break;
|
break;
|
||||||
case RSPCpuMethod::Interpreter:
|
case RSPCpuMethod::Interpreter:
|
||||||
|
case RSPCpuMethod::RecompilerTasks:
|
||||||
case RSPCpuMethod::HighLevelEmulation:
|
case RSPCpuMethod::HighLevelEmulation:
|
||||||
RSPSystem.ExecuteOps((uint32_t)-1, (uint32_t)-1);
|
RSPSystem.ExecuteOps((uint32_t)-1, (uint32_t)-1);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
extern bool AudioHle, GraphicsHle;
|
|
||||||
|
|
||||||
uint32_t clz32(uint32_t val)
|
uint32_t clz32(uint32_t val)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <Project64-rsp-core/Settings/RspSettings.h>
|
||||||
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
||||||
#include <Project64-rsp-core/cpu/RspPipelineStage.h>
|
#include <Project64-rsp-core/cpu/RspPipelineStage.h>
|
||||||
#include <Project64-rsp-core/cpu/RspTypes.h>
|
#include <Project64-rsp-core/cpu/RspTypes.h>
|
||||||
|
@ -12,6 +13,7 @@ class RSPOp :
|
||||||
{
|
{
|
||||||
friend class CRSPSystem;
|
friend class CRSPSystem;
|
||||||
friend class CRSPRecompilerOps;
|
friend class CRSPRecompilerOps;
|
||||||
|
friend class CHleTask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RSPOp(CRSPSystem & System);
|
RSPOp(CRSPSystem & System);
|
||||||
|
|
|
@ -37,6 +37,42 @@ const char * GPR_Strings[32] = {
|
||||||
"RA",
|
"RA",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CGPRRegisters::CGPRRegisters(UWORD32 (&m_GPR)[32]) :
|
||||||
|
GPR_R0(m_GPR[0].UW),
|
||||||
|
GPR_AT(m_GPR[1].UW),
|
||||||
|
GPR_V0(m_GPR[2].UW),
|
||||||
|
GPR_V1(m_GPR[3].UW),
|
||||||
|
GPR_A0(m_GPR[4].UW),
|
||||||
|
GPR_A1(m_GPR[5].UW),
|
||||||
|
GPR_A2(m_GPR[6].UW),
|
||||||
|
GPR_A3(m_GPR[7].UW),
|
||||||
|
GPR_T0(m_GPR[8].UW),
|
||||||
|
GPR_T1(m_GPR[9].UW),
|
||||||
|
GPR_T2(m_GPR[10].UW),
|
||||||
|
GPR_T3(m_GPR[11].UW),
|
||||||
|
GPR_T4(m_GPR[12].UW),
|
||||||
|
GPR_T5(m_GPR[13].UW),
|
||||||
|
GPR_T6(m_GPR[14].UW),
|
||||||
|
GPR_T7(m_GPR[15].UW),
|
||||||
|
GPR_S0(m_GPR[16].UW),
|
||||||
|
GPR_S1(m_GPR[17].UW),
|
||||||
|
GPR_S2(m_GPR[18].UW),
|
||||||
|
GPR_S3(m_GPR[19].UW),
|
||||||
|
GPR_S4(m_GPR[20].UW),
|
||||||
|
GPR_S5(m_GPR[21].UW),
|
||||||
|
GPR_S6(m_GPR[22].UW),
|
||||||
|
GPR_S7(m_GPR[23].UW),
|
||||||
|
GPR_T8(m_GPR[24].UW),
|
||||||
|
GPR_T9(m_GPR[25].UW),
|
||||||
|
GPR_K0(m_GPR[26].UW),
|
||||||
|
GPR_K1(m_GPR[27].UW),
|
||||||
|
GPR_GP(m_GPR[28].UW),
|
||||||
|
GPR_SP(m_GPR[29].UW),
|
||||||
|
GPR_S8(m_GPR[30].UW),
|
||||||
|
GPR_RA(m_GPR[31].UW)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CRSPRegisters::CRSPRegisters() :
|
CRSPRegisters::CRSPRegisters() :
|
||||||
VCOL(m_Flags[0].UB[0]),
|
VCOL(m_Flags[0].UB[0]),
|
||||||
VCOH(m_Flags[0].UB[1]),
|
VCOH(m_Flags[0].UB[1]),
|
||||||
|
|
|
@ -20,7 +20,8 @@ RSPRegisterHandler::RSPRegisterHandler(uint32_t * SignalProcessorInterface, uint
|
||||||
m_IMEM(IMEM),
|
m_IMEM(IMEM),
|
||||||
m_DMEM(DMEM),
|
m_DMEM(DMEM),
|
||||||
m_PendingSPMemAddr(0),
|
m_PendingSPMemAddr(0),
|
||||||
m_PendingSPDramAddr(0)
|
m_PendingSPDramAddr(0),
|
||||||
|
m_IgnoreWrites(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,8 @@ RSPRegisterHandler::RSPRegisterHandler(CRSPSystem & System) :
|
||||||
m_IMEM(System.m_IMEM),
|
m_IMEM(System.m_IMEM),
|
||||||
m_DMEM(System.m_DMEM),
|
m_DMEM(System.m_DMEM),
|
||||||
m_PendingSPMemAddr(0),
|
m_PendingSPMemAddr(0),
|
||||||
m_PendingSPDramAddr(0)
|
m_PendingSPDramAddr(0),
|
||||||
|
m_IgnoreWrites(System.m_BaseSystem != nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +168,7 @@ void RSPRegisterHandler::SP_DMA_WRITE()
|
||||||
{
|
{
|
||||||
CopyAmount = CopyLength;
|
CopyAmount = CopyLength;
|
||||||
}
|
}
|
||||||
if (CopyAmount > 0)
|
if (CopyAmount > 0 && !m_IgnoreWrites)
|
||||||
{
|
{
|
||||||
memcpy(&Dest[WritePos], &Source[Pos], CopyAmount);
|
memcpy(&Dest[WritePos], &Source[Pos], CopyAmount);
|
||||||
}
|
}
|
||||||
|
@ -183,7 +185,7 @@ void RSPRegisterHandler::SP_DMA_WRITE()
|
||||||
{
|
{
|
||||||
CopyAmount = CopyLength;
|
CopyAmount = CopyLength;
|
||||||
}
|
}
|
||||||
if (CopyAmount > 0)
|
if (CopyAmount > 0 && !m_IgnoreWrites)
|
||||||
{
|
{
|
||||||
memcpy(&Dest[WritePos], &Source[Pos], CopyAmount);
|
memcpy(&Dest[WritePos], &Source[Pos], CopyAmount);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,4 +63,5 @@ protected:
|
||||||
uint8_t * m_DMEM;
|
uint8_t * m_DMEM;
|
||||||
uint32_t m_PendingSPMemAddr;
|
uint32_t m_PendingSPMemAddr;
|
||||||
uint32_t m_PendingSPDramAddr;
|
uint32_t m_PendingSPDramAddr;
|
||||||
|
bool m_IgnoreWrites;
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,6 +71,49 @@ enum
|
||||||
MI_INTR_SP = 0x01, // Bit 0: SP INTR
|
MI_INTR_SP = 0x01, // Bit 0: SP INTR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CGPRRegisters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CGPRRegisters(UWORD32 (&m_GPR)[32]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CGPRRegisters();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32_t & GPR_R0;
|
||||||
|
uint32_t & GPR_AT;
|
||||||
|
uint32_t & GPR_V0;
|
||||||
|
uint32_t & GPR_V1;
|
||||||
|
uint32_t & GPR_A0;
|
||||||
|
uint32_t & GPR_A1;
|
||||||
|
uint32_t & GPR_A2;
|
||||||
|
uint32_t & GPR_A3;
|
||||||
|
uint32_t & GPR_T0;
|
||||||
|
uint32_t & GPR_T1;
|
||||||
|
uint32_t & GPR_T2;
|
||||||
|
uint32_t & GPR_T3;
|
||||||
|
uint32_t & GPR_T4;
|
||||||
|
uint32_t & GPR_T5;
|
||||||
|
uint32_t & GPR_T6;
|
||||||
|
uint32_t & GPR_T7;
|
||||||
|
uint32_t & GPR_S0;
|
||||||
|
uint32_t & GPR_S1;
|
||||||
|
uint32_t & GPR_S2;
|
||||||
|
uint32_t & GPR_S3;
|
||||||
|
uint32_t & GPR_S4;
|
||||||
|
uint32_t & GPR_S5;
|
||||||
|
uint32_t & GPR_S6;
|
||||||
|
uint32_t & GPR_S7;
|
||||||
|
uint32_t & GPR_T8;
|
||||||
|
uint32_t & GPR_T9;
|
||||||
|
uint32_t & GPR_K0;
|
||||||
|
uint32_t & GPR_K1;
|
||||||
|
uint32_t & GPR_GP;
|
||||||
|
uint32_t & GPR_SP;
|
||||||
|
uint32_t & GPR_S8;
|
||||||
|
uint32_t & GPR_RA;
|
||||||
|
};
|
||||||
|
|
||||||
class CRSPRegisters
|
class CRSPRegisters
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -2,15 +2,20 @@
|
||||||
|
|
||||||
enum RSPPIPELINE_STAGE
|
enum RSPPIPELINE_STAGE
|
||||||
{
|
{
|
||||||
RSPPIPELINE_NORMAL = 0,
|
RSPPIPELINE_NORMAL,
|
||||||
RSPPIPELINE_DO_DELAY_SLOT = 1,
|
RSPPIPELINE_DO_DELAY_SLOT,
|
||||||
RSPPIPELINE_DELAY_SLOT = 2,
|
RSPPIPELINE_DO_DELAY_SLOT_EXIT,
|
||||||
RSPPIPELINE_DELAY_SLOT_DONE = 3,
|
RSPPIPELINE_DO_DELAY_SLOT_TASK_EXIT,
|
||||||
RSPPIPELINE_DELAY_SLOT_EXIT = 4,
|
RSPPIPELINE_DELAY_SLOT,
|
||||||
RSPPIPELINE_DELAY_SLOT_EXIT_DONE = 5,
|
RSPPIPELINE_DELAY_SLOT_DONE,
|
||||||
RSPPIPELINE_JUMP = 6,
|
RSPPIPELINE_DELAY_SLOT_EXIT,
|
||||||
RSPPIPELINE_SINGLE_STEP = 7,
|
RSPPIPELINE_DELAY_SLOT_EXIT_DONE,
|
||||||
RSPPIPELINE_SINGLE_STEP_DONE = 8,
|
RSPPIPELINE_DELAY_SLOT_TASK_EXIT,
|
||||||
RSPPIPELINE_FINISH_BLOCK = 9,
|
RSPPIPELINE_DELAY_SLOT_TASK_EXIT_DONE,
|
||||||
RSPPIPELINE_FINISH_SUB_BLOCK = 10,
|
RSPPIPELINE_JUMP,
|
||||||
|
RSPPIPELINE_SINGLE_STEP,
|
||||||
|
RSPPIPELINE_SINGLE_STEP_DONE,
|
||||||
|
RSPPIPELINE_FINISH_BLOCK,
|
||||||
|
RSPPIPELINE_FINISH_SUB_BLOCK,
|
||||||
|
RSPPIPELINE_FINISH_TASK_SUB_BLOCK,
|
||||||
};
|
};
|
|
@ -11,6 +11,8 @@ CRSPSystem RSPSystem;
|
||||||
|
|
||||||
CRSPSystem::CRSPSystem() :
|
CRSPSystem::CRSPSystem() :
|
||||||
CHleTask(*this),
|
CHleTask(*this),
|
||||||
|
m_SyncSystem(nullptr),
|
||||||
|
m_BaseSystem(nullptr),
|
||||||
m_Recompiler(*this),
|
m_Recompiler(*this),
|
||||||
m_RSPRegisterHandler(nullptr),
|
m_RSPRegisterHandler(nullptr),
|
||||||
m_Op(*this),
|
m_Op(*this),
|
||||||
|
@ -38,9 +40,10 @@ CRSPSystem::CRSPSystem() :
|
||||||
m_DPC_BUFBUSY_REG(nullptr),
|
m_DPC_BUFBUSY_REG(nullptr),
|
||||||
m_DPC_PIPEBUSY_REG(nullptr),
|
m_DPC_PIPEBUSY_REG(nullptr),
|
||||||
m_DPC_TMEM_REG(nullptr),
|
m_DPC_TMEM_REG(nullptr),
|
||||||
CheckInterrupts(nullptr),
|
CheckInterrupts(NullCheckInterrupts),
|
||||||
ProcessDList(nullptr),
|
ProcessDList(NullProcessDList),
|
||||||
ProcessRdpList(nullptr),
|
ProcessRdpList(NullProcessRdpList),
|
||||||
|
m_SyncReg(nullptr),
|
||||||
m_RdramSize(0)
|
m_RdramSize(0)
|
||||||
{
|
{
|
||||||
m_OpCode.Value = 0;
|
m_OpCode.Value = 0;
|
||||||
|
@ -48,6 +51,29 @@ CRSPSystem::CRSPSystem() :
|
||||||
|
|
||||||
CRSPSystem::~CRSPSystem()
|
CRSPSystem::~CRSPSystem()
|
||||||
{
|
{
|
||||||
|
if (m_SyncSystem->m_BaseSystem != nullptr)
|
||||||
|
{
|
||||||
|
if (m_IMEM != nullptr)
|
||||||
|
{
|
||||||
|
delete[] m_IMEM;
|
||||||
|
m_IMEM = nullptr;
|
||||||
|
}
|
||||||
|
if (m_DMEM != nullptr)
|
||||||
|
{
|
||||||
|
delete[] m_DMEM;
|
||||||
|
m_DMEM = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_SyncReg != nullptr)
|
||||||
|
{
|
||||||
|
delete m_SyncReg;
|
||||||
|
m_SyncReg = nullptr;
|
||||||
|
}
|
||||||
|
if (m_SyncSystem)
|
||||||
|
{
|
||||||
|
delete m_SyncSystem;
|
||||||
|
m_SyncSystem = nullptr;
|
||||||
|
}
|
||||||
if (m_RSPRegisterHandler != nullptr)
|
if (m_RSPRegisterHandler != nullptr)
|
||||||
{
|
{
|
||||||
delete m_RSPRegisterHandler;
|
delete m_RSPRegisterHandler;
|
||||||
|
@ -61,29 +87,33 @@ void CRSPSystem::Reset(RSP_INFO & Info)
|
||||||
|
|
||||||
m_HEADER = Info.HEADER;
|
m_HEADER = Info.HEADER;
|
||||||
m_RDRAM = Info.RDRAM;
|
m_RDRAM = Info.RDRAM;
|
||||||
m_DMEM = Info.DMEM;
|
|
||||||
m_IMEM = Info.IMEM;
|
if (m_BaseSystem == nullptr)
|
||||||
m_MI_INTR_REG = Info.MI_INTR_REG;
|
{
|
||||||
m_SP_MEM_ADDR_REG = Info.SP_MEM_ADDR_REG;
|
m_DMEM = Info.DMEM;
|
||||||
m_SP_DRAM_ADDR_REG = Info.SP_DRAM_ADDR_REG;
|
m_IMEM = Info.IMEM;
|
||||||
m_SP_RD_LEN_REG = Info.SP_RD_LEN_REG;
|
m_MI_INTR_REG = Info.MI_INTR_REG;
|
||||||
m_SP_WR_LEN_REG = Info.SP_WR_LEN_REG;
|
m_SP_MEM_ADDR_REG = Info.SP_MEM_ADDR_REG;
|
||||||
m_SP_STATUS_REG = Info.SP_STATUS_REG;
|
m_SP_DRAM_ADDR_REG = Info.SP_DRAM_ADDR_REG;
|
||||||
m_SP_DMA_FULL_REG = Info.SP_DMA_FULL_REG;
|
m_SP_RD_LEN_REG = Info.SP_RD_LEN_REG;
|
||||||
m_SP_DMA_BUSY_REG = Info.SP_DMA_BUSY_REG;
|
m_SP_WR_LEN_REG = Info.SP_WR_LEN_REG;
|
||||||
m_SP_PC_REG = Info.SP_PC_REG;
|
m_SP_STATUS_REG = Info.SP_STATUS_REG;
|
||||||
m_SP_SEMAPHORE_REG = Info.SP_SEMAPHORE_REG;
|
m_SP_DMA_FULL_REG = Info.SP_DMA_FULL_REG;
|
||||||
m_DPC_START_REG = Info.DPC_START_REG;
|
m_SP_DMA_BUSY_REG = Info.SP_DMA_BUSY_REG;
|
||||||
m_DPC_END_REG = Info.DPC_END_REG;
|
m_SP_PC_REG = Info.SP_PC_REG;
|
||||||
m_DPC_CURRENT_REG = Info.DPC_CURRENT_REG;
|
m_SP_SEMAPHORE_REG = Info.SP_SEMAPHORE_REG;
|
||||||
m_DPC_STATUS_REG = Info.DPC_STATUS_REG;
|
m_DPC_START_REG = Info.DPC_START_REG;
|
||||||
m_DPC_CLOCK_REG = Info.DPC_CLOCK_REG;
|
m_DPC_END_REG = Info.DPC_END_REG;
|
||||||
m_DPC_BUFBUSY_REG = Info.DPC_BUFBUSY_REG;
|
m_DPC_CURRENT_REG = Info.DPC_CURRENT_REG;
|
||||||
m_DPC_PIPEBUSY_REG = Info.DPC_PIPEBUSY_REG;
|
m_DPC_STATUS_REG = Info.DPC_STATUS_REG;
|
||||||
m_DPC_TMEM_REG = Info.DPC_TMEM_REG;
|
m_DPC_CLOCK_REG = Info.DPC_CLOCK_REG;
|
||||||
CheckInterrupts = Info.CheckInterrupts;
|
m_DPC_BUFBUSY_REG = Info.DPC_BUFBUSY_REG;
|
||||||
ProcessDList = Info.ProcessDList;
|
m_DPC_PIPEBUSY_REG = Info.DPC_PIPEBUSY_REG;
|
||||||
ProcessRdpList = Info.ProcessRdpList;
|
m_DPC_TMEM_REG = Info.DPC_TMEM_REG;
|
||||||
|
CheckInterrupts = Info.CheckInterrupts;
|
||||||
|
ProcessDList = Info.ProcessDList;
|
||||||
|
ProcessRdpList = Info.ProcessRdpList;
|
||||||
|
}
|
||||||
|
|
||||||
m_RdramSize = Set_AllocatedRdramSize != 0 ? GetSystemSetting(Set_AllocatedRdramSize) : 0;
|
m_RdramSize = Set_AllocatedRdramSize != 0 ? GetSystemSetting(Set_AllocatedRdramSize) : 0;
|
||||||
if (m_RdramSize == 0)
|
if (m_RdramSize == 0)
|
||||||
|
@ -91,6 +121,11 @@ void CRSPSystem::Reset(RSP_INFO & Info)
|
||||||
m_RdramSize = 0x00400000;
|
m_RdramSize = 0x00400000;
|
||||||
}
|
}
|
||||||
m_RSPRegisterHandler = new RSPRegisterHandlerPlugin(*this);
|
m_RSPRegisterHandler = new RSPRegisterHandlerPlugin(*this);
|
||||||
|
|
||||||
|
if (m_SyncSystem != nullptr)
|
||||||
|
{
|
||||||
|
m_SyncSystem->Reset(Info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRSPSystem::RomClosed(void)
|
void CRSPSystem::RomClosed(void)
|
||||||
|
@ -159,3 +194,166 @@ void CRSPSystem::ExecuteOps(uint32_t Cycles, uint32_t TargetPC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CRSPSystem::SetupSyncCPU()
|
||||||
|
{
|
||||||
|
if (m_SyncSystem == nullptr)
|
||||||
|
{
|
||||||
|
m_SyncSystem = new CRSPSystem();
|
||||||
|
m_SyncSystem->m_BaseSystem = this;
|
||||||
|
m_SyncSystem->m_HEADER = m_HEADER;
|
||||||
|
m_SyncSystem->m_RDRAM = m_RDRAM;
|
||||||
|
m_SyncSystem->m_IMEM = new uint8_t[0x1000];
|
||||||
|
m_SyncSystem->m_DMEM = new uint8_t[0x1000];
|
||||||
|
m_SyncSystem->m_SyncReg = new uint32_t[18];
|
||||||
|
m_SyncSystem->m_MI_INTR_REG = &m_SyncSystem->m_SyncReg[0];
|
||||||
|
m_SyncSystem->m_SP_MEM_ADDR_REG = &m_SyncSystem->m_SyncReg[1];
|
||||||
|
m_SyncSystem->m_SP_DRAM_ADDR_REG = &m_SyncSystem->m_SyncReg[2];
|
||||||
|
m_SyncSystem->m_SP_RD_LEN_REG = &m_SyncSystem->m_SyncReg[3];
|
||||||
|
m_SyncSystem->m_SP_WR_LEN_REG = &m_SyncSystem->m_SyncReg[4];
|
||||||
|
m_SyncSystem->m_SP_STATUS_REG = &m_SyncSystem->m_SyncReg[5];
|
||||||
|
m_SyncSystem->m_SP_DMA_FULL_REG = &m_SyncSystem->m_SyncReg[6];
|
||||||
|
m_SyncSystem->m_SP_DMA_BUSY_REG = &m_SyncSystem->m_SyncReg[7];
|
||||||
|
m_SyncSystem->m_SP_PC_REG = &m_SyncSystem->m_SyncReg[8];
|
||||||
|
m_SyncSystem->m_SP_SEMAPHORE_REG = &m_SyncSystem->m_SyncReg[9];
|
||||||
|
m_SyncSystem->m_DPC_START_REG = &m_SyncSystem->m_SyncReg[10];
|
||||||
|
m_SyncSystem->m_DPC_END_REG = &m_SyncSystem->m_SyncReg[11];
|
||||||
|
m_SyncSystem->m_DPC_CURRENT_REG = &m_SyncSystem->m_SyncReg[12];
|
||||||
|
m_SyncSystem->m_DPC_STATUS_REG = &m_SyncSystem->m_SyncReg[13];
|
||||||
|
m_SyncSystem->m_DPC_CLOCK_REG = &m_SyncSystem->m_SyncReg[14];
|
||||||
|
m_SyncSystem->m_DPC_BUFBUSY_REG = &m_SyncSystem->m_SyncReg[15];
|
||||||
|
m_SyncSystem->m_DPC_PIPEBUSY_REG = &m_SyncSystem->m_SyncReg[16];
|
||||||
|
m_SyncSystem->m_DPC_TMEM_REG = &m_SyncSystem->m_SyncReg[17];
|
||||||
|
|
||||||
|
m_SyncSystem->m_Reg.Reset();
|
||||||
|
m_SyncSystem->m_RdramSize = m_RdramSize;
|
||||||
|
m_SyncSystem->m_RSPRegisterHandler = new RSPRegisterHandlerPlugin(*m_SyncSystem);
|
||||||
|
}
|
||||||
|
if (m_IMEM != nullptr)
|
||||||
|
{
|
||||||
|
memcpy(m_SyncSystem->m_IMEM, m_IMEM, 0x1000);
|
||||||
|
}
|
||||||
|
if (m_DMEM != nullptr)
|
||||||
|
{
|
||||||
|
memcpy(m_SyncSystem->m_DMEM, m_DMEM, 0x1000);
|
||||||
|
}
|
||||||
|
*m_SyncSystem->m_MI_INTR_REG = *m_MI_INTR_REG;
|
||||||
|
*m_SyncSystem->m_SP_MEM_ADDR_REG = *m_SP_MEM_ADDR_REG;
|
||||||
|
*m_SyncSystem->m_SP_DRAM_ADDR_REG = *m_SP_DRAM_ADDR_REG;
|
||||||
|
*m_SyncSystem->m_SP_RD_LEN_REG = *m_SP_RD_LEN_REG;
|
||||||
|
*m_SyncSystem->m_SP_WR_LEN_REG = *m_SP_WR_LEN_REG;
|
||||||
|
*m_SyncSystem->m_SP_STATUS_REG = *m_SP_STATUS_REG;
|
||||||
|
*m_SyncSystem->m_SP_DMA_FULL_REG = *m_SP_DMA_FULL_REG;
|
||||||
|
*m_SyncSystem->m_SP_DMA_BUSY_REG = *m_SP_DMA_BUSY_REG;
|
||||||
|
*m_SyncSystem->m_SP_PC_REG = *m_SP_PC_REG;
|
||||||
|
*m_SyncSystem->m_SP_SEMAPHORE_REG = *m_SP_SEMAPHORE_REG;
|
||||||
|
*m_SyncSystem->m_DPC_START_REG = *m_DPC_START_REG;
|
||||||
|
*m_SyncSystem->m_DPC_END_REG = *m_DPC_END_REG;
|
||||||
|
*m_SyncSystem->m_DPC_CURRENT_REG = *m_DPC_CURRENT_REG;
|
||||||
|
*m_SyncSystem->m_DPC_STATUS_REG = *m_DPC_STATUS_REG;
|
||||||
|
*m_SyncSystem->m_DPC_CLOCK_REG = *m_DPC_CLOCK_REG;
|
||||||
|
*m_SyncSystem->m_DPC_BUFBUSY_REG = *m_DPC_BUFBUSY_REG;
|
||||||
|
*m_SyncSystem->m_DPC_PIPEBUSY_REG = *m_DPC_PIPEBUSY_REG;
|
||||||
|
*m_SyncSystem->m_DPC_TMEM_REG = *m_DPC_TMEM_REG;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CRSPSystem::IsSyncSystem(void)
|
||||||
|
{
|
||||||
|
return m_BaseSystem != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRSPSystem * CRSPSystem::SyncSystem(void)
|
||||||
|
{
|
||||||
|
if (m_SyncSystem == nullptr)
|
||||||
|
{
|
||||||
|
SetupSyncCPU();
|
||||||
|
}
|
||||||
|
return m_SyncSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRSPSystem::BasicSyncCheck(void)
|
||||||
|
{
|
||||||
|
bool SyncFailed = false;
|
||||||
|
if (memcmp(m_IMEM, m_SyncSystem->m_IMEM, 0x1000) != 0)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (memcmp(m_DMEM, m_SyncSystem->m_DMEM, 0x1000) != 0)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
for (uint32_t i = 0, n = 0x1000; i < n; i++)
|
||||||
|
{
|
||||||
|
if (m_DMEM[i] != m_SyncSystem->m_DMEM[i])
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*m_MI_INTR_REG != *m_SyncSystem->m_MI_INTR_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_MEM_ADDR_REG != *m_SyncSystem->m_SP_MEM_ADDR_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_DRAM_ADDR_REG != *m_SyncSystem->m_SP_DRAM_ADDR_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_RD_LEN_REG != *m_SyncSystem->m_SP_RD_LEN_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_WR_LEN_REG != *m_SyncSystem->m_SP_WR_LEN_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_STATUS_REG != *m_SyncSystem->m_SP_STATUS_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_DMA_FULL_REG != *m_SyncSystem->m_SP_DMA_FULL_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_DMA_BUSY_REG != *m_SyncSystem->m_SP_DMA_BUSY_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_PC_REG != *m_SyncSystem->m_SP_PC_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (*m_SP_SEMAPHORE_REG != *m_SyncSystem->m_SP_SEMAPHORE_REG)
|
||||||
|
{
|
||||||
|
SyncFailed = true;
|
||||||
|
}
|
||||||
|
if (SyncFailed)
|
||||||
|
{
|
||||||
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void * CRSPSystem::operator new(size_t size)
|
||||||
|
{
|
||||||
|
return _aligned_malloc(size, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRSPSystem::operator delete(void * ptr)
|
||||||
|
{
|
||||||
|
_aligned_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRSPSystem::NullProcessDList(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRSPSystem::NullProcessRdpList(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRSPSystem::NullCheckInterrupts(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -34,11 +34,23 @@ public:
|
||||||
|
|
||||||
void RunRecompiler(void);
|
void RunRecompiler(void);
|
||||||
void ExecuteOps(uint32_t Cycles, uint32_t TargetPC);
|
void ExecuteOps(uint32_t Cycles, uint32_t TargetPC);
|
||||||
|
void SetupSyncCPU();
|
||||||
|
bool IsSyncSystem(void);
|
||||||
|
CRSPSystem * SyncSystem(void);
|
||||||
|
void BasicSyncCheck(void);
|
||||||
|
void * operator new(size_t size);
|
||||||
|
void operator delete(void * ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CRSPSystem(const CRSPSystem &);
|
CRSPSystem(const CRSPSystem &);
|
||||||
CRSPSystem & operator=(const CRSPSystem &);
|
CRSPSystem & operator=(const CRSPSystem &);
|
||||||
|
|
||||||
|
static void NullProcessDList(void);
|
||||||
|
static void NullProcessRdpList(void);
|
||||||
|
static void NullCheckInterrupts(void);
|
||||||
|
|
||||||
|
CRSPSystem * m_SyncSystem;
|
||||||
|
CRSPSystem * m_BaseSystem;
|
||||||
CRSPRecompiler m_Recompiler;
|
CRSPRecompiler m_Recompiler;
|
||||||
RSPRegisterHandlerPlugin * m_RSPRegisterHandler;
|
RSPRegisterHandlerPlugin * m_RSPRegisterHandler;
|
||||||
CRSPRegisters m_Reg;
|
CRSPRegisters m_Reg;
|
||||||
|
@ -69,6 +81,7 @@ private:
|
||||||
uint32_t * m_DPC_PIPEBUSY_REG;
|
uint32_t * m_DPC_PIPEBUSY_REG;
|
||||||
uint32_t * m_DPC_TMEM_REG;
|
uint32_t * m_DPC_TMEM_REG;
|
||||||
uint32_t m_RdramSize;
|
uint32_t m_RdramSize;
|
||||||
|
uint32_t * m_SyncReg;
|
||||||
void (*CheckInterrupts)(void);
|
void (*CheckInterrupts)(void);
|
||||||
void (*ProcessDList)(void);
|
void (*ProcessDList)(void);
|
||||||
void (*ProcessRdpList)(void);
|
void (*ProcessRdpList)(void);
|
||||||
|
|
|
@ -179,9 +179,11 @@ void FixMenuState(void)
|
||||||
|
|
||||||
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_RECOMPILER, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::Recompiler ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_RECOMPILER, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::Recompiler ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_INTERPT, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::Interpreter ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_INTERPT, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::Interpreter ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
|
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_RECOMPILER_TASKS, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::RecompilerTasks ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_HLE, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::HighLevelEmulation ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_HLE, MF_BYCOMMAND | ((RSPCpuMethod)GetSetting(Set_CPUCore) == RSPCpuMethod::HighLevelEmulation ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | (BreakOnStart ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | (BreakOnStart ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | (LogRDP ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | (LogRDP ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
|
CheckMenuItem(hRSPMenu, ID_SETTINGS_SYNCCPU, MF_BYCOMMAND | (SyncCPU ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND | (HleAlistTask ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND | (HleAlistTask ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | (LogX86Code ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | (LogX86Code ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
CheckMenuItem(hRSPMenu, ID_SETTINGS_MULTITHREADED, MF_BYCOMMAND | (MultiThreadedDefault ? MFS_CHECKED : MF_UNCHECKED));
|
CheckMenuItem(hRSPMenu, ID_SETTINGS_MULTITHREADED, MF_BYCOMMAND | (MultiThreadedDefault ? MFS_CHECKED : MF_UNCHECKED));
|
||||||
|
@ -384,6 +386,13 @@ void ProcessMenuItem(int32_t ID)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ID_SETTINGS_SYNCCPU:
|
||||||
|
{
|
||||||
|
bool Checked = (GetMenuState(hRSPMenu, ID_SETTINGS_SYNCCPU, MF_BYCOMMAND) & MFS_CHECKED) != 0;
|
||||||
|
CheckMenuItem(hRSPMenu, ID_SETTINGS_SYNCCPU, MF_BYCOMMAND | (Checked ? MFS_UNCHECKED : MFS_CHECKED));
|
||||||
|
SetSetting(Set_SyncCPU, !Checked);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ID_SETTINGS_HLEALISTTASK:
|
case ID_SETTINGS_HLEALISTTASK:
|
||||||
{
|
{
|
||||||
bool Checked = (GetMenuState(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND) & MFS_CHECKED) != 0;
|
bool Checked = (GetMenuState(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND) & MFS_CHECKED) != 0;
|
||||||
|
@ -410,6 +419,10 @@ void ProcessMenuItem(int32_t ID)
|
||||||
SetSetting(Set_CPUCore, (int)RSPCpuMethod::Interpreter);
|
SetSetting(Set_CPUCore, (int)RSPCpuMethod::Interpreter);
|
||||||
FixMenuState();
|
FixMenuState();
|
||||||
break;
|
break;
|
||||||
|
case ID_CPUMETHOD_RECOMPILER_TASKS:
|
||||||
|
SetSetting(Set_CPUCore, (int)RSPCpuMethod::RecompilerTasks);
|
||||||
|
FixMenuState();
|
||||||
|
break;
|
||||||
case ID_CPUMETHOD_HLE:
|
case ID_CPUMETHOD_HLE:
|
||||||
SetSetting(Set_CPUCore, (int)RSPCpuMethod::HighLevelEmulation);
|
SetSetting(Set_CPUCore, (int)RSPCpuMethod::HighLevelEmulation);
|
||||||
FixMenuState();
|
FixMenuState();
|
||||||
|
@ -551,7 +564,6 @@ BOOL CALLBACK ConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam
|
||||||
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
|
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
|
||||||
ComboBox_AddString(hWndItem, "Interpreter");
|
ComboBox_AddString(hWndItem, "Interpreter");
|
||||||
ComboBox_AddString(hWndItem, "Recompiler");
|
ComboBox_AddString(hWndItem, "Recompiler");
|
||||||
//ComboBox_SetCurSel(hWndItem, g_CPUCore);
|
|
||||||
break;
|
break;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||||
|
@ -596,6 +608,7 @@ EXPORT void EnableDebugging(int Enabled)
|
||||||
IndvidualBlock = GetSetting(Set_IndvidualBlock) != 0;
|
IndvidualBlock = GetSetting(Set_IndvidualBlock) != 0;
|
||||||
ShowErrors = GetSetting(Set_ShowErrors) != 0;
|
ShowErrors = GetSetting(Set_ShowErrors) != 0;
|
||||||
HleAlistTask = GetSetting(Set_HleAlistTask) != 0;
|
HleAlistTask = GetSetting(Set_HleAlistTask) != 0;
|
||||||
|
SyncCPU = GetSetting(Set_SyncCPU) != 0;
|
||||||
|
|
||||||
Compiler.bDest = GetSetting(Set_CheckDest) != 0;
|
Compiler.bDest = GetSetting(Set_CheckDest) != 0;
|
||||||
Compiler.bAccum = GetSetting(Set_Accum) != 0;
|
Compiler.bAccum = GetSetting(Set_Accum) != 0;
|
||||||
|
|
|
@ -170,6 +170,7 @@ BEGIN
|
||||||
POPUP "CPU Method"
|
POPUP "CPU Method"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "Recompiler", ID_CPUMETHOD_RECOMPILER
|
MENUITEM "Recompiler", ID_CPUMETHOD_RECOMPILER
|
||||||
|
MENUITEM "Recompiler Tasks", ID_CPUMETHOD_RECOMPILER_TASKS
|
||||||
MENUITEM "Interpreter", ID_CPUMETHOD_INTERPT
|
MENUITEM "Interpreter", ID_CPUMETHOD_INTERPT
|
||||||
MENUITEM "HLE", ID_CPUMETHOD_HLE
|
MENUITEM "HLE", ID_CPUMETHOD_HLE
|
||||||
END
|
END
|
||||||
|
@ -196,6 +197,7 @@ BEGIN
|
||||||
MENUITEM "Break on start of task", ID_BREAKONSTARTOFTASK
|
MENUITEM "Break on start of task", ID_BREAKONSTARTOFTASK
|
||||||
MENUITEM "Log RDP Commands", ID_LOGRDPCOMMANDS
|
MENUITEM "Log RDP Commands", ID_LOGRDPCOMMANDS
|
||||||
MENUITEM "Log X86 code", ID_SETTINGS_LOGX86CODE
|
MENUITEM "Log X86 code", ID_SETTINGS_LOGX86CODE
|
||||||
|
MENUITEM "Sync CPU", ID_SETTINGS_SYNCCPU
|
||||||
MENUITEM "Multithreaded", ID_SETTINGS_MULTITHREADED
|
MENUITEM "Multithreaded", ID_SETTINGS_MULTITHREADED
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -40,13 +40,15 @@
|
||||||
#define ID_SETTINGS_MULTITHREADED 5020
|
#define ID_SETTINGS_MULTITHREADED 5020
|
||||||
#define ID_SETTINGS_HLEALISTTASK 5021
|
#define ID_SETTINGS_HLEALISTTASK 5021
|
||||||
#define ID_CPUMETHOD_HLE 5022
|
#define ID_CPUMETHOD_HLE 5022
|
||||||
|
#define ID_CPUMETHOD_RECOMPILER_TASKS 5023
|
||||||
|
#define ID_SETTINGS_SYNCCPU 5024
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 108
|
#define _APS_NEXT_RESOURCE_VALUE 108
|
||||||
#define _APS_NEXT_COMMAND_VALUE 5023
|
#define _APS_NEXT_COMMAND_VALUE 5025
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1032
|
#define _APS_NEXT_CONTROL_VALUE 1032
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue