RSP: Start to add CPU style HLE

This commit is contained in:
zilmar 2024-08-29 15:37:52 +09:30
parent 5eac210197
commit eb985de132
15 changed files with 211 additions and 171 deletions

View File

@ -0,0 +1,70 @@
#include <Project64-rsp-core/Hle/HleTask.h>
#include <Project64-rsp-core/cpu/RspSystem.h>
#include <zlib/zlib.h>
CHleTask::CHleTask(CRSPSystem & System) :
m_hle(System),
m_System(System),
m_SP_STATUS_REG(System.m_SP_STATUS_REG),
m_SP_PC_REG(System.m_SP_PC_REG),
m_DPC_STATUS_REG(System.m_DPC_STATUS_REG),
m_DMEM(System.m_DMEM),
m_IMEM(System.m_IMEM),
CheckInterrupts(System.CheckInterrupts),
ProcessDList(System.ProcessDList)
{
}
bool CHleTask::IsHleTask(void)
{
if ((*m_SP_PC_REG) != 0)
{
return false;
}
uint32_t ImemCrc = crc32(0L, m_IMEM, 0xCC);
if (ImemCrc == 0xcab15710 || // Super Mario
ImemCrc == 0x6f849879) // pokemon puzzle league
{
return true;
}
return false;
}
bool CHleTask::ProcessHleTask(void)
{
TASK_INFO & TaskInfo = *((TASK_INFO *)(m_DMEM + 0xFC0));
extern bool AudioHle, GraphicsHle;
if (((HLETaskType)TaskInfo.Type) == HLETaskType::Video && GraphicsHle && TaskInfo.DataPtr != 0)
{
if (ProcessDList != nullptr)
{
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();
}
*RSPInfo.DPC_STATUS_REG &= ~0x0002;
return true;
}
else if (TaskInfo.Type == 7)
{
RSPInfo.ShowCFB();
}
if (CRSPSettings::CPUMethod() == RSPCpuMethod::HighLevelEmulation && m_hle.try_fast_audio_dispatching())
{
*m_SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
if ((*m_SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
}
return true;
}
return false;
}

View File

@ -0,0 +1,59 @@
#pragma once
#include <Project64-rsp-core/Hle/hle.h>
#include <Project64-rsp-core/cpu/RspTypes.h>
#include <stdint.h>
class CRSPSystem;
class RSPRegisterHandlerPlugin;
class CHle;
class CHleTask
{
struct TASK_INFO
{
uint32_t Type;
uint32_t Flags;
uint32_t Boot;
uint32_t BootSize;
uint32_t Ucode;
uint32_t UcodeSize;
uint32_t UcodeData;
uint32_t UcodeDataSize;
uint32_t DramStack;
uint32_t DramStackSize;
uint32_t OutputBuff;
uint32_t OutputBuffSize;
uint32_t DataPtr;
uint32_t DataSize;
uint32_t YieldDataPtr;
uint32_t YieldDataSize;
};
enum class HLETaskType
{
Video = 1,
Audio = 2,
};
public:
CHleTask(CRSPSystem & System);
bool IsHleTask(void);
bool ProcessHleTask(void);
private:
CHleTask(void);
CHleTask(const CHleTask & copy);
CHleTask & operator=(const CHleTask & rhs);
void (*&CheckInterrupts)(void);
void (*&ProcessDList)(void);
CHle m_hle;
CRSPSystem & m_System;
uint32_t *& m_SP_STATUS_REG;
uint32_t *& m_SP_PC_REG;
uint32_t *& m_DPC_STATUS_REG;
uint8_t *& m_DMEM;
uint8_t *& m_IMEM;
};

View File

@ -7,6 +7,7 @@
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "hle.h"
#include <Project64-rsp-core/cpu/RspSystem.h>
#include <stdint.h>
#if defined(_WIN32) && defined(_DEBUG)
#include <Windows.h>
@ -21,33 +22,31 @@
static unsigned int sum_bytes(const uint8_t * bytes, uint32_t size);
CHle::CHle(const RSP_INFO & Rsp_Info) :
m_dram(Rsp_Info.RDRAM),
m_dmem(Rsp_Info.DMEM),
m_imem(Rsp_Info.IMEM),
m_mi_intr(Rsp_Info.MI_INTR_REG),
m_sp_mem_addr(Rsp_Info.SP_MEM_ADDR_REG),
m_sp_dram_addr(Rsp_Info.SP_DRAM_ADDR_REG),
m_sp_rd_length(Rsp_Info.SP_RD_LEN_REG),
m_sp_wr_length(Rsp_Info.SP_WR_LEN_REG),
m_sp_status(Rsp_Info.SP_STATUS_REG),
m_sp_dma_full(Rsp_Info.SP_DMA_FULL_REG),
m_sp_dma_busy(Rsp_Info.SP_DMA_BUSY_REG),
m_sp_pc(Rsp_Info.SP_PC_REG),
m_sp_semaphore(Rsp_Info.SP_SEMAPHORE_REG),
m_dpc_start(Rsp_Info.DPC_START_REG),
m_dpc_end(Rsp_Info.DPC_END_REG),
m_dpc_current(Rsp_Info.DPC_CURRENT_REG),
m_dpc_status(Rsp_Info.DPC_STATUS_REG),
m_dpc_clock(Rsp_Info.DPC_CLOCK_REG),
m_dpc_bufbusy(Rsp_Info.DPC_BUFBUSY_REG),
m_dpc_pipebusy(Rsp_Info.DPC_PIPEBUSY_REG),
m_dpc_tmem(Rsp_Info.DPC_TMEM_REG),
m_CheckInterrupts(Rsp_Info.CheckInterrupts),
m_ProcessDList(Rsp_Info.ProcessDList),
m_ProcessAList(Rsp_Info.ProcessAList),
m_ProcessRdpList(Rsp_Info.ProcessRdpList),
m_ShowCFB(Rsp_Info.ShowCFB),
CHle::CHle(CRSPSystem & System) :
m_dram(System.m_RDRAM),
m_dmem(System.m_DMEM),
m_imem(System.m_IMEM),
m_mi_intr(System.m_MI_INTR_REG),
m_sp_mem_addr(System.m_SP_MEM_ADDR_REG),
m_sp_dram_addr(System.m_SP_DRAM_ADDR_REG),
m_sp_rd_length(System.m_SP_RD_LEN_REG),
m_sp_wr_length(System.m_SP_WR_LEN_REG),
m_sp_status(System.m_SP_STATUS_REG),
m_sp_dma_full(System.m_SP_DMA_FULL_REG),
m_sp_dma_busy(System.m_SP_DMA_BUSY_REG),
m_sp_pc(System.m_SP_PC_REG),
m_sp_semaphore(System.m_SP_SEMAPHORE_REG),
m_dpc_start(System.m_DPC_START_REG),
m_dpc_end(System.m_DPC_END_REG),
m_dpc_current(System.m_DPC_CURRENT_REG),
m_dpc_status(System.m_DPC_STATUS_REG),
m_dpc_clock(System.m_DPC_CLOCK_REG),
m_dpc_bufbusy(System.m_DPC_BUFBUSY_REG),
m_dpc_pipebusy(System.m_DPC_PIPEBUSY_REG),
m_dpc_tmem(System.m_DPC_TMEM_REG),
m_CheckInterrupts(System.CheckInterrupts),
m_ProcessDList(System.ProcessDList),
m_ProcessRdpList(System.ProcessRdpList),
m_AudioHle(false),
m_GraphicsHle(true),
m_ForwardAudio(false),
@ -77,23 +76,6 @@ void CHle::rsp_break(unsigned int setbits)
}
}
void CHle::hle_execute(void)
{
if (is_task())
{
if (!try_fast_task_dispatching())
{
normal_task_dispatching();
}
rsp_break(SP_STATUS_SIG2);
}
else
{
non_task_dispatching();
rsp_break(0);
}
}
// Local functions
static unsigned int sum_bytes(const uint8_t * bytes, unsigned int size)
@ -126,36 +108,6 @@ bool CHle::is_task(void)
return (*dmem_u32(this, TASK_UCODE_BOOT_SIZE) <= 0x1000);
}
bool CHle::try_fast_task_dispatching(void)
{
// Identify task microcode by its type
switch (*dmem_u32(this, TASK_TYPE))
{
case 1:
if (m_ForwardGFX)
{
m_ProcessDList();
return true;
}
break;
case 2:
if (m_AudioHle)
{
m_ProcessAList();
return true;
}
else if (try_fast_audio_dispatching())
{
return true;
}
break;
case 7:
m_ShowCFB();
return true;
}
return false;
}
bool CHle::try_fast_audio_dispatching(void)
{
// Identify audio microcode by using the content of ucode_data

View File

@ -17,10 +17,12 @@
#define UNUSED(x) /* x */
#endif
class CRSPSystem;
class CHle
{
public:
CHle(const RSP_INFO & Rsp_Info);
CHle(CRSPSystem & System);
~CHle();
uint8_t * dram()
@ -71,7 +73,6 @@ public:
void ErrorMessage(const char * message, ...);
void rsp_break(uint32_t setbits);
void hle_execute(void);
bool try_fast_audio_dispatching(void);
@ -81,40 +82,37 @@ private:
CHle & operator=(const CHle &);
bool is_task(void);
bool try_fast_task_dispatching(void);
void normal_task_dispatching(void);
void non_task_dispatching(void);
uint8_t * m_dram;
uint8_t * m_dmem;
uint8_t * m_imem;
uint8_t *& m_dram;
uint8_t *& m_dmem;
uint8_t *& m_imem;
uint32_t * m_mi_intr;
uint32_t *& m_mi_intr;
uint32_t * m_sp_mem_addr;
uint32_t * m_sp_dram_addr;
uint32_t * m_sp_rd_length;
uint32_t * m_sp_wr_length;
uint32_t * m_sp_status;
uint32_t * m_sp_dma_full;
uint32_t * m_sp_dma_busy;
uint32_t * m_sp_pc;
uint32_t * m_sp_semaphore;
uint32_t *& m_sp_mem_addr;
uint32_t *& m_sp_dram_addr;
uint32_t *& m_sp_rd_length;
uint32_t *& m_sp_wr_length;
uint32_t *& m_sp_status;
uint32_t *& m_sp_dma_full;
uint32_t *& m_sp_dma_busy;
uint32_t *& m_sp_pc;
uint32_t *& m_sp_semaphore;
uint32_t * m_dpc_start;
uint32_t * m_dpc_end;
uint32_t * m_dpc_current;
uint32_t * m_dpc_status;
uint32_t * m_dpc_clock;
uint32_t * m_dpc_bufbusy;
uint32_t * m_dpc_pipebusy;
uint32_t * m_dpc_tmem;
uint32_t *& m_dpc_start;
uint32_t *& m_dpc_end;
uint32_t *& m_dpc_current;
uint32_t *& m_dpc_status;
uint32_t *& m_dpc_clock;
uint32_t *& m_dpc_bufbusy;
uint32_t *& m_dpc_pipebusy;
uint32_t *& m_dpc_tmem;
void (*m_CheckInterrupts)(void);
void (*m_ProcessDList)(void);
void (*m_ProcessAList)(void);
void (*m_ProcessRdpList)(void);
void (*m_ShowCFB)(void);
void (*&m_CheckInterrupts)(void);
void (*&m_ProcessDList)(void);
void (*&m_ProcessRdpList)(void);
// alist.cpp
uint8_t m_alist_buffer[0x1000];

View File

@ -58,6 +58,7 @@
<ClCompile Include="Hle\audio.cpp" />
<ClCompile Include="Hle\cicx105.cpp" />
<ClCompile Include="Hle\hle.cpp" />
<ClCompile Include="Hle\HleTask.cpp" />
<ClCompile Include="Hle\jpeg.cpp" />
<ClCompile Include="Hle\mem.cpp" />
<ClCompile Include="Hle\mp3.cpp" />
@ -92,6 +93,7 @@
<ClInclude Include="Hle\arithmetics.h" />
<ClInclude Include="Hle\audio.h" />
<ClInclude Include="Hle\hle.h" />
<ClInclude Include="Hle\HleTask.h" />
<ClInclude Include="Hle\mem.h" />
<ClInclude Include="Hle\ucodes.h" />
<ClInclude Include="Recompiler\RspProfiling.h" />

View File

@ -138,6 +138,9 @@
<ClCompile Include="cpu\RspSystem.cpp">
<Filter>Source Files\cpu</Filter>
</ClCompile>
<ClCompile Include="Hle\HleTask.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cpu\RSPInstruction.h">
@ -221,5 +224,8 @@
<ClInclude Include="cpu\RspPipelineStage.h">
<Filter>Header Files\cpu</Filter>
</ClInclude>
<ClInclude Include="Hle\HleTask.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,5 +1,4 @@
#include "RSPInfo.h"
#include <Project64-rsp-core/Hle/hle.h>
#include <Project64-rsp-core/Recompiler/RspProfiling.h>
#include <Project64-rsp-core/Recompiler/RspRecompilerCPU.h>
#include <Project64-rsp-core/Settings/RspSettings.h>
@ -17,7 +16,6 @@
RSP_INFO RSPInfo;
uint32_t RdramSize = 0;
CHle * g_hle = nullptr;
void ClearAllx86Code(void);
@ -122,12 +120,6 @@ void InitilizeRSP(RSP_INFO & Rsp_Info)
#ifdef GenerateLog
Start_Log();
#endif
if (g_hle != nullptr)
{
delete g_hle;
g_hle = nullptr;
}
}
void RspRomOpened(void)
@ -166,9 +158,4 @@ void RspRomClosed(void)
void FreeRSP(void)
{
FreeMemory();
if (g_hle != nullptr)
{
delete g_hle;
g_hle = nullptr;
}
}

View File

@ -3,7 +3,6 @@
class CHle;
extern RSP_INFO RSPInfo;
extern CHle * g_hle;
void InitilizeRSP(RSP_INFO & Rsp_Info);
void RspPluginLoaded(void);

View File

@ -9,6 +9,7 @@ enum class RSPCpuMethod
{
Interpreter = 0,
Recompiler = 1,
HighLevelEmulation = 2,
};
class CRSPSettings

View File

@ -1,6 +1,5 @@
#include "RSPCpu.h"
#include <Common/CriticalSection.h>
#include <Project64-rsp-core/Hle/hle.h>
#include <Project64-rsp-core/RSPDebugger.h>
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/Recompiler/RspRecompilerCPU.h>
@ -96,60 +95,10 @@ be greater than the number of cycles that the RSP should have performed.
uint32_t DoRspCycles(uint32_t Cycles)
{
extern bool AudioHle, GraphicsHle;
uint32_t TaskType = *(uint32_t *)(RSPInfo.DMEM + 0xFC0);
if (TaskType == 1 && GraphicsHle && *(uint32_t *)(RSPInfo.DMEM + 0x0ff0) != 0)
if (RSPSystem.IsHleTask() && RSPSystem.ProcessHleTask())
{
if (RSPInfo.ProcessDList != NULL)
{
RSPInfo.ProcessDList();
}
*RSPInfo.SP_STATUS_REG |= (0x0203);
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
}
*RSPInfo.DPC_STATUS_REG &= ~0x0002;
return Cycles;
}
else if (TaskType == 2 && HleAlistTask)
{
if (g_hle == nullptr)
{
g_hle = new CHle(RSPInfo);
}
if (g_hle != nullptr)
{
g_hle->try_fast_audio_dispatching();
*RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
}
}
}
else if (TaskType == 2 && AudioHle)
{
if (RSPInfo.ProcessAList != NULL)
{
RSPInfo.ProcessAList();
}
*RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
}
return Cycles;
}
else if (TaskType == 7)
{
RSPInfo.ShowCFB();
}
if (g_RSPDebugger != nullptr)
{
@ -163,6 +112,7 @@ uint32_t DoRspCycles(uint32_t Cycles)
RSPSystem.RunRecompiler();
break;
case RSPCpuMethod::Interpreter:
case RSPCpuMethod::HighLevelEmulation:
RSPSystem.RunInterpreterCPU(Cycles);
break;
}

View File

@ -10,6 +10,7 @@
CRSPSystem RSPSystem;
CRSPSystem::CRSPSystem() :
CHleTask(*this),
m_Recompiler(*this),
m_RSPRegisterHandler(nullptr),
m_Op(*this),
@ -38,6 +39,7 @@ CRSPSystem::CRSPSystem() :
m_DPC_PIPEBUSY_REG(nullptr),
m_DPC_TMEM_REG(nullptr),
CheckInterrupts(nullptr),
ProcessDList(nullptr),
ProcessRdpList(nullptr),
m_RdramSize(0)
{
@ -80,6 +82,7 @@ void CRSPSystem::Reset(RSP_INFO & Info)
m_DPC_PIPEBUSY_REG = Info.DPC_PIPEBUSY_REG;
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;

View File

@ -1,4 +1,5 @@
#pragma once
#include <Project64-rsp-core/Hle/HleTask.h>
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/Recompiler/RspRecompilerCPU.h>
#include <Project64-rsp-core/cpu/RSPInterpreterOps.h>
@ -9,15 +10,18 @@
class RSPRegisterHandlerPlugin;
class CRSPSystem
class CRSPSystem :
public CHleTask
{
friend class RSPOp;
friend class CRSPRecompilerOps;
friend class CRSPRecompiler;
friend class CHleTask;
friend class RSPDebuggerUI;
friend class CRDPLog;
friend class RSPRegisterHandler;
friend class RSPRegisterHandlerPlugin;
friend class CHle;
friend void UpdateRSPRegistersScreen(void);
@ -66,6 +70,7 @@ private:
uint32_t * m_DPC_TMEM_REG;
uint32_t m_RdramSize;
void (*CheckInterrupts)(void);
void (*ProcessDList)(void);
void (*ProcessRdpList)(void);
};

View File

@ -175,9 +175,11 @@ void FixMenuState(void)
EnableMenuItem(hRSPMenu, ID_DUMP_DMEM, MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_CPUMETHOD_RECOMPILER, MF_BYCOMMAND | (!CRSPSettings::RomOpen() ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_CPUMETHOD_INTERPT, MF_BYCOMMAND | (!CRSPSettings::RomOpen() ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_CPUMETHOD_HLE, MF_BYCOMMAND | (!CRSPSettings::RomOpen() ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
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_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_HLEALISTTASK, MF_BYCOMMAND | (HleAlistTask ? MFS_CHECKED : MF_UNCHECKED));
@ -408,6 +410,10 @@ void ProcessMenuItem(int32_t ID)
SetSetting(Set_CPUCore, (int)RSPCpuMethod::Interpreter);
FixMenuState();
break;
case ID_CPUMETHOD_HLE:
SetSetting(Set_CPUCore, (int)RSPCpuMethod::HighLevelEmulation);
FixMenuState();
break;
}
}
#endif

View File

@ -171,6 +171,7 @@ BEGIN
BEGIN
MENUITEM "Recompiler", ID_CPUMETHOD_RECOMPILER
MENUITEM "Interpreter", ID_CPUMETHOD_INTERPT
MENUITEM "HLE", ID_CPUMETHOD_HLE
END
MENUITEM SEPARATOR
POPUP "Pro&filing"

View File

@ -39,13 +39,14 @@
#define ID_SETTINGS_LOGX86CODE 5019
#define ID_SETTINGS_MULTITHREADED 5020
#define ID_SETTINGS_HLEALISTTASK 5021
#define ID_CPUMETHOD_HLE 5022
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 5022
#define _APS_NEXT_COMMAND_VALUE 5023
#define _APS_NEXT_CONTROL_VALUE 1032
#define _APS_NEXT_SYMED_VALUE 101
#endif