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/cpu/RSPRegisterHandlerPlugin.h>
|
||||
#include <Project64-rsp-core/cpu/RspMemory.h>
|
||||
#include <Project64-rsp-core/cpu/RspSystem.h>
|
||||
#include <zlib/zlib.h>
|
||||
|
||||
CHleTask::CHleTask(CRSPSystem & System) :
|
||||
CGPRRegisters(System.m_Reg.m_GPR),
|
||||
m_hle(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_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_SEMAPHORE_REG(System.m_SP_SEMAPHORE_REG),
|
||||
m_DPC_STATUS_REG(System.m_DPC_STATUS_REG),
|
||||
m_DMEM(System.m_DMEM),
|
||||
m_IMEM(System.m_IMEM),
|
||||
m_UcodeCRC(0),
|
||||
CheckInterrupts(System.CheckInterrupts),
|
||||
ProcessDList(System.ProcessDList)
|
||||
{
|
||||
|
@ -30,6 +40,200 @@ bool CHleTask::IsHleTask(void)
|
|||
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)
|
||||
{
|
||||
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 (ProcessDList != nullptr)
|
||||
if (ProcessDList == nullptr)
|
||||
{
|
||||
ProcessDList();
|
||||
return false;
|
||||
}
|
||||
ProcessDList();
|
||||
*m_SP_STATUS_REG |= (0x0203);
|
||||
if ((*m_SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
|
||||
{
|
||||
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
|
||||
RSPInfo.CheckInterrupts();
|
||||
*m_MI_INTR_REG |= MI_INTR_SP;
|
||||
CheckInterrupts();
|
||||
}
|
||||
|
||||
*RSPInfo.DPC_STATUS_REG &= ~0x0002;
|
||||
*m_DPC_STATUS_REG &= ~0x0002;
|
||||
return true;
|
||||
}
|
||||
else if (TaskInfo.Type == 7)
|
||||
|
@ -56,6 +260,30 @@ bool CHleTask::ProcessHleTask(void)
|
|||
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())
|
||||
{
|
||||
*m_SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
|
||||
|
|
|
@ -1,14 +1,23 @@
|
|||
#pragma once
|
||||
#include <Project64-rsp-core/Hle/hle.h>
|
||||
#include <Project64-rsp-core/cpu/RSPRegisters.h>
|
||||
#include <Project64-rsp-core/cpu/RspTypes.h>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
class CRSPSystem;
|
||||
class RSPRegisterHandlerPlugin;
|
||||
class CRSPRecompiler;
|
||||
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
|
||||
{
|
||||
uint32_t Type;
|
||||
|
@ -46,14 +55,27 @@ private:
|
|||
CHleTask(const CHleTask & copy);
|
||||
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 (*&ProcessDList)(void);
|
||||
|
||||
CHle m_hle;
|
||||
TaskFunctionMap m_FunctionMap;
|
||||
const TaskFunctions * m_TaskFunctions;
|
||||
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_DMA_FULL_REG;
|
||||
uint32_t *& m_SP_DMA_BUSY_REG;
|
||||
uint32_t *& m_SP_PC_REG;
|
||||
uint32_t *& m_SP_SEMAPHORE_REG;
|
||||
uint32_t *& m_DPC_STATUS_REG;
|
||||
uint8_t *& m_DMEM;
|
||||
uint8_t *& m_IMEM;
|
||||
uint32_t m_UcodeCRC;
|
||||
};
|
||||
|
|
|
@ -42,6 +42,7 @@ p_Recompfunc RSP_Recomp_Sc2[32];
|
|||
|
||||
CRSPRecompiler::CRSPRecompiler(CRSPSystem & System) :
|
||||
m_System(System),
|
||||
m_RecompilerOps(System, *this),
|
||||
m_RSPRegisterHandler(System.m_RSPRegisterHandler),
|
||||
m_CompilePC(0),
|
||||
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.
|
||||
*/
|
||||
|
||||
void BuildBranchLabels(void)
|
||||
void CRSPRecompiler::BuildBranchLabels(void)
|
||||
{
|
||||
RSPOpcode RspOp;
|
||||
uint32_t i, Dest;
|
||||
|
@ -810,8 +811,6 @@ void CRSPRecompiler::CompilerLinkBlocks(void)
|
|||
|
||||
void CRSPRecompiler::CompilerRSPBlock(void)
|
||||
{
|
||||
CRSPRecompilerOps RecompilerOps(RSPSystem, *this);
|
||||
|
||||
uint8_t * IMEM_SAVE = (uint8_t *)malloc(0x1000);
|
||||
const size_t X86BaseAddress = (size_t)RecompPos;
|
||||
m_NextInstruction = RSPPIPELINE_NORMAL;
|
||||
|
@ -877,7 +876,7 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
|||
|
||||
if (Compiler.bSections)
|
||||
{
|
||||
if (RecompilerOps.RSP_DoSections())
|
||||
if (m_RecompilerOps.RSP_DoSections())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -898,7 +897,7 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
(RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])();
|
||||
(m_RecompilerOps.*RSP_Recomp_Opcode[m_OpCode.op])();
|
||||
}
|
||||
|
||||
switch (m_NextInstruction)
|
||||
|
@ -910,6 +909,10 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
|||
m_NextInstruction = RSPPIPELINE_DELAY_SLOT;
|
||||
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);
|
||||
|
@ -918,6 +921,10 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
|||
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;
|
||||
|
@ -940,7 +947,9 @@ void CRSPRecompiler::CompilerRSPBlock(void)
|
|||
CompilerLinkBlocks();
|
||||
}
|
||||
break;
|
||||
|
||||
case RSPPIPELINE_FINISH_TASK_SUB_BLOCK:
|
||||
m_NextInstruction = RSPPIPELINE_FINISH_BLOCK;
|
||||
break;
|
||||
case RSPPIPELINE_FINISH_BLOCK: break;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
if (m_CurrentBlock.ResolveCount >= 150)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <Project64-rsp-core/Recompiler/RspRecompilerOps.h>
|
||||
#include <Project64-rsp-core/Settings/RspSettings.h>
|
||||
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
||||
#include <Project64-rsp-core/cpu/RspPipelineStage.h>
|
||||
|
@ -12,6 +13,7 @@ class RSPRegisterHandlerPlugin;
|
|||
class CRSPRecompiler
|
||||
{
|
||||
friend class CRSPRecompilerOps;
|
||||
friend class CHleTask;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -38,15 +40,18 @@ private:
|
|||
CRSPRecompiler(const CRSPRecompiler &);
|
||||
CRSPRecompiler & operator=(const CRSPRecompiler &);
|
||||
|
||||
void BuildBranchLabels(void);
|
||||
void BuildRecompilerCPU(void);
|
||||
void CompilerLinkBlocks(void);
|
||||
void CompilerRSPBlock(void);
|
||||
void CompileHLETask(uint32_t Address);
|
||||
void LinkBranches(RSP_BLOCK * Block);
|
||||
void ReOrderSubBlock(RSP_BLOCK * Block);
|
||||
void ReOrderInstructions(uint32_t StartPC, uint32_t EndPC);
|
||||
void ResetJumpTables(void);
|
||||
|
||||
CRSPSystem & m_System;
|
||||
CRSPRecompilerOps m_RecompilerOps;
|
||||
RSPRegisterHandlerPlugin *& m_RSPRegisterHandler;
|
||||
RSPOpcode & m_OpCode;
|
||||
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());
|
||||
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)
|
||||
{
|
||||
|
@ -175,10 +179,10 @@ void CRSPRecompilerOps::J(void)
|
|||
m_Recompiler.Branch_AddRef((m_OpCode.target << 2) & 0xFFC, (uint32_t *)(RecompPos - 4));
|
||||
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");
|
||||
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();
|
||||
}
|
||||
else
|
||||
|
@ -1494,17 +1498,14 @@ void CRSPRecompilerOps::Special_JR(void)
|
|||
TestX86RegToX86Reg(x86_EAX, x86_EAX);
|
||||
JeLabel8("Null", 0);
|
||||
Jump = RecompPos - 1;
|
||||
|
||||
// Before we branch quickly update our stats
|
||||
/*if (m_CompilePC == 0x080) {
|
||||
Pushad();
|
||||
Call_Direct((void *)UpdateAudioTimer, "UpdateAudioTimer");
|
||||
Popad();
|
||||
}*/
|
||||
JumpX86Reg(x86_EAX);
|
||||
|
||||
x86_SetBranch8b(Jump, RecompPos);
|
||||
CPU_Message(" Null:");
|
||||
if (CRSPSettings::CPUMethod() == RSPCpuMethod::HighLevelEmulation)
|
||||
{
|
||||
BreakPoint();
|
||||
}
|
||||
Ret();
|
||||
ChangedPC = false;
|
||||
m_NextInstruction = RSPPIPELINE_FINISH_SUB_BLOCK;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// Opcode functions
|
||||
#pragma once
|
||||
#include <Project64-rsp-core/cpu/RSPInterpreterOps.h>
|
||||
|
||||
class CRSPSystem;
|
||||
class CRSPRegisters;
|
||||
class CRSPRecompiler;
|
||||
|
||||
class CRSPRecompilerOps
|
||||
{
|
||||
|
@ -11,6 +12,11 @@ class CRSPRecompilerOps
|
|||
HIT_BRANCH = 0x2,
|
||||
};
|
||||
|
||||
enum EndHleTaskOp
|
||||
{
|
||||
J_0x1118 = 0x09000446
|
||||
};
|
||||
|
||||
public:
|
||||
CRSPRecompilerOps(CRSPSystem & System, CRSPRecompiler & Recompiler);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ RSPCpuMethod CRSPSettings::m_CPUMethod = RSPCpuMethod::Interpreter;
|
|||
#endif
|
||||
|
||||
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;
|
||||
|
||||
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_ShowErrors, Data_DWORD_General, "Show Errors", NULL, ShowErrors, 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
|
||||
RegisterSetting(Set_CheckDest, Data_DWORD_General, "Check Destination Vector", NULL, Compiler.bDest, NULL);
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
#include <stdint.h>
|
||||
|
||||
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;
|
||||
|
||||
enum class RSPCpuMethod
|
||||
{
|
||||
Interpreter = 0,
|
||||
Recompiler = 1,
|
||||
HighLevelEmulation = 2,
|
||||
RecompilerTasks = 2,
|
||||
HighLevelEmulation = 3,
|
||||
};
|
||||
|
||||
class CRSPSettings
|
||||
|
|
|
@ -10,6 +10,7 @@ enum
|
|||
Set_IndvidualBlock,
|
||||
Set_ShowErrors,
|
||||
Set_HleAlistTask,
|
||||
Set_SyncCPU,
|
||||
|
||||
// Compiler settings
|
||||
Set_CheckDest,
|
||||
|
|
|
@ -112,6 +112,7 @@ uint32_t DoRspCycles(uint32_t Cycles)
|
|||
RSPSystem.RunRecompiler();
|
||||
break;
|
||||
case RSPCpuMethod::Interpreter:
|
||||
case RSPCpuMethod::RecompilerTasks:
|
||||
case RSPCpuMethod::HighLevelEmulation:
|
||||
RSPSystem.ExecuteOps((uint32_t)-1, (uint32_t)-1);
|
||||
break;
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
extern bool AudioHle, GraphicsHle;
|
||||
|
||||
uint32_t clz32(uint32_t val)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include <Project64-rsp-core/Settings/RspSettings.h>
|
||||
#include <Project64-rsp-core/cpu/RSPOpcode.h>
|
||||
#include <Project64-rsp-core/cpu/RspPipelineStage.h>
|
||||
#include <Project64-rsp-core/cpu/RspTypes.h>
|
||||
|
@ -12,6 +13,7 @@ class RSPOp :
|
|||
{
|
||||
friend class CRSPSystem;
|
||||
friend class CRSPRecompilerOps;
|
||||
friend class CHleTask;
|
||||
|
||||
public:
|
||||
RSPOp(CRSPSystem & System);
|
||||
|
|
|
@ -37,6 +37,42 @@ const char * GPR_Strings[32] = {
|
|||
"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() :
|
||||
VCOL(m_Flags[0].UB[0]),
|
||||
VCOH(m_Flags[0].UB[1]),
|
||||
|
|
|
@ -20,7 +20,8 @@ RSPRegisterHandler::RSPRegisterHandler(uint32_t * SignalProcessorInterface, uint
|
|||
m_IMEM(IMEM),
|
||||
m_DMEM(DMEM),
|
||||
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_DMEM(System.m_DMEM),
|
||||
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;
|
||||
}
|
||||
if (CopyAmount > 0)
|
||||
if (CopyAmount > 0 && !m_IgnoreWrites)
|
||||
{
|
||||
memcpy(&Dest[WritePos], &Source[Pos], CopyAmount);
|
||||
}
|
||||
|
@ -183,7 +185,7 @@ void RSPRegisterHandler::SP_DMA_WRITE()
|
|||
{
|
||||
CopyAmount = CopyLength;
|
||||
}
|
||||
if (CopyAmount > 0)
|
||||
if (CopyAmount > 0 && !m_IgnoreWrites)
|
||||
{
|
||||
memcpy(&Dest[WritePos], &Source[Pos], CopyAmount);
|
||||
}
|
||||
|
|
|
@ -63,4 +63,5 @@ protected:
|
|||
uint8_t * m_DMEM;
|
||||
uint32_t m_PendingSPMemAddr;
|
||||
uint32_t m_PendingSPDramAddr;
|
||||
bool m_IgnoreWrites;
|
||||
};
|
||||
|
|
|
@ -71,6 +71,49 @@ enum
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -2,15 +2,20 @@
|
|||
|
||||
enum RSPPIPELINE_STAGE
|
||||
{
|
||||
RSPPIPELINE_NORMAL = 0,
|
||||
RSPPIPELINE_DO_DELAY_SLOT = 1,
|
||||
RSPPIPELINE_DELAY_SLOT = 2,
|
||||
RSPPIPELINE_DELAY_SLOT_DONE = 3,
|
||||
RSPPIPELINE_DELAY_SLOT_EXIT = 4,
|
||||
RSPPIPELINE_DELAY_SLOT_EXIT_DONE = 5,
|
||||
RSPPIPELINE_JUMP = 6,
|
||||
RSPPIPELINE_SINGLE_STEP = 7,
|
||||
RSPPIPELINE_SINGLE_STEP_DONE = 8,
|
||||
RSPPIPELINE_FINISH_BLOCK = 9,
|
||||
RSPPIPELINE_FINISH_SUB_BLOCK = 10,
|
||||
RSPPIPELINE_NORMAL,
|
||||
RSPPIPELINE_DO_DELAY_SLOT,
|
||||
RSPPIPELINE_DO_DELAY_SLOT_EXIT,
|
||||
RSPPIPELINE_DO_DELAY_SLOT_TASK_EXIT,
|
||||
RSPPIPELINE_DELAY_SLOT,
|
||||
RSPPIPELINE_DELAY_SLOT_DONE,
|
||||
RSPPIPELINE_DELAY_SLOT_EXIT,
|
||||
RSPPIPELINE_DELAY_SLOT_EXIT_DONE,
|
||||
RSPPIPELINE_DELAY_SLOT_TASK_EXIT,
|
||||
RSPPIPELINE_DELAY_SLOT_TASK_EXIT_DONE,
|
||||
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() :
|
||||
CHleTask(*this),
|
||||
m_SyncSystem(nullptr),
|
||||
m_BaseSystem(nullptr),
|
||||
m_Recompiler(*this),
|
||||
m_RSPRegisterHandler(nullptr),
|
||||
m_Op(*this),
|
||||
|
@ -38,9 +40,10 @@ CRSPSystem::CRSPSystem() :
|
|||
m_DPC_BUFBUSY_REG(nullptr),
|
||||
m_DPC_PIPEBUSY_REG(nullptr),
|
||||
m_DPC_TMEM_REG(nullptr),
|
||||
CheckInterrupts(nullptr),
|
||||
ProcessDList(nullptr),
|
||||
ProcessRdpList(nullptr),
|
||||
CheckInterrupts(NullCheckInterrupts),
|
||||
ProcessDList(NullProcessDList),
|
||||
ProcessRdpList(NullProcessRdpList),
|
||||
m_SyncReg(nullptr),
|
||||
m_RdramSize(0)
|
||||
{
|
||||
m_OpCode.Value = 0;
|
||||
|
@ -48,6 +51,29 @@ 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)
|
||||
{
|
||||
delete m_RSPRegisterHandler;
|
||||
|
@ -61,6 +87,9 @@ void CRSPSystem::Reset(RSP_INFO & Info)
|
|||
|
||||
m_HEADER = Info.HEADER;
|
||||
m_RDRAM = Info.RDRAM;
|
||||
|
||||
if (m_BaseSystem == nullptr)
|
||||
{
|
||||
m_DMEM = Info.DMEM;
|
||||
m_IMEM = Info.IMEM;
|
||||
m_MI_INTR_REG = Info.MI_INTR_REG;
|
||||
|
@ -84,6 +113,7 @@ void CRSPSystem::Reset(RSP_INFO & Info)
|
|||
CheckInterrupts = Info.CheckInterrupts;
|
||||
ProcessDList = Info.ProcessDList;
|
||||
ProcessRdpList = Info.ProcessRdpList;
|
||||
}
|
||||
|
||||
m_RdramSize = Set_AllocatedRdramSize != 0 ? GetSystemSetting(Set_AllocatedRdramSize) : 0;
|
||||
if (m_RdramSize == 0)
|
||||
|
@ -91,6 +121,11 @@ void CRSPSystem::Reset(RSP_INFO & Info)
|
|||
m_RdramSize = 0x00400000;
|
||||
}
|
||||
m_RSPRegisterHandler = new RSPRegisterHandlerPlugin(*this);
|
||||
|
||||
if (m_SyncSystem != nullptr)
|
||||
{
|
||||
m_SyncSystem->Reset(Info);
|
||||
}
|
||||
}
|
||||
|
||||
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 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:
|
||||
CRSPSystem(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;
|
||||
RSPRegisterHandlerPlugin * m_RSPRegisterHandler;
|
||||
CRSPRegisters m_Reg;
|
||||
|
@ -69,6 +81,7 @@ private:
|
|||
uint32_t * m_DPC_PIPEBUSY_REG;
|
||||
uint32_t * m_DPC_TMEM_REG;
|
||||
uint32_t m_RdramSize;
|
||||
uint32_t * m_SyncReg;
|
||||
void (*CheckInterrupts)(void);
|
||||
void (*ProcessDList)(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_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_BREAKONSTARTOFTASK, MF_BYCOMMAND | (BreakOnStart ? 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_LOGX86CODE, MF_BYCOMMAND | (LogX86Code ? 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;
|
||||
}
|
||||
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:
|
||||
{
|
||||
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);
|
||||
FixMenuState();
|
||||
break;
|
||||
case ID_CPUMETHOD_RECOMPILER_TASKS:
|
||||
SetSetting(Set_CPUCore, (int)RSPCpuMethod::RecompilerTasks);
|
||||
FixMenuState();
|
||||
break;
|
||||
case ID_CPUMETHOD_HLE:
|
||||
SetSetting(Set_CPUCore, (int)RSPCpuMethod::HighLevelEmulation);
|
||||
FixMenuState();
|
||||
|
@ -551,7 +564,6 @@ BOOL CALLBACK ConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam
|
|||
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
|
||||
ComboBox_AddString(hWndItem, "Interpreter");
|
||||
ComboBox_AddString(hWndItem, "Recompiler");
|
||||
//ComboBox_SetCurSel(hWndItem, g_CPUCore);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
||||
|
@ -596,6 +608,7 @@ EXPORT void EnableDebugging(int Enabled)
|
|||
IndvidualBlock = GetSetting(Set_IndvidualBlock) != 0;
|
||||
ShowErrors = GetSetting(Set_ShowErrors) != 0;
|
||||
HleAlistTask = GetSetting(Set_HleAlistTask) != 0;
|
||||
SyncCPU = GetSetting(Set_SyncCPU) != 0;
|
||||
|
||||
Compiler.bDest = GetSetting(Set_CheckDest) != 0;
|
||||
Compiler.bAccum = GetSetting(Set_Accum) != 0;
|
||||
|
|
|
@ -170,6 +170,7 @@ BEGIN
|
|||
POPUP "CPU Method"
|
||||
BEGIN
|
||||
MENUITEM "Recompiler", ID_CPUMETHOD_RECOMPILER
|
||||
MENUITEM "Recompiler Tasks", ID_CPUMETHOD_RECOMPILER_TASKS
|
||||
MENUITEM "Interpreter", ID_CPUMETHOD_INTERPT
|
||||
MENUITEM "HLE", ID_CPUMETHOD_HLE
|
||||
END
|
||||
|
@ -196,6 +197,7 @@ BEGIN
|
|||
MENUITEM "Break on start of task", ID_BREAKONSTARTOFTASK
|
||||
MENUITEM "Log RDP Commands", ID_LOGRDPCOMMANDS
|
||||
MENUITEM "Log X86 code", ID_SETTINGS_LOGX86CODE
|
||||
MENUITEM "Sync CPU", ID_SETTINGS_SYNCCPU
|
||||
MENUITEM "Multithreaded", ID_SETTINGS_MULTITHREADED
|
||||
END
|
||||
END
|
||||
|
|
|
@ -40,13 +40,15 @@
|
|||
#define ID_SETTINGS_MULTITHREADED 5020
|
||||
#define ID_SETTINGS_HLEALISTTASK 5021
|
||||
#define ID_CPUMETHOD_HLE 5022
|
||||
#define ID_CPUMETHOD_RECOMPILER_TASKS 5023
|
||||
#define ID_SETTINGS_SYNCCPU 5024
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#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_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue