mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
Clang format
This commit is contained in:
parent
2efab18cb5
commit
acf75535ec
707 changed files with 21870 additions and 21827 deletions
|
@ -1,13 +1,12 @@
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include "PathUtils.h"
|
#include "PathUtils.h"
|
||||||
|
|
||||||
#define BASE_DATA_PATH (L"Play Data Files")
|
#define BASE_DATA_PATH (L"Play Data Files")
|
||||||
#define CONFIG_FILENAME (L"config.xml")
|
#define CONFIG_FILENAME (L"config.xml")
|
||||||
|
|
||||||
CAppConfig::CAppConfig()
|
CAppConfig::CAppConfig()
|
||||||
: CConfig(BuildConfigPath())
|
: CConfig(BuildConfigPath())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Framework::CConfig::PathType CAppConfig::GetBasePath()
|
Framework::CConfig::PathType CAppConfig::GetBasePath()
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
class CAppConfig : public Framework::CConfig, public CSingleton<CAppConfig>
|
class CAppConfig : public Framework::CConfig, public CSingleton<CAppConfig>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CAppConfig();
|
CAppConfig();
|
||||||
virtual ~CAppConfig() = default;
|
virtual ~CAppConfig() = default;
|
||||||
|
|
||||||
static CConfig::PathType GetBasePath();
|
static CConfig::PathType GetBasePath();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static CConfig::PathType BuildConfigPath();
|
static CConfig::PathType BuildConfigPath();
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,12 +26,13 @@
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct AOT_BLOCK
|
struct AOT_BLOCK
|
||||||
{
|
{
|
||||||
AOT_BLOCK_KEY key;
|
AOT_BLOCK_KEY key;
|
||||||
void* fct;
|
void* fct;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
extern AOT_BLOCK _aot_firstBlock;
|
extern AOT_BLOCK _aot_firstBlock;
|
||||||
extern uint32 _aot_blockCount;
|
extern uint32 _aot_blockCount;
|
||||||
}
|
}
|
||||||
|
@ -39,11 +40,11 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
|
CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
|
||||||
: m_begin(begin)
|
: m_begin(begin)
|
||||||
, m_end(end)
|
, m_end(end)
|
||||||
, m_context(context)
|
, m_context(context)
|
||||||
#ifdef AOT_USE_CACHE
|
#ifdef AOT_USE_CACHE
|
||||||
, m_function(nullptr)
|
, m_function(nullptr)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
assert(m_end >= m_begin);
|
assert(m_end >= m_begin);
|
||||||
|
@ -51,8 +52,8 @@ CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
|
||||||
|
|
||||||
#ifdef AOT_BUILD_CACHE
|
#ifdef AOT_BUILD_CACHE
|
||||||
|
|
||||||
Framework::CStdStream* CBasicBlock::m_aotBlockOutputStream(nullptr);
|
Framework::CStdStream* CBasicBlock::m_aotBlockOutputStream(nullptr);
|
||||||
std::mutex CBasicBlock::m_aotBlockOutputStreamMutex;
|
std::mutex CBasicBlock::m_aotBlockOutputStreamMutex;
|
||||||
|
|
||||||
void CBasicBlock::SetAotBlockOutputStream(Framework::CStdStream* outputStream)
|
void CBasicBlock::SetAotBlockOutputStream(Framework::CStdStream* outputStream)
|
||||||
{
|
{
|
||||||
|
@ -70,9 +71,9 @@ void CBasicBlock::Compile()
|
||||||
{
|
{
|
||||||
static
|
static
|
||||||
#ifdef AOT_BUILD_CACHE
|
#ifdef AOT_BUILD_CACHE
|
||||||
__declspec(thread)
|
__declspec(thread)
|
||||||
#endif
|
#endif
|
||||||
CMipsJitter* jitter = nullptr;
|
CMipsJitter* jitter = nullptr;
|
||||||
if(jitter == nullptr)
|
if(jitter == nullptr)
|
||||||
{
|
{
|
||||||
Jitter::CCodeGen* codeGen = Jitter::CreateCodeGen();
|
Jitter::CCodeGen* codeGen = Jitter::CreateCodeGen();
|
||||||
|
@ -81,22 +82,21 @@ void CBasicBlock::Compile()
|
||||||
for(unsigned int i = 0; i < 4; i++)
|
for(unsigned int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
jitter->SetVariableAsConstant(
|
jitter->SetVariableAsConstant(
|
||||||
offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]),
|
offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]),
|
||||||
0
|
0);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jitter->SetStream(&stream);
|
jitter->SetStream(&stream);
|
||||||
jitter->Begin();
|
jitter->Begin();
|
||||||
CompileRange(jitter);
|
CompileRange(jitter);
|
||||||
// codeGen.DumpVariables(0);
|
// codeGen.DumpVariables(0);
|
||||||
// codeGen.EndQuota();
|
// codeGen.EndQuota();
|
||||||
jitter->End();
|
jitter->End();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_function = CMemoryFunction(stream.GetBuffer(), stream.GetSize());
|
m_function = CMemoryFunction(stream.GetBuffer(), stream.GetSize());
|
||||||
|
|
||||||
#ifdef VTUNE_ENABLED
|
#ifdef VTUNE_ENABLED
|
||||||
if(iJIT_IsProfilingActive() == iJIT_SAMPLING_ON)
|
if(iJIT_IsProfilingActive() == iJIT_SAMPLING_ON)
|
||||||
{
|
{
|
||||||
|
@ -137,19 +137,18 @@ void CBasicBlock::Compile()
|
||||||
AOT_BLOCK* blocksBegin = &_aot_firstBlock;
|
AOT_BLOCK* blocksBegin = &_aot_firstBlock;
|
||||||
AOT_BLOCK* blocksEnd = blocksBegin + _aot_blockCount;
|
AOT_BLOCK* blocksEnd = blocksBegin + _aot_blockCount;
|
||||||
|
|
||||||
AOT_BLOCK blockRef = { blockChecksum, m_begin, m_end, nullptr };
|
AOT_BLOCK blockRef = {blockChecksum, m_begin, m_end, nullptr};
|
||||||
|
|
||||||
static const auto blockComparer =
|
static const auto blockComparer =
|
||||||
[] (const AOT_BLOCK& item1, const AOT_BLOCK& item2)
|
[](const AOT_BLOCK& item1, const AOT_BLOCK& item2) {
|
||||||
{
|
return item1.key < item2.key;
|
||||||
return item1.key < item2.key;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
// assert(std::is_sorted(blocksBegin, blocksEnd, blockComparer));
|
// assert(std::is_sorted(blocksBegin, blocksEnd, blockComparer));
|
||||||
|
|
||||||
bool blockExists = std::binary_search(blocksBegin, blocksEnd, blockRef, blockComparer);
|
bool blockExists = std::binary_search(blocksBegin, blocksEnd, blockRef, blockComparer);
|
||||||
auto blockIterator = std::lower_bound(blocksBegin, blocksEnd, blockRef, blockComparer);
|
auto blockIterator = std::lower_bound(blocksBegin, blocksEnd, blockRef, blockComparer);
|
||||||
|
|
||||||
assert(blockExists);
|
assert(blockExists);
|
||||||
assert(blockIterator != blocksEnd);
|
assert(blockIterator != blocksEnd);
|
||||||
assert(blockIterator->key.crc == blockChecksum);
|
assert(blockIterator->key.crc == blockChecksum);
|
||||||
|
@ -192,9 +191,9 @@ void CBasicBlock::CompileRange(CMipsJitter* jitter)
|
||||||
for(uint32 address = m_begin; address <= fixedEnd; address += 4)
|
for(uint32 address = m_begin; address <= fixedEnd; address += 4)
|
||||||
{
|
{
|
||||||
m_context.m_pArch->CompileInstruction(
|
m_context.m_pArch->CompileInstruction(
|
||||||
address,
|
address,
|
||||||
jitter,
|
jitter,
|
||||||
&m_context);
|
&m_context);
|
||||||
//Sanity check
|
//Sanity check
|
||||||
assert(jitter->IsStackEmpty());
|
assert(jitter->IsStackEmpty());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
|
|
||||||
struct AOT_BLOCK_KEY
|
struct AOT_BLOCK_KEY
|
||||||
{
|
{
|
||||||
uint32 crc;
|
uint32 crc;
|
||||||
uint32 begin;
|
uint32 begin;
|
||||||
uint32 end;
|
uint32 end;
|
||||||
|
|
||||||
bool operator <(const AOT_BLOCK_KEY& k2) const
|
bool operator<(const AOT_BLOCK_KEY& k2) const
|
||||||
{
|
{
|
||||||
const auto& k1 = (*this);
|
const auto& k1 = (*this);
|
||||||
if(k1.crc == k2.crc)
|
if(k1.crc == k2.crc)
|
||||||
|
@ -43,36 +43,35 @@ namespace Jitter
|
||||||
class CBasicBlock
|
class CBasicBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CBasicBlock(CMIPS&, uint32, uint32);
|
CBasicBlock(CMIPS&, uint32, uint32);
|
||||||
virtual ~CBasicBlock() = default;
|
virtual ~CBasicBlock() = default;
|
||||||
unsigned int Execute();
|
unsigned int Execute();
|
||||||
void Compile();
|
void Compile();
|
||||||
|
|
||||||
uint32 GetBeginAddress() const;
|
uint32 GetBeginAddress() const;
|
||||||
uint32 GetEndAddress() const;
|
uint32 GetEndAddress() const;
|
||||||
bool IsCompiled() const;
|
bool IsCompiled() const;
|
||||||
|
|
||||||
#ifdef AOT_BUILD_CACHE
|
#ifdef AOT_BUILD_CACHE
|
||||||
static void SetAotBlockOutputStream(Framework::CStdStream*);
|
static void SetAotBlockOutputStream(Framework::CStdStream*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 m_begin;
|
uint32 m_begin;
|
||||||
uint32 m_end;
|
uint32 m_end;
|
||||||
CMIPS& m_context;
|
CMIPS& m_context;
|
||||||
|
|
||||||
virtual void CompileRange(CMipsJitter*);
|
virtual void CompileRange(CMipsJitter*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifdef AOT_BUILD_CACHE
|
#ifdef AOT_BUILD_CACHE
|
||||||
static Framework::CStdStream* m_aotBlockOutputStream;
|
static Framework::CStdStream* m_aotBlockOutputStream;
|
||||||
static std::mutex m_aotBlockOutputStreamMutex;
|
static std::mutex m_aotBlockOutputStreamMutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef AOT_USE_CACHE
|
#ifndef AOT_USE_CACHE
|
||||||
CMemoryFunction m_function;
|
CMemoryFunction m_function;
|
||||||
#else
|
#else
|
||||||
void (*m_function)(void*);
|
void (*m_function)(void*);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
struct BIOS_DEBUG_MODULE_INFO
|
struct BIOS_DEBUG_MODULE_INFO
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
uint32 begin;
|
uint32 begin;
|
||||||
uint32 end;
|
uint32 end;
|
||||||
void* param;
|
void* param;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<BIOS_DEBUG_MODULE_INFO> BiosDebugModuleInfoArray;
|
typedef std::vector<BIOS_DEBUG_MODULE_INFO> BiosDebugModuleInfoArray;
|
||||||
|
@ -18,12 +18,12 @@ typedef BiosDebugModuleInfoArray::iterator BiosDebugModuleInfoIterator;
|
||||||
|
|
||||||
struct BIOS_DEBUG_THREAD_INFO
|
struct BIOS_DEBUG_THREAD_INFO
|
||||||
{
|
{
|
||||||
uint32 id;
|
uint32 id;
|
||||||
uint32 priority;
|
uint32 priority;
|
||||||
uint32 pc;
|
uint32 pc;
|
||||||
uint32 ra;
|
uint32 ra;
|
||||||
uint32 sp;
|
uint32 sp;
|
||||||
std::string stateDescription;
|
std::string stateDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<BIOS_DEBUG_THREAD_INFO> BiosDebugThreadInfoArray;
|
typedef std::vector<BIOS_DEBUG_THREAD_INFO> BiosDebugThreadInfoArray;
|
||||||
|
@ -31,10 +31,12 @@ typedef std::vector<BIOS_DEBUG_THREAD_INFO> BiosDebugThreadInfoArray;
|
||||||
class CBiosDebugInfoProvider
|
class CBiosDebugInfoProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~CBiosDebugInfoProvider() {}
|
virtual ~CBiosDebugInfoProvider()
|
||||||
|
{
|
||||||
|
}
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
virtual BiosDebugModuleInfoArray GetModulesDebugInfo() const = 0;
|
virtual BiosDebugModuleInfoArray GetModulesDebugInfo() const = 0;
|
||||||
virtual BiosDebugThreadInfoArray GetThreadsDebugInfo() const = 0;
|
virtual BiosDebugThreadInfoArray GetThreadsDebugInfo() const = 0;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
#include "MemoryUtils.h"
|
#include "MemoryUtils.h"
|
||||||
|
|
||||||
const uint32 CCOP_FPU::m_ccMask[8] =
|
const uint32 CCOP_FPU::m_ccMask[8] =
|
||||||
{
|
{
|
||||||
0x00800000,
|
0x00800000,
|
||||||
0x02000000,
|
0x02000000,
|
||||||
0x04000000,
|
0x04000000,
|
||||||
0x08000000,
|
0x08000000,
|
||||||
0x10000000,
|
0x10000000,
|
||||||
0x20000000,
|
0x20000000,
|
||||||
0x40000000,
|
0x40000000,
|
||||||
0x80000000
|
0x80000000};
|
||||||
};
|
|
||||||
|
|
||||||
CCOP_FPU::CCOP_FPU(MIPS_REGSIZE regSize)
|
CCOP_FPU::CCOP_FPU(MIPS_REGSIZE regSize)
|
||||||
: CMIPSCoprocessor(regSize)
|
: CMIPSCoprocessor(regSize)
|
||||||
{
|
{
|
||||||
SetupReflectionTables();
|
SetupReflectionTables();
|
||||||
}
|
}
|
||||||
|
|
158
Source/COP_FPU.h
158
Source/COP_FPU.h
|
@ -6,108 +6,108 @@
|
||||||
class CCOP_FPU : public CMIPSCoprocessor
|
class CCOP_FPU : public CMIPSCoprocessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCOP_FPU(MIPS_REGSIZE);
|
CCOP_FPU(MIPS_REGSIZE);
|
||||||
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override;
|
void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override;
|
||||||
void GetInstruction(uint32, char*) override;
|
void GetInstruction(uint32, char*) override;
|
||||||
void GetArguments(uint32, uint32, char*) override;
|
void GetArguments(uint32, uint32, char*) override;
|
||||||
uint32 GetEffectiveAddress(uint32, uint32) override;
|
uint32 GetEffectiveAddress(uint32, uint32) override;
|
||||||
MIPS_BRANCH_TYPE IsBranch(uint32) override;
|
MIPS_BRANCH_TYPE IsBranch(uint32) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetupReflectionTables();
|
void SetupReflectionTables();
|
||||||
|
|
||||||
static void ReflOpRtFs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtFs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRtFcs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtFcs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpFdFs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpFdFs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpFdFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpFdFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpFsFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpFsFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpCcFsFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpCcFsFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpFdFsFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpFdFsFt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpFtOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpFtOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpCcOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpCcOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
|
|
||||||
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
|
|
||||||
MIPSReflection::INSTRUCTION m_reflGeneral[64];
|
MIPSReflection::INSTRUCTION m_reflGeneral[64];
|
||||||
MIPSReflection::INSTRUCTION m_reflCop1[32];
|
MIPSReflection::INSTRUCTION m_reflCop1[32];
|
||||||
MIPSReflection::INSTRUCTION m_reflBc1[4];
|
MIPSReflection::INSTRUCTION m_reflBc1[4];
|
||||||
MIPSReflection::INSTRUCTION m_reflS[64];
|
MIPSReflection::INSTRUCTION m_reflS[64];
|
||||||
MIPSReflection::INSTRUCTION m_reflW[64];
|
MIPSReflection::INSTRUCTION m_reflW[64];
|
||||||
|
|
||||||
MIPSReflection::SUBTABLE m_reflGeneralTable;
|
MIPSReflection::SUBTABLE m_reflGeneralTable;
|
||||||
MIPSReflection::SUBTABLE m_reflCop1Table;
|
MIPSReflection::SUBTABLE m_reflCop1Table;
|
||||||
MIPSReflection::SUBTABLE m_reflBc1Table;
|
MIPSReflection::SUBTABLE m_reflBc1Table;
|
||||||
MIPSReflection::SUBTABLE m_reflSTable;
|
MIPSReflection::SUBTABLE m_reflSTable;
|
||||||
MIPSReflection::SUBTABLE m_reflWTable;
|
MIPSReflection::SUBTABLE m_reflWTable;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef void (CCOP_FPU::*InstructionFuncConstant)();
|
typedef void (CCOP_FPU::*InstructionFuncConstant)();
|
||||||
|
|
||||||
uint8 m_ft = 0;
|
uint8 m_ft = 0;
|
||||||
uint8 m_fs = 0;
|
uint8 m_fs = 0;
|
||||||
uint8 m_fd = 0;
|
uint8 m_fd = 0;
|
||||||
|
|
||||||
static const uint32 m_ccMask[8];
|
static const uint32 m_ccMask[8];
|
||||||
|
|
||||||
void SetCCBit(bool, uint32);
|
void SetCCBit(bool, uint32);
|
||||||
void PushCCBit(uint32);
|
void PushCCBit(uint32);
|
||||||
|
|
||||||
static InstructionFuncConstant m_opGeneral[0x20];
|
static InstructionFuncConstant m_opGeneral[0x20];
|
||||||
static InstructionFuncConstant m_opSingle[0x40];
|
static InstructionFuncConstant m_opSingle[0x40];
|
||||||
static InstructionFuncConstant m_opWord[0x40];
|
static InstructionFuncConstant m_opWord[0x40];
|
||||||
|
|
||||||
//General
|
//General
|
||||||
void MFC1();
|
void MFC1();
|
||||||
void CFC1();
|
void CFC1();
|
||||||
void MTC1();
|
void MTC1();
|
||||||
void CTC1();
|
void CTC1();
|
||||||
void BC1();
|
void BC1();
|
||||||
void S();
|
void S();
|
||||||
void W();
|
void W();
|
||||||
|
|
||||||
//Branch
|
//Branch
|
||||||
void BC1F();
|
void BC1F();
|
||||||
void BC1T();
|
void BC1T();
|
||||||
void BC1FL();
|
void BC1FL();
|
||||||
void BC1TL();
|
void BC1TL();
|
||||||
|
|
||||||
//Single
|
//Single
|
||||||
void ADD_S();
|
void ADD_S();
|
||||||
void SUB_S();
|
void SUB_S();
|
||||||
void MUL_S();
|
void MUL_S();
|
||||||
void DIV_S();
|
void DIV_S();
|
||||||
void SQRT_S();
|
void SQRT_S();
|
||||||
void ABS_S();
|
void ABS_S();
|
||||||
void MOV_S();
|
void MOV_S();
|
||||||
void NEG_S();
|
void NEG_S();
|
||||||
void TRUNC_W_S();
|
void TRUNC_W_S();
|
||||||
void RSQRT_S();
|
void RSQRT_S();
|
||||||
void ADDA_S();
|
void ADDA_S();
|
||||||
void SUBA_S();
|
void SUBA_S();
|
||||||
void MULA_S();
|
void MULA_S();
|
||||||
void MADD_S();
|
void MADD_S();
|
||||||
void MSUB_S();
|
void MSUB_S();
|
||||||
void MADDA_S();
|
void MADDA_S();
|
||||||
void MSUBA_S();
|
void MSUBA_S();
|
||||||
void CVT_W_S();
|
void CVT_W_S();
|
||||||
void MAX_S();
|
void MAX_S();
|
||||||
void MIN_S();
|
void MIN_S();
|
||||||
void C_F_S();
|
void C_F_S();
|
||||||
void C_EQ_S();
|
void C_EQ_S();
|
||||||
void C_LT_S();
|
void C_LT_S();
|
||||||
void C_LE_S();
|
void C_LE_S();
|
||||||
|
|
||||||
//Word
|
//Word
|
||||||
void CVT_S_W();
|
void CVT_S_W();
|
||||||
|
|
||||||
//Misc
|
//Misc
|
||||||
void LWC1();
|
void LWC1();
|
||||||
void SWC1();
|
void SWC1();
|
||||||
|
|
||||||
//Reflection tables
|
//Reflection tables
|
||||||
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
|
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflCop1[32];
|
static MIPSReflection::INSTRUCTION m_cReflCop1[32];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflBc1[4];
|
static MIPSReflection::INSTRUCTION m_cReflBc1[4];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflS[64];
|
static MIPSReflection::INSTRUCTION m_cReflS[64];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflW[64];
|
static MIPSReflection::INSTRUCTION m_cReflW[64];
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ void CCOP_FPU::ReflOpRtFcs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, ui
|
||||||
void CCOP_FPU::ReflOpFdFs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CCOP_FPU::ReflOpFdFs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||||
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
||||||
|
|
||||||
sprintf(sText, "F%i, F%i", nFD, nFS);
|
sprintf(sText, "F%i, F%i", nFD, nFS);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ void CCOP_FPU::ReflOpFdFs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uin
|
||||||
void CCOP_FPU::ReflOpFdFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CCOP_FPU::ReflOpFdFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||||
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
||||||
|
|
||||||
sprintf(sText, "F%i, F%i", nFD, nFT);
|
sprintf(sText, "F%i, F%i", nFD, nFT);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ void CCOP_FPU::ReflOpCcFsFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, u
|
||||||
{
|
{
|
||||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||||
uint8 nCC = static_cast<uint8>((nOpcode >> 8) & 0x0007);
|
uint8 nCC = static_cast<uint8>((nOpcode >> 8) & 0x0007);
|
||||||
|
|
||||||
sprintf(sText, "CC%i, F%i, F%i", nCC, nFS, nFT);
|
sprintf(sText, "CC%i, F%i, F%i", nCC, nFS, nFT);
|
||||||
}
|
}
|
||||||
|
@ -58,30 +58,30 @@ void CCOP_FPU::ReflOpFdFsFt(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, u
|
||||||
{
|
{
|
||||||
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||||
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
uint8 nFS = static_cast<uint8>((nOpcode >> 11) & 0x001F);
|
||||||
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
uint8 nFD = static_cast<uint8>((nOpcode >> 6) & 0x001F);
|
||||||
|
|
||||||
sprintf(sText, "F%i, F%i, F%i", nFD, nFS, nFT);
|
sprintf(sText, "F%i, F%i, F%i", nFD, nFS, nFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCOP_FPU::ReflOpFtOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CCOP_FPU::ReflOpFtOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
uint8 nRS = static_cast<uint8> ((nOpcode >> 21) & 0x001F);
|
uint8 nRS = static_cast<uint8>((nOpcode >> 21) & 0x001F);
|
||||||
uint8 nFT = static_cast<uint8> ((nOpcode >> 16) & 0x001F);
|
uint8 nFT = static_cast<uint8>((nOpcode >> 16) & 0x001F);
|
||||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
sprintf(sText, "F%i, $%04X(%s)", nFT, nImm, CMIPS::m_sGPRName[nRS]);
|
sprintf(sText, "F%i, $%04X(%s)", nFT, nImm, CMIPS::m_sGPRName[nRS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCOP_FPU::ReflOpCcOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CCOP_FPU::ReflOpCcOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "CC%i, $%08X", (nOpcode >> 18) & 0x07, nAddress + CMIPS::GetBranch(nImm));
|
sprintf(sText, "CC%i, $%08X", (nOpcode >> 18) & 0x07, nAddress + CMIPS::GetBranch(nImm));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 CCOP_FPU::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
uint32 CCOP_FPU::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||||
{
|
{
|
||||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
return (nAddress + CMIPS::GetBranch(nImm));
|
return (nAddress + CMIPS::GetBranch(nImm));
|
||||||
}
|
}
|
||||||
|
@ -367,43 +367,43 @@ INSTRUCTION CCOP_FPU::m_cReflW[64] =
|
||||||
|
|
||||||
void CCOP_FPU::SetupReflectionTables()
|
void CCOP_FPU::SetupReflectionTables()
|
||||||
{
|
{
|
||||||
static_assert(sizeof(m_reflGeneral) == sizeof(m_cReflGeneral), "Array sizes don't match");
|
static_assert(sizeof(m_reflGeneral) == sizeof(m_cReflGeneral), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_reflCop1) == sizeof(m_cReflCop1), "Array sizes don't match");
|
static_assert(sizeof(m_reflCop1) == sizeof(m_cReflCop1), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_reflBc1) == sizeof(m_cReflBc1), "Array sizes don't match");
|
static_assert(sizeof(m_reflBc1) == sizeof(m_cReflBc1), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_reflS) == sizeof(m_cReflS), "Array sizes don't match");
|
static_assert(sizeof(m_reflS) == sizeof(m_cReflS), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_reflW) == sizeof(m_cReflW), "Array sizes don't match");
|
static_assert(sizeof(m_reflW) == sizeof(m_cReflW), "Array sizes don't match");
|
||||||
|
|
||||||
memcpy(m_reflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
memcpy(m_reflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
||||||
memcpy(m_reflCop1, m_cReflCop1, sizeof(m_cReflCop1));
|
memcpy(m_reflCop1, m_cReflCop1, sizeof(m_cReflCop1));
|
||||||
memcpy(m_reflBc1, m_cReflBc1, sizeof(m_cReflBc1));
|
memcpy(m_reflBc1, m_cReflBc1, sizeof(m_cReflBc1));
|
||||||
memcpy(m_reflS, m_cReflS, sizeof(m_cReflS));
|
memcpy(m_reflS, m_cReflS, sizeof(m_cReflS));
|
||||||
memcpy(m_reflW, m_cReflW, sizeof(m_cReflW));
|
memcpy(m_reflW, m_cReflW, sizeof(m_cReflW));
|
||||||
|
|
||||||
m_reflGeneralTable.nShift = 26;
|
m_reflGeneralTable.nShift = 26;
|
||||||
m_reflGeneralTable.nMask = 0x3F;
|
m_reflGeneralTable.nMask = 0x3F;
|
||||||
m_reflGeneralTable.pTable = m_reflGeneral;
|
m_reflGeneralTable.pTable = m_reflGeneral;
|
||||||
|
|
||||||
m_reflCop1Table.nShift = 21;
|
m_reflCop1Table.nShift = 21;
|
||||||
m_reflCop1Table.nMask = 0x1F;
|
m_reflCop1Table.nMask = 0x1F;
|
||||||
m_reflCop1Table.pTable = m_reflCop1;
|
m_reflCop1Table.pTable = m_reflCop1;
|
||||||
|
|
||||||
m_reflBc1Table.nShift = 16;
|
m_reflBc1Table.nShift = 16;
|
||||||
m_reflBc1Table.nMask = 0x03;
|
m_reflBc1Table.nMask = 0x03;
|
||||||
m_reflBc1Table.pTable = m_reflBc1;
|
m_reflBc1Table.pTable = m_reflBc1;
|
||||||
|
|
||||||
m_reflSTable.nShift = 0;
|
m_reflSTable.nShift = 0;
|
||||||
m_reflSTable.nMask = 0x3F;
|
m_reflSTable.nMask = 0x3F;
|
||||||
m_reflSTable.pTable = m_reflS;
|
m_reflSTable.pTable = m_reflS;
|
||||||
|
|
||||||
m_reflWTable.nShift = 0;
|
m_reflWTable.nShift = 0;
|
||||||
m_reflWTable.nMask = 0x3F;
|
m_reflWTable.nMask = 0x3F;
|
||||||
m_reflWTable.pTable = m_reflW;
|
m_reflWTable.pTable = m_reflW;
|
||||||
|
|
||||||
m_reflGeneral[0x11].pSubTable = &m_reflCop1Table;
|
m_reflGeneral[0x11].pSubTable = &m_reflCop1Table;
|
||||||
|
|
||||||
m_reflCop1[0x08].pSubTable = &m_reflBc1Table;
|
m_reflCop1[0x08].pSubTable = &m_reflBc1Table;
|
||||||
m_reflCop1[0x10].pSubTable = &m_reflSTable;
|
m_reflCop1[0x10].pSubTable = &m_reflSTable;
|
||||||
m_reflCop1[0x14].pSubTable = &m_reflWTable;
|
m_reflCop1[0x14].pSubTable = &m_reflWTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCOP_FPU::GetInstruction(uint32 nOpcode, char* sText)
|
void CCOP_FPU::GetInstruction(uint32 nOpcode, char* sText)
|
||||||
|
@ -416,8 +416,8 @@ void CCOP_FPU::GetInstruction(uint32 nOpcode, char* sText)
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pGetMnemonic = SubTableMnemonic;
|
Instr.pGetMnemonic = SubTableMnemonic;
|
||||||
Instr.pSubTable = &m_reflGeneralTable;
|
Instr.pSubTable = &m_reflGeneralTable;
|
||||||
Instr.pGetMnemonic(&Instr, NULL, nOpcode, sText, nCount);
|
Instr.pGetMnemonic(&Instr, NULL, nOpcode, sText, nCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,8 +431,8 @@ void CCOP_FPU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pGetOperands = SubTableOperands;
|
Instr.pGetOperands = SubTableOperands;
|
||||||
Instr.pSubTable = &m_reflGeneralTable;
|
Instr.pSubTable = &m_reflGeneralTable;
|
||||||
Instr.pGetOperands(&Instr, NULL, nAddress, nOpcode, sText, nCount);
|
Instr.pGetOperands(&Instr, NULL, nAddress, nOpcode, sText, nCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,8 +441,8 @@ MIPS_BRANCH_TYPE CCOP_FPU::IsBranch(uint32 nOpcode)
|
||||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pIsBranch = SubTableIsBranch;
|
Instr.pIsBranch = SubTableIsBranch;
|
||||||
Instr.pSubTable = &m_reflGeneralTable;
|
Instr.pSubTable = &m_reflGeneralTable;
|
||||||
return Instr.pIsBranch(&Instr, NULL, nOpcode);
|
return Instr.pIsBranch(&Instr, NULL, nOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ uint32 CCOP_FPU::GetEffectiveAddress(uint32 nAddress, uint32 nOpcode)
|
||||||
if(nOpcode == 0) return 0;
|
if(nOpcode == 0) return 0;
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
||||||
Instr.pSubTable = &m_reflGeneralTable;
|
Instr.pSubTable = &m_reflGeneralTable;
|
||||||
return Instr.pGetEffectiveAddress(&Instr, NULL, nAddress, nOpcode);
|
return Instr.pGetEffectiveAddress(&Instr, NULL, nAddress, nOpcode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,9 @@ const char* CCOP_SCU::m_sRegName[] =
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
CCOP_SCU::CCOP_SCU(MIPS_REGSIZE nRegSize)
|
CCOP_SCU::CCOP_SCU(MIPS_REGSIZE nRegSize)
|
||||||
: CMIPSCoprocessor(nRegSize)
|
: CMIPSCoprocessor(nRegSize)
|
||||||
, m_nRT(0)
|
, m_nRT(0)
|
||||||
, m_nRD(0)
|
, m_nRD(0)
|
||||||
{
|
{
|
||||||
SetupReflectionTables();
|
SetupReflectionTables();
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ void CCOP_SCU::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS*
|
||||||
{
|
{
|
||||||
SetupQuickVariables(nAddress, codeGen, pCtx);
|
SetupQuickVariables(nAddress, codeGen, pCtx);
|
||||||
|
|
||||||
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
|
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
|
||||||
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);
|
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);
|
||||||
|
|
||||||
((this)->*(m_pOpGeneral[(m_nOpcode >> 21) & 0x1F]))();
|
((this)->*(m_pOpGeneral[(m_nOpcode >> 21) & 0x1F]))();
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ void CCOP_SCU::ERET()
|
||||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP0[STATUS]));
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nCOP0[STATUS]));
|
||||||
m_codeGen->PushCst(CMIPS::STATUS_ERL);
|
m_codeGen->PushCst(CMIPS::STATUS_ERL);
|
||||||
m_codeGen->And();
|
m_codeGen->And();
|
||||||
|
|
||||||
m_codeGen->PushCst(0);
|
m_codeGen->PushCst(0);
|
||||||
m_codeGen->BeginIf(Jitter::CONDITION_NE);
|
m_codeGen->BeginIf(Jitter::CONDITION_NE);
|
||||||
{
|
{
|
||||||
|
|
147
Source/COP_SCU.h
147
Source/COP_SCU.h
|
@ -9,105 +9,104 @@ class CCOP_SCU : public CMIPSCoprocessor
|
||||||
public:
|
public:
|
||||||
enum REGISTER
|
enum REGISTER
|
||||||
{
|
{
|
||||||
COUNT = 0x09,
|
COUNT = 0x09,
|
||||||
STATUS = 0x0C,
|
STATUS = 0x0C,
|
||||||
EPC = 0x0E,
|
EPC = 0x0E,
|
||||||
CPCOND0 = 0x15,
|
CPCOND0 = 0x15,
|
||||||
ERROREPC = 0x1E,
|
ERROREPC = 0x1E,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PCCR : public convertible<uint32>
|
struct PCCR : public convertible<uint32>
|
||||||
{
|
{
|
||||||
unsigned int reserved0 : 1;
|
unsigned int reserved0 : 1;
|
||||||
unsigned int exl0 : 1;
|
unsigned int exl0 : 1;
|
||||||
unsigned int k0 : 1;
|
unsigned int k0 : 1;
|
||||||
unsigned int s0 : 1;
|
unsigned int s0 : 1;
|
||||||
unsigned int u0 : 1;
|
unsigned int u0 : 1;
|
||||||
unsigned int event0 : 5;
|
unsigned int event0 : 5;
|
||||||
unsigned int reserved1 : 1;
|
unsigned int reserved1 : 1;
|
||||||
unsigned int exl1 : 1;
|
unsigned int exl1 : 1;
|
||||||
unsigned int k1 : 1;
|
unsigned int k1 : 1;
|
||||||
unsigned int s1 : 1;
|
unsigned int s1 : 1;
|
||||||
unsigned int u1 : 1;
|
unsigned int u1 : 1;
|
||||||
unsigned int event1 : 5;
|
unsigned int event1 : 5;
|
||||||
unsigned int reserved2 : 11;
|
unsigned int reserved2 : 11;
|
||||||
unsigned int cte : 1;
|
unsigned int cte : 1;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PCCR) == 4, "PCCR must be 4 bytes long.");
|
static_assert(sizeof(PCCR) == 4, "PCCR must be 4 bytes long.");
|
||||||
|
|
||||||
CCOP_SCU(MIPS_REGSIZE);
|
CCOP_SCU(MIPS_REGSIZE);
|
||||||
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override;
|
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*) override;
|
||||||
virtual void GetInstruction(uint32, char*) override;
|
virtual void GetInstruction(uint32, char*) override;
|
||||||
virtual void GetArguments(uint32, uint32, char*) override;
|
virtual void GetArguments(uint32, uint32, char*) override;
|
||||||
virtual uint32 GetEffectiveAddress(uint32, uint32) override;
|
virtual uint32 GetEffectiveAddress(uint32, uint32) override;
|
||||||
virtual MIPS_BRANCH_TYPE IsBranch(uint32) override;
|
virtual MIPS_BRANCH_TYPE IsBranch(uint32) override;
|
||||||
|
|
||||||
static const char* m_sRegName[];
|
static const char* m_sRegName[];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetupReflectionTables();
|
void SetupReflectionTables();
|
||||||
|
|
||||||
static void ReflOpRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRtPcr(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtPcr(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRtRd(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtRd(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpCcOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpCcOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
|
|
||||||
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
|
|
||||||
MIPSReflection::INSTRUCTION m_ReflGeneral[64];
|
MIPSReflection::INSTRUCTION m_ReflGeneral[64];
|
||||||
MIPSReflection::INSTRUCTION m_ReflMfc0[32];
|
MIPSReflection::INSTRUCTION m_ReflMfc0[32];
|
||||||
MIPSReflection::INSTRUCTION m_ReflMtc0[32];
|
MIPSReflection::INSTRUCTION m_ReflMtc0[32];
|
||||||
MIPSReflection::INSTRUCTION m_ReflCop0[32];
|
MIPSReflection::INSTRUCTION m_ReflCop0[32];
|
||||||
MIPSReflection::INSTRUCTION m_ReflBc0[4];
|
MIPSReflection::INSTRUCTION m_ReflBc0[4];
|
||||||
MIPSReflection::INSTRUCTION m_ReflC0[64];
|
MIPSReflection::INSTRUCTION m_ReflC0[64];
|
||||||
MIPSReflection::INSTRUCTION m_ReflMfPerf[2];
|
MIPSReflection::INSTRUCTION m_ReflMfPerf[2];
|
||||||
MIPSReflection::INSTRUCTION m_ReflMtPerf[2];
|
MIPSReflection::INSTRUCTION m_ReflMtPerf[2];
|
||||||
|
|
||||||
MIPSReflection::SUBTABLE m_ReflGeneralTable;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflMfc0Table;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflMtc0Table;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflCop0Table;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflBc0Table;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflC0Table;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflMfPerfTable;
|
|
||||||
MIPSReflection::SUBTABLE m_ReflMtPerfTable;
|
|
||||||
|
|
||||||
|
MIPSReflection::SUBTABLE m_ReflGeneralTable;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflMfc0Table;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflMtc0Table;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflCop0Table;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflBc0Table;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflC0Table;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflMfPerfTable;
|
||||||
|
MIPSReflection::SUBTABLE m_ReflMtPerfTable;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef void (CCOP_SCU::*InstructionFuncConstant)();
|
typedef void (CCOP_SCU::*InstructionFuncConstant)();
|
||||||
|
|
||||||
static InstructionFuncConstant m_pOpGeneral[0x20];
|
static InstructionFuncConstant m_pOpGeneral[0x20];
|
||||||
static InstructionFuncConstant m_pOpMtc0[0x20];
|
static InstructionFuncConstant m_pOpMtc0[0x20];
|
||||||
static InstructionFuncConstant m_pOpBC0[0x20];
|
static InstructionFuncConstant m_pOpBC0[0x20];
|
||||||
static InstructionFuncConstant m_pOpC0[0x40];
|
static InstructionFuncConstant m_pOpC0[0x40];
|
||||||
|
|
||||||
uint8 m_nRT;
|
uint8 m_nRT;
|
||||||
uint8 m_nRD;
|
uint8 m_nRD;
|
||||||
|
|
||||||
//General
|
//General
|
||||||
void MFC0();
|
void MFC0();
|
||||||
void MTC0();
|
void MTC0();
|
||||||
void BC0();
|
void BC0();
|
||||||
void C0();
|
void C0();
|
||||||
|
|
||||||
//BC0
|
//BC0
|
||||||
void BC0F();
|
void BC0F();
|
||||||
void BC0T();
|
void BC0T();
|
||||||
void BC0FL();
|
void BC0FL();
|
||||||
|
|
||||||
//C0
|
//C0
|
||||||
void TLBWI();
|
void TLBWI();
|
||||||
void ERET();
|
void ERET();
|
||||||
void EI();
|
void EI();
|
||||||
void DI();
|
void DI();
|
||||||
|
|
||||||
//Reflection tables
|
//Reflection tables
|
||||||
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
|
static MIPSReflection::INSTRUCTION m_cReflGeneral[64];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflCop0[32];
|
static MIPSReflection::INSTRUCTION m_cReflCop0[32];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflMfc0[32];
|
static MIPSReflection::INSTRUCTION m_cReflMfc0[32];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflMtc0[32];
|
static MIPSReflection::INSTRUCTION m_cReflMtc0[32];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflBc0[4];
|
static MIPSReflection::INSTRUCTION m_cReflBc0[4];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflC0[64];
|
static MIPSReflection::INSTRUCTION m_cReflC0[64];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflMfPerf[2];
|
static MIPSReflection::INSTRUCTION m_cReflMfPerf[2];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflMtPerf[2];
|
static MIPSReflection::INSTRUCTION m_cReflMtPerf[2];
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,14 +30,14 @@ void CCOP_SCU::ReflOpRtRd(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uin
|
||||||
|
|
||||||
void CCOP_SCU::ReflOpCcOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CCOP_SCU::ReflOpCcOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "CC%i, $%08X", (nOpcode >> 18) & 0x07, nAddress + CMIPS::GetBranch(nImm));
|
sprintf(sText, "CC%i, $%08X", (nOpcode >> 18) & 0x07, nAddress + CMIPS::GetBranch(nImm));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 CCOP_SCU::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
uint32 CCOP_SCU::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||||
{
|
{
|
||||||
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
uint16 nImm = static_cast<uint16>((nOpcode >> 0) & 0xFFFF);
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
return (nAddress + CMIPS::GetBranch(nImm));
|
return (nAddress + CMIPS::GetBranch(nImm));
|
||||||
}
|
}
|
||||||
|
@ -339,66 +339,66 @@ INSTRUCTION CCOP_SCU::m_cReflMtPerf[2] =
|
||||||
|
|
||||||
void CCOP_SCU::SetupReflectionTables()
|
void CCOP_SCU::SetupReflectionTables()
|
||||||
{
|
{
|
||||||
static_assert(sizeof(m_ReflGeneral) == sizeof(m_cReflGeneral), "Array sizes don't match");
|
static_assert(sizeof(m_ReflGeneral) == sizeof(m_cReflGeneral), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflCop0) == sizeof(m_cReflCop0), "Array sizes don't match");
|
static_assert(sizeof(m_ReflCop0) == sizeof(m_cReflCop0), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflMfc0) == sizeof(m_cReflMfc0), "Array sizes don't match");
|
static_assert(sizeof(m_ReflMfc0) == sizeof(m_cReflMfc0), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflMtc0) == sizeof(m_cReflMtc0), "Array sizes don't match");
|
static_assert(sizeof(m_ReflMtc0) == sizeof(m_cReflMtc0), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflBc0) == sizeof(m_cReflBc0), "Array sizes don't match");
|
static_assert(sizeof(m_ReflBc0) == sizeof(m_cReflBc0), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflC0) == sizeof(m_cReflC0), "Array sizes don't match");
|
static_assert(sizeof(m_ReflC0) == sizeof(m_cReflC0), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflMtPerf) == sizeof(m_cReflMtPerf), "Array sizes don't match");
|
static_assert(sizeof(m_ReflMtPerf) == sizeof(m_cReflMtPerf), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflMfPerf) == sizeof(m_cReflMfPerf), "Array sizes don't match");
|
static_assert(sizeof(m_ReflMfPerf) == sizeof(m_cReflMfPerf), "Array sizes don't match");
|
||||||
|
|
||||||
memcpy(m_ReflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
memcpy(m_ReflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
||||||
memcpy(m_ReflCop0, m_cReflCop0, sizeof(m_cReflCop0));
|
memcpy(m_ReflCop0, m_cReflCop0, sizeof(m_cReflCop0));
|
||||||
memcpy(m_ReflMtc0, m_cReflMtc0, sizeof(m_cReflMtc0));
|
memcpy(m_ReflMtc0, m_cReflMtc0, sizeof(m_cReflMtc0));
|
||||||
memcpy(m_ReflMfc0, m_cReflMfc0, sizeof(m_cReflMfc0));
|
memcpy(m_ReflMfc0, m_cReflMfc0, sizeof(m_cReflMfc0));
|
||||||
memcpy(m_ReflBc0, m_cReflBc0, sizeof(m_cReflBc0));
|
memcpy(m_ReflBc0, m_cReflBc0, sizeof(m_cReflBc0));
|
||||||
memcpy(m_ReflC0, m_cReflC0, sizeof(m_cReflC0));
|
memcpy(m_ReflC0, m_cReflC0, sizeof(m_cReflC0));
|
||||||
memcpy(m_ReflMtPerf, m_cReflMtPerf, sizeof(m_cReflMtPerf));
|
memcpy(m_ReflMtPerf, m_cReflMtPerf, sizeof(m_cReflMtPerf));
|
||||||
memcpy(m_ReflMfPerf, m_cReflMfPerf, sizeof(m_cReflMfPerf));
|
memcpy(m_ReflMfPerf, m_cReflMfPerf, sizeof(m_cReflMfPerf));
|
||||||
|
|
||||||
m_ReflGeneralTable.nShift = 26;
|
m_ReflGeneralTable.nShift = 26;
|
||||||
m_ReflGeneralTable.nMask = 0x3F;
|
m_ReflGeneralTable.nMask = 0x3F;
|
||||||
m_ReflGeneralTable.pTable = m_ReflGeneral;
|
m_ReflGeneralTable.pTable = m_ReflGeneral;
|
||||||
|
|
||||||
m_ReflCop0Table.nShift = 21;
|
m_ReflCop0Table.nShift = 21;
|
||||||
m_ReflCop0Table.nMask = 0x1F;
|
m_ReflCop0Table.nMask = 0x1F;
|
||||||
m_ReflCop0Table.pTable = m_ReflCop0;
|
m_ReflCop0Table.pTable = m_ReflCop0;
|
||||||
|
|
||||||
m_ReflMfc0Table.nShift = 11;
|
m_ReflMfc0Table.nShift = 11;
|
||||||
m_ReflMfc0Table.nMask = 0x1F;
|
m_ReflMfc0Table.nMask = 0x1F;
|
||||||
m_ReflMfc0Table.pTable = m_ReflMfc0;
|
m_ReflMfc0Table.pTable = m_ReflMfc0;
|
||||||
|
|
||||||
m_ReflMtc0Table.nShift = 11;
|
m_ReflMtc0Table.nShift = 11;
|
||||||
m_ReflMtc0Table.nMask = 0x1F;
|
m_ReflMtc0Table.nMask = 0x1F;
|
||||||
m_ReflMtc0Table.pTable = m_ReflMtc0;
|
m_ReflMtc0Table.pTable = m_ReflMtc0;
|
||||||
|
|
||||||
m_ReflBc0Table.nShift = 16;
|
m_ReflBc0Table.nShift = 16;
|
||||||
m_ReflBc0Table.nMask = 0x03;
|
m_ReflBc0Table.nMask = 0x03;
|
||||||
m_ReflBc0Table.pTable = m_ReflBc0;
|
m_ReflBc0Table.pTable = m_ReflBc0;
|
||||||
|
|
||||||
m_ReflC0Table.nShift = 0;
|
m_ReflC0Table.nShift = 0;
|
||||||
m_ReflC0Table.nMask = 0x3F;
|
m_ReflC0Table.nMask = 0x3F;
|
||||||
m_ReflC0Table.pTable = m_ReflC0;
|
m_ReflC0Table.pTable = m_ReflC0;
|
||||||
|
|
||||||
m_ReflMfPerfTable.nShift = 0;
|
m_ReflMfPerfTable.nShift = 0;
|
||||||
m_ReflMfPerfTable.nMask = 1;
|
m_ReflMfPerfTable.nMask = 1;
|
||||||
m_ReflMfPerfTable.pTable = m_ReflMfPerf;
|
m_ReflMfPerfTable.pTable = m_ReflMfPerf;
|
||||||
|
|
||||||
m_ReflMtPerfTable.nShift = 0;
|
m_ReflMtPerfTable.nShift = 0;
|
||||||
m_ReflMtPerfTable.nMask = 1;
|
m_ReflMtPerfTable.nMask = 1;
|
||||||
m_ReflMtPerfTable.pTable = m_ReflMtPerf;
|
m_ReflMtPerfTable.pTable = m_ReflMtPerf;
|
||||||
|
|
||||||
m_ReflGeneral[0x10].pSubTable = &m_ReflCop0Table;
|
m_ReflGeneral[0x10].pSubTable = &m_ReflCop0Table;
|
||||||
|
|
||||||
m_ReflCop0[0x00].pSubTable = &m_ReflMfc0Table;
|
m_ReflCop0[0x00].pSubTable = &m_ReflMfc0Table;
|
||||||
m_ReflCop0[0x04].pSubTable = &m_ReflMtc0Table;
|
m_ReflCop0[0x04].pSubTable = &m_ReflMtc0Table;
|
||||||
m_ReflCop0[0x08].pSubTable = &m_ReflBc0Table;
|
m_ReflCop0[0x08].pSubTable = &m_ReflBc0Table;
|
||||||
m_ReflCop0[0x10].pSubTable = &m_ReflC0Table;
|
m_ReflCop0[0x10].pSubTable = &m_ReflC0Table;
|
||||||
|
|
||||||
m_ReflMfc0[0x19].pSubTable = &m_ReflMfPerfTable;
|
m_ReflMfc0[0x19].pSubTable = &m_ReflMfPerfTable;
|
||||||
|
|
||||||
m_ReflMtc0[0x19].pSubTable = &m_ReflMtPerfTable;
|
m_ReflMtc0[0x19].pSubTable = &m_ReflMtPerfTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
|
void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
|
||||||
|
@ -411,8 +411,8 @@ void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pGetMnemonic = SubTableMnemonic;
|
Instr.pGetMnemonic = SubTableMnemonic;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
Instr.pGetMnemonic(&Instr, NULL, nOpcode, sText, nCount);
|
Instr.pGetMnemonic(&Instr, NULL, nOpcode, sText, nCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,8 +426,8 @@ void CCOP_SCU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pGetOperands = SubTableOperands;
|
Instr.pGetOperands = SubTableOperands;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
Instr.pGetOperands(&Instr, NULL, nAddress, nOpcode, sText, nCount);
|
Instr.pGetOperands(&Instr, NULL, nAddress, nOpcode, sText, nCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,8 +436,8 @@ MIPS_BRANCH_TYPE CCOP_SCU::IsBranch(uint32 nOpcode)
|
||||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pIsBranch = SubTableIsBranch;
|
Instr.pIsBranch = SubTableIsBranch;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
return Instr.pIsBranch(&Instr, NULL, nOpcode);
|
return Instr.pIsBranch(&Instr, NULL, nOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ uint32 CCOP_SCU::GetEffectiveAddress(uint32 nAddress, uint32 nOpcode)
|
||||||
if(nOpcode == 0) return 0;
|
if(nOpcode == 0) return 0;
|
||||||
|
|
||||||
INSTRUCTION Instr;
|
INSTRUCTION Instr;
|
||||||
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
return Instr.pGetEffectiveAddress(&Instr, NULL, nAddress, nOpcode);
|
return Instr.pGetEffectiveAddress(&Instr, NULL, nAddress, nOpcode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,34 +3,32 @@
|
||||||
using namespace PS2;
|
using namespace PS2;
|
||||||
|
|
||||||
const char* CControllerInfo::m_buttonName[CControllerInfo::MAX_BUTTONS] =
|
const char* CControllerInfo::m_buttonName[CControllerInfo::MAX_BUTTONS] =
|
||||||
{
|
{
|
||||||
"analog_left_x",
|
"analog_left_x",
|
||||||
"analog_left_y",
|
"analog_left_y",
|
||||||
"analog_right_x",
|
"analog_right_x",
|
||||||
"analog_right_y",
|
"analog_right_y",
|
||||||
"dpad_up",
|
"dpad_up",
|
||||||
"dpad_down",
|
"dpad_down",
|
||||||
"dpad_left",
|
"dpad_left",
|
||||||
"dpad_right",
|
"dpad_right",
|
||||||
"select",
|
"select",
|
||||||
"start",
|
"start",
|
||||||
"square",
|
"square",
|
||||||
"triangle",
|
"triangle",
|
||||||
"circle",
|
"circle",
|
||||||
"cross",
|
"cross",
|
||||||
"l1",
|
"l1",
|
||||||
"l2",
|
"l2",
|
||||||
"l3",
|
"l3",
|
||||||
"r1",
|
"r1",
|
||||||
"r2",
|
"r2",
|
||||||
"r3"
|
"r3"};
|
||||||
};
|
|
||||||
|
|
||||||
bool CControllerInfo::IsAxis(BUTTON button)
|
bool CControllerInfo::IsAxis(BUTTON button)
|
||||||
{
|
{
|
||||||
return
|
return (button == ANALOG_LEFT_X) ||
|
||||||
(button == ANALOG_LEFT_X) ||
|
(button == ANALOG_LEFT_Y) ||
|
||||||
(button == ANALOG_LEFT_Y) ||
|
(button == ANALOG_RIGHT_X) ||
|
||||||
(button == ANALOG_RIGHT_X) ||
|
(button == ANALOG_RIGHT_Y);
|
||||||
(button == ANALOG_RIGHT_Y);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ namespace PS2
|
||||||
MAX_BUTTONS
|
MAX_BUTTONS
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* m_buttonName[MAX_BUTTONS];
|
static const char* m_buttonName[MAX_BUTTONS];
|
||||||
|
|
||||||
static bool IsAxis(BUTTON);
|
static bool IsAxis(BUTTON);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,11 @@ struct CsoHeader
|
||||||
};
|
};
|
||||||
|
|
||||||
CCsoImageStream::CCsoImageStream(CStream* baseStream)
|
CCsoImageStream::CCsoImageStream(CStream* baseStream)
|
||||||
: m_baseStream(baseStream), m_readBuffer(nullptr), m_zlibBuffer(nullptr), m_index(nullptr), m_position(0)
|
: m_baseStream(baseStream)
|
||||||
|
, m_readBuffer(nullptr)
|
||||||
|
, m_zlibBuffer(nullptr)
|
||||||
|
, m_index(nullptr)
|
||||||
|
, m_position(0)
|
||||||
{
|
{
|
||||||
if(baseStream == nullptr)
|
if(baseStream == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -35,9 +39,9 @@ CCsoImageStream::CCsoImageStream(CStream* baseStream)
|
||||||
|
|
||||||
CCsoImageStream::~CCsoImageStream()
|
CCsoImageStream::~CCsoImageStream()
|
||||||
{
|
{
|
||||||
delete [] m_readBuffer;
|
delete[] m_readBuffer;
|
||||||
delete [] m_zlibBuffer;
|
delete[] m_zlibBuffer;
|
||||||
delete [] m_index;
|
delete[] m_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCsoImageStream::ReadFileHeader()
|
void CCsoImageStream::ReadFileHeader()
|
||||||
|
@ -106,7 +110,7 @@ void CCsoImageStream::InitializeBuffers()
|
||||||
|
|
||||||
void CCsoImageStream::Seek(int64 position, Framework::STREAM_SEEK_DIRECTION origin)
|
void CCsoImageStream::Seek(int64 position, Framework::STREAM_SEEK_DIRECTION origin)
|
||||||
{
|
{
|
||||||
switch (origin)
|
switch(origin)
|
||||||
{
|
{
|
||||||
case Framework::STREAM_SEEK_CUR:
|
case Framework::STREAM_SEEK_CUR:
|
||||||
m_position += position;
|
m_position += position;
|
||||||
|
|
|
@ -6,31 +6,31 @@
|
||||||
class CCsoImageStream : public Framework::CStream
|
class CCsoImageStream : public Framework::CStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCsoImageStream(Framework::CStream* baseStream);
|
CCsoImageStream(Framework::CStream* baseStream);
|
||||||
virtual ~CCsoImageStream();
|
virtual ~CCsoImageStream();
|
||||||
|
|
||||||
virtual void Seek(int64 pos, Framework::STREAM_SEEK_DIRECTION whence) override;
|
virtual void Seek(int64 pos, Framework::STREAM_SEEK_DIRECTION whence) override;
|
||||||
virtual uint64 Tell() override;
|
virtual uint64 Tell() override;
|
||||||
virtual bool IsEOF() override;
|
virtual bool IsEOF() override;
|
||||||
virtual uint64 Read(void* dest, uint64 bytes) override;
|
virtual uint64 Read(void* dest, uint64 bytes) override;
|
||||||
virtual uint64 Write(const void* src, uint64 bytes) override;
|
virtual uint64 Write(const void* src, uint64 bytes) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ReadFileHeader();
|
void ReadFileHeader();
|
||||||
void InitializeBuffers();
|
void InitializeBuffers();
|
||||||
uint64 GetTotalSize() const;
|
uint64 GetTotalSize() const;
|
||||||
uint32 ReadFromNextFrame(uint8* dest, uint64 maxBytes);
|
uint32 ReadFromNextFrame(uint8* dest, uint64 maxBytes);
|
||||||
uint64 ReadBaseAt(uint64 pos, uint8* dest, uint64 bytes);
|
uint64 ReadBaseAt(uint64 pos, uint8* dest, uint64 bytes);
|
||||||
void DecompressFrame(uint32 frame, uint64 readBufferSize);
|
void DecompressFrame(uint32 frame, uint64 readBufferSize);
|
||||||
|
|
||||||
Framework::CStream* m_baseStream;
|
Framework::CStream* m_baseStream;
|
||||||
uint32 m_frameSize;
|
uint32 m_frameSize;
|
||||||
uint8 m_frameShift;
|
uint8 m_frameShift;
|
||||||
uint8 m_indexShift;
|
uint8 m_indexShift;
|
||||||
uint8* m_readBuffer;
|
uint8* m_readBuffer;
|
||||||
uint8* m_zlibBuffer;
|
uint8* m_zlibBuffer;
|
||||||
uint32 m_zlibBufferFrame;
|
uint32 m_zlibBufferFrame;
|
||||||
uint32* m_index;
|
uint32* m_index;
|
||||||
uint64 m_totalSize;
|
uint64 m_totalSize;
|
||||||
uint64 m_position;
|
uint64 m_position;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,8 +10,8 @@ namespace DiskUtils
|
||||||
typedef std::unique_ptr<COpticalMedia> OpticalMediaPtr;
|
typedef std::unique_ptr<COpticalMedia> OpticalMediaPtr;
|
||||||
typedef std::map<std::string, std::string> SystemConfigMap;
|
typedef std::map<std::string, std::string> SystemConfigMap;
|
||||||
|
|
||||||
OpticalMediaPtr CreateOpticalMediaFromPath(const boost::filesystem::path&);
|
OpticalMediaPtr CreateOpticalMediaFromPath(const boost::filesystem::path&);
|
||||||
SystemConfigMap ParseSystemConfigFile(Framework::CStream*);
|
SystemConfigMap ParseSystemConfigFile(Framework::CStream*);
|
||||||
|
|
||||||
bool TryGetDiskId(const boost::filesystem::path&, std::string*);
|
bool TryGetDiskId(const boost::filesystem::path&, std::string*);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
#include "ELF.h"
|
#include "ELF.h"
|
||||||
#include "PtrStream.h"
|
#include "PtrStream.h"
|
||||||
|
|
||||||
CELF::CELF(uint8* content)
|
CELF::CELF(uint8* content)
|
||||||
: m_content(content)
|
: m_content(content)
|
||||||
{
|
{
|
||||||
Framework::CPtrStream stream(m_content, -1);
|
Framework::CPtrStream stream(m_content, -1);
|
||||||
|
|
||||||
stream.Read(&m_Header, sizeof(ELFHEADER));
|
stream.Read(&m_Header, sizeof(ELFHEADER));
|
||||||
|
|
||||||
if(m_Header.nId[0] != 0x7F || m_Header.nId[1] != 'E' || m_Header.nId[2] != 'L' || m_Header.nId[3] != 'F')
|
if(m_Header.nId[0] != 0x7F || m_Header.nId[1] != 'E' || m_Header.nId[2] != 'L' || m_Header.nId[3] != 'F')
|
||||||
{
|
{
|
||||||
throw std::runtime_error("This file isn't a valid ELF file.");
|
throw std::runtime_error("This file isn't a valid ELF file.");
|
||||||
|
@ -46,8 +46,8 @@ CELF::CELF(uint8* content)
|
||||||
|
|
||||||
CELF::~CELF()
|
CELF::~CELF()
|
||||||
{
|
{
|
||||||
delete [] m_pProgram;
|
delete[] m_pProgram;
|
||||||
delete [] m_pSection;
|
delete[] m_pSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* CELF::GetContent() const
|
uint8* CELF::GetContent() const
|
||||||
|
|
200
Source/ELF.h
200
Source/ELF.h
|
@ -7,56 +7,56 @@
|
||||||
|
|
||||||
struct ELFSYMBOL
|
struct ELFSYMBOL
|
||||||
{
|
{
|
||||||
uint32 nName;
|
uint32 nName;
|
||||||
uint32 nValue;
|
uint32 nValue;
|
||||||
uint32 nSize;
|
uint32 nSize;
|
||||||
uint8 nInfo;
|
uint8 nInfo;
|
||||||
uint8 nOther;
|
uint8 nOther;
|
||||||
uint16 nSectionIndex;
|
uint16 nSectionIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ELFHEADER
|
struct ELFHEADER
|
||||||
{
|
{
|
||||||
uint8 nId[16];
|
uint8 nId[16];
|
||||||
uint16 nType;
|
uint16 nType;
|
||||||
uint16 nCPU;
|
uint16 nCPU;
|
||||||
uint32 nVersion;
|
uint32 nVersion;
|
||||||
uint32 nEntryPoint;
|
uint32 nEntryPoint;
|
||||||
uint32 nProgHeaderStart;
|
uint32 nProgHeaderStart;
|
||||||
uint32 nSectHeaderStart;
|
uint32 nSectHeaderStart;
|
||||||
uint32 nFlags;
|
uint32 nFlags;
|
||||||
uint16 nSize;
|
uint16 nSize;
|
||||||
uint16 nProgHeaderEntrySize;
|
uint16 nProgHeaderEntrySize;
|
||||||
uint16 nProgHeaderCount;
|
uint16 nProgHeaderCount;
|
||||||
uint16 nSectHeaderEntrySize;
|
uint16 nSectHeaderEntrySize;
|
||||||
uint16 nSectHeaderCount;
|
uint16 nSectHeaderCount;
|
||||||
uint16 nSectHeaderStringTableIndex;
|
uint16 nSectHeaderStringTableIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ELFSECTIONHEADER
|
struct ELFSECTIONHEADER
|
||||||
{
|
{
|
||||||
uint32 nStringTableIndex;
|
uint32 nStringTableIndex;
|
||||||
uint32 nType;
|
uint32 nType;
|
||||||
uint32 nFlags;
|
uint32 nFlags;
|
||||||
uint32 nStart;
|
uint32 nStart;
|
||||||
uint32 nOffset;
|
uint32 nOffset;
|
||||||
uint32 nSize;
|
uint32 nSize;
|
||||||
uint32 nIndex;
|
uint32 nIndex;
|
||||||
uint32 nInfo;
|
uint32 nInfo;
|
||||||
uint32 nAlignment;
|
uint32 nAlignment;
|
||||||
uint32 nOther;
|
uint32 nOther;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ELFPROGRAMHEADER
|
struct ELFPROGRAMHEADER
|
||||||
{
|
{
|
||||||
uint32 nType;
|
uint32 nType;
|
||||||
uint32 nOffset;
|
uint32 nOffset;
|
||||||
uint32 nVAddress;
|
uint32 nVAddress;
|
||||||
uint32 nPAddress;
|
uint32 nPAddress;
|
||||||
uint32 nFileSize;
|
uint32 nFileSize;
|
||||||
uint32 nMemorySize;
|
uint32 nMemorySize;
|
||||||
uint32 nFlags;
|
uint32 nFlags;
|
||||||
uint32 nAlignment;
|
uint32 nAlignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -66,75 +66,75 @@ class CELF
|
||||||
public:
|
public:
|
||||||
enum EXECUTABLE_TYPE
|
enum EXECUTABLE_TYPE
|
||||||
{
|
{
|
||||||
ET_NONE = 0,
|
ET_NONE = 0,
|
||||||
ET_REL = 1,
|
ET_REL = 1,
|
||||||
ET_EXEC = 2,
|
ET_EXEC = 2,
|
||||||
ET_DYN = 3,
|
ET_DYN = 3,
|
||||||
ET_CORE = 4,
|
ET_CORE = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MACHINE_TYPE
|
enum MACHINE_TYPE
|
||||||
{
|
{
|
||||||
EM_NONE = 0,
|
EM_NONE = 0,
|
||||||
EM_M32 = 1,
|
EM_M32 = 1,
|
||||||
EM_SPARC = 2,
|
EM_SPARC = 2,
|
||||||
EM_386 = 3,
|
EM_386 = 3,
|
||||||
EM_68K = 4,
|
EM_68K = 4,
|
||||||
EM_88K = 5,
|
EM_88K = 5,
|
||||||
EM_860 = 7,
|
EM_860 = 7,
|
||||||
EM_MIPS = 8,
|
EM_MIPS = 8,
|
||||||
EM_ARM = 40,
|
EM_ARM = 40,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EXECUTABLE_VERSION
|
enum EXECUTABLE_VERSION
|
||||||
{
|
{
|
||||||
EV_NONE = 0,
|
EV_NONE = 0,
|
||||||
EV_CURRENT = 1,
|
EV_CURRENT = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SECTION_HEADER_TYPE
|
enum SECTION_HEADER_TYPE
|
||||||
{
|
{
|
||||||
SHT_NULL = 0,
|
SHT_NULL = 0,
|
||||||
SHT_PROGBITS = 1,
|
SHT_PROGBITS = 1,
|
||||||
SHT_SYMTAB = 2,
|
SHT_SYMTAB = 2,
|
||||||
SHT_STRTAB = 3,
|
SHT_STRTAB = 3,
|
||||||
SHT_HASH = 5,
|
SHT_HASH = 5,
|
||||||
SHT_DYNAMIC = 6,
|
SHT_DYNAMIC = 6,
|
||||||
SHT_NOTE = 7,
|
SHT_NOTE = 7,
|
||||||
SHT_NOBITS = 8,
|
SHT_NOBITS = 8,
|
||||||
SHT_REL = 9,
|
SHT_REL = 9,
|
||||||
SHT_DYNSYM = 11,
|
SHT_DYNSYM = 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PROGRAM_HEADER_TYPE
|
enum PROGRAM_HEADER_TYPE
|
||||||
{
|
{
|
||||||
PT_NULL = 0,
|
PT_NULL = 0,
|
||||||
PT_LOAD = 1,
|
PT_LOAD = 1,
|
||||||
PT_DYNAMIC = 2,
|
PT_DYNAMIC = 2,
|
||||||
PT_INTERP = 3,
|
PT_INTERP = 3,
|
||||||
PT_NOTE = 4,
|
PT_NOTE = 4,
|
||||||
PT_SHLIB = 5,
|
PT_SHLIB = 5,
|
||||||
PT_PHDR = 6,
|
PT_PHDR = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PROGRAM_HEADER_FLAG
|
enum PROGRAM_HEADER_FLAG
|
||||||
{
|
{
|
||||||
PF_X = 0x01,
|
PF_X = 0x01,
|
||||||
PF_W = 0x02,
|
PF_W = 0x02,
|
||||||
PF_R = 0x04,
|
PF_R = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DYNAMIC_INFO_TYPE
|
enum DYNAMIC_INFO_TYPE
|
||||||
{
|
{
|
||||||
DT_NONE = 0,
|
DT_NONE = 0,
|
||||||
DT_NEEDED = 1,
|
DT_NEEDED = 1,
|
||||||
DT_PLTRELSZ = 2,
|
DT_PLTRELSZ = 2,
|
||||||
DT_PLTGOT = 3,
|
DT_PLTGOT = 3,
|
||||||
DT_HASH = 4,
|
DT_HASH = 4,
|
||||||
DT_STRTAB = 5,
|
DT_STRTAB = 5,
|
||||||
DT_SYMTAB = 6,
|
DT_SYMTAB = 6,
|
||||||
DT_SONAME = 14,
|
DT_SONAME = 14,
|
||||||
DT_SYMBOLIC = 16,
|
DT_SYMBOLIC = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MIPS_RELOCATION_TYPE
|
enum MIPS_RELOCATION_TYPE
|
||||||
|
@ -146,29 +146,29 @@ public:
|
||||||
R_MIPS_GPREL16 = 7,
|
R_MIPS_GPREL16 = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
CELF(uint8*);
|
CELF(uint8*);
|
||||||
CELF(const CELF&) = delete;
|
CELF(const CELF&) = delete;
|
||||||
virtual ~CELF();
|
virtual ~CELF();
|
||||||
|
|
||||||
CELF& operator =(const CELF&) = delete;
|
CELF& operator=(const CELF&) = delete;
|
||||||
|
|
||||||
uint8* GetContent() const;
|
uint8* GetContent() const;
|
||||||
const ELFHEADER& GetHeader() const;
|
const ELFHEADER& GetHeader() const;
|
||||||
|
|
||||||
ELFSECTIONHEADER* GetSection(unsigned int);
|
ELFSECTIONHEADER* GetSection(unsigned int);
|
||||||
const void* GetSectionData(unsigned int);
|
const void* GetSectionData(unsigned int);
|
||||||
const char* GetSectionName(unsigned int);
|
const char* GetSectionName(unsigned int);
|
||||||
|
|
||||||
ELFSECTIONHEADER* FindSection(const char*);
|
ELFSECTIONHEADER* FindSection(const char*);
|
||||||
unsigned int FindSectionIndex(const char*);
|
unsigned int FindSectionIndex(const char*);
|
||||||
const void* FindSectionData(const char*);
|
const void* FindSectionData(const char*);
|
||||||
|
|
||||||
ELFPROGRAMHEADER* GetProgram(unsigned int);
|
ELFPROGRAMHEADER* GetProgram(unsigned int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ELFHEADER m_Header;
|
ELFHEADER m_Header;
|
||||||
uint8* m_content = nullptr;
|
uint8* m_content = nullptr;
|
||||||
|
|
||||||
ELFSECTIONHEADER* m_pSection = nullptr;
|
ELFSECTIONHEADER* m_pSection = nullptr;
|
||||||
ELFPROGRAMHEADER* m_pProgram = nullptr;
|
ELFPROGRAMHEADER* m_pProgram = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
#include "ElfFile.h"
|
#include "ElfFile.h"
|
||||||
|
|
||||||
CElfFile::CElfFile(Framework::CStream& stream)
|
CElfFile::CElfFile(Framework::CStream& stream)
|
||||||
: CElfFileContainer(stream)
|
: CElfFileContainer(stream)
|
||||||
, CELF(GetFileContent())
|
, CELF(GetFileContent())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CElfFile::~CElfFile()
|
CElfFile::~CElfFile()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CElfFileContainer::CElfFileContainer(Framework::CStream& input)
|
CElfFileContainer::CElfFileContainer(Framework::CStream& input)
|
||||||
{
|
{
|
||||||
uint32 size = static_cast<uint32>(input.GetLength());
|
uint32 size = static_cast<uint32>(input.GetLength());
|
||||||
|
@ -22,7 +19,7 @@ CElfFileContainer::CElfFileContainer(Framework::CStream& input)
|
||||||
|
|
||||||
CElfFileContainer::~CElfFileContainer()
|
CElfFileContainer::~CElfFileContainer()
|
||||||
{
|
{
|
||||||
delete [] m_content;
|
delete[] m_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* CElfFileContainer::GetFileContent() const
|
uint8* CElfFileContainer::GetFileContent() const
|
||||||
|
|
|
@ -6,24 +6,22 @@
|
||||||
class CElfFileContainer
|
class CElfFileContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CElfFileContainer(Framework::CStream&);
|
CElfFileContainer(Framework::CStream&);
|
||||||
virtual ~CElfFileContainer();
|
virtual ~CElfFileContainer();
|
||||||
|
|
||||||
uint8* GetFileContent() const;
|
uint8* GetFileContent() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8* m_content;
|
uint8* m_content;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CElfFile : protected CElfFileContainer, public CELF
|
class CElfFile : protected CElfFileContainer, public CELF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CElfFile(Framework::CStream&);
|
CElfFile(Framework::CStream&);
|
||||||
virtual ~CElfFile();
|
virtual ~CElfFile();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
#include "MemoryStateFile.h"
|
#include "MemoryStateFile.h"
|
||||||
#include "RegisterStateFile.h"
|
#include "RegisterStateFile.h"
|
||||||
|
|
||||||
#define STATE_INITIAL_GSRAM "init/gsram"
|
#define STATE_INITIAL_GSRAM "init/gsram"
|
||||||
#define STATE_INITIAL_GSREGS "init/gsregs"
|
#define STATE_INITIAL_GSREGS "init/gsregs"
|
||||||
#define STATE_INITIAL_GSPRIVREGS "init/gsprivregs"
|
#define STATE_INITIAL_GSPRIVREGS "init/gsprivregs"
|
||||||
#define STATE_PACKET_METADATA_PREFIX "packet_metadata_"
|
#define STATE_PACKET_METADATA_PREFIX "packet_metadata_"
|
||||||
#define STATE_PACKET_REGISTERWRITES_PREFIX "packet_registerwrites_"
|
#define STATE_PACKET_REGISTERWRITES_PREFIX "packet_registerwrites_"
|
||||||
#define STATE_PACKET_IMAGEDATA_PREFIX "packet_imagedata_"
|
#define STATE_PACKET_IMAGEDATA_PREFIX "packet_imagedata_"
|
||||||
|
|
||||||
#define STATE_PRIVREG_SMODE2 "SMODE2"
|
#define STATE_PRIVREG_SMODE2 "SMODE2"
|
||||||
|
|
||||||
CFrameDump::CFrameDump()
|
CFrameDump::CFrameDump()
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ CFrameDump::CFrameDump()
|
||||||
|
|
||||||
CFrameDump::~CFrameDump()
|
CFrameDump::~CFrameDump()
|
||||||
{
|
{
|
||||||
delete [] m_initialGsRam;
|
delete[] m_initialGsRam;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameDump::Reset()
|
void CFrameDump::Reset()
|
||||||
|
@ -78,7 +78,7 @@ void CFrameDump::Read(Framework::CStream& input)
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
Framework::CZipArchiveReader archive(input);
|
Framework::CZipArchiveReader archive(input);
|
||||||
|
|
||||||
archive.BeginReadFile(STATE_INITIAL_GSRAM)->Read(m_initialGsRam, CGSHandler::RAMSIZE);
|
archive.BeginReadFile(STATE_INITIAL_GSRAM)->Read(m_initialGsRam, CGSHandler::RAMSIZE);
|
||||||
archive.BeginReadFile(STATE_INITIAL_GSREGS)->Read(m_initialGsRegisters, sizeof(uint64) * CGSHandler::REGISTER_MAX);
|
archive.BeginReadFile(STATE_INITIAL_GSREGS)->Read(m_initialGsRegisters, sizeof(uint64) * CGSHandler::REGISTER_MAX);
|
||||||
|
|
||||||
|
@ -135,8 +135,8 @@ void CFrameDump::Write(Framework::CStream& output) const
|
||||||
{
|
{
|
||||||
Framework::CZipArchiveWriter archive;
|
Framework::CZipArchiveWriter archive;
|
||||||
|
|
||||||
archive.InsertFile(new CMemoryStateFile(STATE_INITIAL_GSRAM, m_initialGsRam, CGSHandler::RAMSIZE));
|
archive.InsertFile(new CMemoryStateFile(STATE_INITIAL_GSRAM, m_initialGsRam, CGSHandler::RAMSIZE));
|
||||||
archive.InsertFile(new CMemoryStateFile(STATE_INITIAL_GSREGS, m_initialGsRegisters, sizeof(uint64) * CGSHandler::REGISTER_MAX));
|
archive.InsertFile(new CMemoryStateFile(STATE_INITIAL_GSREGS, m_initialGsRegisters, sizeof(uint64) * CGSHandler::REGISTER_MAX));
|
||||||
|
|
||||||
{
|
{
|
||||||
auto privRegsStateFile = new CRegisterStateFile(STATE_INITIAL_GSPRIVREGS);
|
auto privRegsStateFile = new CRegisterStateFile(STATE_INITIAL_GSPRIVREGS);
|
||||||
|
@ -171,8 +171,8 @@ void CFrameDump::IdentifyDrawingKicks()
|
||||||
|
|
||||||
DRAWINGKICK_INFO drawingKickInfo;
|
DRAWINGKICK_INFO drawingKickInfo;
|
||||||
|
|
||||||
static const unsigned int g_initVertexCounts[8] = { 1, 2, 2, 3, 3, 3, 2, 0 };
|
static const unsigned int g_initVertexCounts[8] = {1, 2, 2, 3, 3, 3, 2, 0};
|
||||||
static const unsigned int g_nextVertexCounts[8] = { 1, 2, 1, 3, 1, 1, 2, 0 };
|
static const unsigned int g_nextVertexCounts[8] = {1, 2, 1, 3, 1, 1, 2, 0};
|
||||||
|
|
||||||
CGSHandler::PRIM currentPrim;
|
CGSHandler::PRIM currentPrim;
|
||||||
currentPrim <<= GetInitialGsRegisters()[GS_REG_PRIM];
|
currentPrim <<= GetInitialGsRegisters()[GS_REG_PRIM];
|
||||||
|
@ -194,16 +194,16 @@ void CFrameDump::IdentifyDrawingKicks()
|
||||||
vertexCount = g_initVertexCounts[currentPrim.nType];
|
vertexCount = g_initVertexCounts[currentPrim.nType];
|
||||||
}
|
}
|
||||||
else if(
|
else if(
|
||||||
(registerWrite.first == GS_REG_XYOFFSET_1) ||
|
(registerWrite.first == GS_REG_XYOFFSET_1) ||
|
||||||
(registerWrite.first == GS_REG_XYOFFSET_2))
|
(registerWrite.first == GS_REG_XYOFFSET_2))
|
||||||
{
|
{
|
||||||
currentOfs[registerWrite.first - GS_REG_XYOFFSET_1] <<= registerWrite.second;
|
currentOfs[registerWrite.first - GS_REG_XYOFFSET_1] <<= registerWrite.second;
|
||||||
}
|
}
|
||||||
else if(
|
else if(
|
||||||
(registerWrite.first == GS_REG_XYZ2) ||
|
(registerWrite.first == GS_REG_XYZ2) ||
|
||||||
(registerWrite.first == GS_REG_XYZ3) ||
|
(registerWrite.first == GS_REG_XYZ3) ||
|
||||||
(registerWrite.first == GS_REG_XYZF2) ||
|
(registerWrite.first == GS_REG_XYZF2) ||
|
||||||
(registerWrite.first == GS_REG_XYZF3))
|
(registerWrite.first == GS_REG_XYZF3))
|
||||||
{
|
{
|
||||||
if(vertexCount != 0)
|
if(vertexCount != 0)
|
||||||
{
|
{
|
||||||
|
@ -213,7 +213,7 @@ void CFrameDump::IdentifyDrawingKicks()
|
||||||
|
|
||||||
drawingKickInfo.primType = currentPrim.nType;
|
drawingKickInfo.primType = currentPrim.nType;
|
||||||
drawingKickInfo.context = currentPrim.nContext;
|
drawingKickInfo.context = currentPrim.nContext;
|
||||||
drawingKickInfo.vertex[vertexCount].x = ((registerWrite.second >> 0) & 0xFFFF) - offset.nOffsetX;
|
drawingKickInfo.vertex[vertexCount].x = ((registerWrite.second >> 0) & 0xFFFF) - offset.nOffsetX;
|
||||||
drawingKickInfo.vertex[vertexCount].y = ((registerWrite.second >> 16) & 0xFFFF) - offset.nOffsetY;
|
drawingKickInfo.vertex[vertexCount].y = ((registerWrite.second >> 16) & 0xFFFF) - offset.nOffsetY;
|
||||||
|
|
||||||
if(vertexCount == 0)
|
if(vertexCount == 0)
|
||||||
|
|
|
@ -10,7 +10,7 @@ class CGsPacketMetadata
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CGsPacketMetadata(unsigned int pathIndex = 0)
|
explicit CGsPacketMetadata(unsigned int pathIndex = 0)
|
||||||
: pathIndex(pathIndex)
|
: pathIndex(pathIndex)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
memset(&vu1State, 0, sizeof(vu1State));
|
memset(&vu1State, 0, sizeof(vu1State));
|
||||||
|
@ -19,14 +19,14 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int pathIndex = 0;
|
unsigned int pathIndex = 0;
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
MIPSSTATE vu1State;
|
MIPSSTATE vu1State;
|
||||||
uint8 microMem1[PS2::MICROMEM1SIZE];
|
uint8 microMem1[PS2::MICROMEM1SIZE];
|
||||||
uint8 vuMem1[PS2::VUMEM1SIZE];
|
uint8 vuMem1[PS2::VUMEM1SIZE];
|
||||||
uint32 vpu1Top = 0;
|
uint32 vpu1Top = 0;
|
||||||
uint32 vpu1Itop = 0;
|
uint32 vpu1Itop = 0;
|
||||||
uint32 vuMemPacketAddress = 0;
|
uint32 vuMemPacketAddress = 0;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ public:
|
||||||
typedef std::vector<CGSHandler::RegisterWrite> RegisterWriteArray;
|
typedef std::vector<CGSHandler::RegisterWrite> RegisterWriteArray;
|
||||||
typedef std::vector<uint8> ImageDataArray;
|
typedef std::vector<uint8> ImageDataArray;
|
||||||
|
|
||||||
CGsPacketMetadata metadata;
|
CGsPacketMetadata metadata;
|
||||||
RegisterWriteArray registerWrites;
|
RegisterWriteArray registerWrites;
|
||||||
ImageDataArray imageData;
|
ImageDataArray imageData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DRAWINGKICK_INFO
|
struct DRAWINGKICK_INFO
|
||||||
|
@ -49,9 +49,9 @@ struct DRAWINGKICK_INFO
|
||||||
uint16 y = 0;
|
uint16 y = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int context = 0;
|
unsigned int context = 0;
|
||||||
unsigned int primType = CGSHandler::PRIM_INVALID;
|
unsigned int primType = CGSHandler::PRIM_INVALID;
|
||||||
VERTEX vertex[3];
|
VERTEX vertex[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<uint32, DRAWINGKICK_INFO> DrawingKickInfoMap;
|
typedef std::map<uint32, DRAWINGKICK_INFO> DrawingKickInfoMap;
|
||||||
|
@ -61,31 +61,31 @@ class CFrameDump
|
||||||
public:
|
public:
|
||||||
typedef std::vector<CGsPacket> PacketArray;
|
typedef std::vector<CGsPacket> PacketArray;
|
||||||
|
|
||||||
CFrameDump();
|
CFrameDump();
|
||||||
virtual ~CFrameDump();
|
virtual ~CFrameDump();
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
uint8* GetInitialGsRam();
|
uint8* GetInitialGsRam();
|
||||||
uint64* GetInitialGsRegisters();
|
uint64* GetInitialGsRegisters();
|
||||||
|
|
||||||
uint64 GetInitialSMODE2() const;
|
uint64 GetInitialSMODE2() const;
|
||||||
void SetInitialSMODE2(uint64);
|
void SetInitialSMODE2(uint64);
|
||||||
|
|
||||||
const PacketArray& GetPackets() const;
|
const PacketArray& GetPackets() const;
|
||||||
void AddRegisterPacket(const CGSHandler::RegisterWrite*, uint32, const CGsPacketMetadata*);
|
void AddRegisterPacket(const CGSHandler::RegisterWrite*, uint32, const CGsPacketMetadata*);
|
||||||
void AddImagePacket(const uint8*, uint32);
|
void AddImagePacket(const uint8*, uint32);
|
||||||
|
|
||||||
void Read(Framework::CStream&);
|
void Read(Framework::CStream&);
|
||||||
void Write(Framework::CStream&) const;
|
void Write(Framework::CStream&) const;
|
||||||
|
|
||||||
void IdentifyDrawingKicks();
|
void IdentifyDrawingKicks();
|
||||||
const DrawingKickInfoMap& GetDrawingKicks() const;
|
const DrawingKickInfoMap& GetDrawingKicks() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8* m_initialGsRam = nullptr;
|
uint8* m_initialGsRam = nullptr;
|
||||||
uint64 m_initialGsRegisters[CGSHandler::REGISTER_MAX];
|
uint64 m_initialGsRegisters[CGSHandler::REGISTER_MAX];
|
||||||
uint64 m_initialSMODE2 = 0;
|
uint64 m_initialSMODE2 = 0;
|
||||||
PacketArray m_packets;
|
PacketArray m_packets;
|
||||||
DrawingKickInfoMap m_drawingKicks;
|
DrawingKickInfoMap m_drawingKicks;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,8 +17,8 @@ public:
|
||||||
|
|
||||||
void Execute()
|
void Execute()
|
||||||
{
|
{
|
||||||
auto newEnd = std::remove_if(m_futures.begin(), m_futures.end(),
|
auto newEnd = std::remove_if(m_futures.begin(), m_futures.end(),
|
||||||
[] (const FuturePtr& future) { return future->IsDone(); } );
|
[](const FuturePtr& future) { return future->IsDone(); });
|
||||||
m_futures.erase(newEnd, m_futures.end());
|
m_futures.erase(newEnd, m_futures.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,16 +31,16 @@ private:
|
||||||
};
|
};
|
||||||
typedef std::unique_ptr<CFuture> FuturePtr;
|
typedef std::unique_ptr<CFuture> FuturePtr;
|
||||||
|
|
||||||
template<typename ResultType>
|
template <typename ResultType>
|
||||||
class CFutureWrapper : public CFuture
|
class CFutureWrapper : public CFuture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void (const ResultType&)> CallbackType;
|
typedef std::function<void(const ResultType&)> CallbackType;
|
||||||
|
|
||||||
CFutureWrapper(std::future<ResultType> future, CallbackType callback)
|
CFutureWrapper(std::future<ResultType> future, CallbackType callback)
|
||||||
: m_future(std::move(future)), m_callback(std::move(callback))
|
: m_future(std::move(future))
|
||||||
|
, m_callback(std::move(callback))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDone() override
|
bool IsDone() override
|
||||||
|
|
|
@ -14,8 +14,8 @@ namespace ISO9660
|
||||||
BLOCKSIZE = 0x800ULL
|
BLOCKSIZE = 0x800ULL
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~CBlockProvider() {};
|
virtual ~CBlockProvider(){};
|
||||||
virtual void ReadBlock(uint32, void*) = 0;
|
virtual void ReadBlock(uint32, void*) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBlockProvider2048 : public CBlockProvider
|
class CBlockProvider2048 : public CBlockProvider
|
||||||
|
@ -24,14 +24,12 @@ namespace ISO9660
|
||||||
typedef std::shared_ptr<Framework::CStream> StreamPtr;
|
typedef std::shared_ptr<Framework::CStream> StreamPtr;
|
||||||
|
|
||||||
CBlockProvider2048(const StreamPtr& stream)
|
CBlockProvider2048(const StreamPtr& stream)
|
||||||
: m_stream(stream)
|
: m_stream(stream)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~CBlockProvider2048()
|
virtual ~CBlockProvider2048()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBlock(uint32 address, void* block) override
|
void ReadBlock(uint32 address, void* block) override
|
||||||
|
@ -50,14 +48,12 @@ namespace ISO9660
|
||||||
typedef std::shared_ptr<Framework::CStream> StreamPtr;
|
typedef std::shared_ptr<Framework::CStream> StreamPtr;
|
||||||
|
|
||||||
CBlockProviderCDROMXA(const StreamPtr& stream)
|
CBlockProviderCDROMXA(const StreamPtr& stream)
|
||||||
: m_stream(stream)
|
: m_stream(stream)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~CBlockProviderCDROMXA()
|
virtual ~CBlockProviderCDROMXA()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadBlock(uint32 address, void* block) override
|
void ReadBlock(uint32 address, void* block) override
|
||||||
|
|
|
@ -32,7 +32,6 @@ CDirectoryRecord::CDirectoryRecord(Framework::CStream* stream)
|
||||||
|
|
||||||
CDirectoryRecord::~CDirectoryRecord()
|
CDirectoryRecord::~CDirectoryRecord()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 CDirectoryRecord::GetLength() const
|
uint8 CDirectoryRecord::GetLength() const
|
||||||
|
|
|
@ -8,22 +8,22 @@ namespace ISO9660
|
||||||
class CDirectoryRecord
|
class CDirectoryRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDirectoryRecord();
|
CDirectoryRecord();
|
||||||
CDirectoryRecord(Framework::CStream*);
|
CDirectoryRecord(Framework::CStream*);
|
||||||
~CDirectoryRecord();
|
~CDirectoryRecord();
|
||||||
|
|
||||||
bool IsDirectory() const;
|
bool IsDirectory() const;
|
||||||
uint8 GetLength() const;
|
uint8 GetLength() const;
|
||||||
const char* GetName() const;
|
const char* GetName() const;
|
||||||
uint32 GetPosition() const;
|
uint32 GetPosition() const;
|
||||||
uint32 GetDataLength() const;
|
uint32 GetDataLength() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 m_length = 0;
|
uint8 m_length = 0;
|
||||||
uint8 m_exLength = 0;
|
uint8 m_exLength = 0;
|
||||||
uint32 m_position = 0;
|
uint32 m_position = 0;
|
||||||
uint32 m_dataLength = 0;
|
uint32 m_dataLength = 0;
|
||||||
uint8 m_flags = 0;
|
uint8 m_flags = 0;
|
||||||
char m_name[256];
|
char m_name[256];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,23 @@
|
||||||
using namespace ISO9660;
|
using namespace ISO9660;
|
||||||
|
|
||||||
CFile::CFile(CBlockProvider* blockProvider, uint64 start)
|
CFile::CFile(CBlockProvider* blockProvider, uint64 start)
|
||||||
: m_blockProvider(blockProvider)
|
: m_blockProvider(blockProvider)
|
||||||
, m_start(start)
|
, m_start(start)
|
||||||
, m_end(ULLONG_MAX)
|
, m_end(ULLONG_MAX)
|
||||||
{
|
{
|
||||||
InitBlock();
|
InitBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
CFile::CFile(CBlockProvider* blockProvider, uint64 start, uint64 size)
|
CFile::CFile(CBlockProvider* blockProvider, uint64 start, uint64 size)
|
||||||
: m_blockProvider(blockProvider)
|
: m_blockProvider(blockProvider)
|
||||||
, m_start(start)
|
, m_start(start)
|
||||||
, m_end(start + size)
|
, m_end(start + size)
|
||||||
{
|
{
|
||||||
InitBlock();
|
InitBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
CFile::~CFile()
|
CFile::~CFile()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFile::Seek(int64 amount, Framework::STREAM_SEEK_DIRECTION whence)
|
void CFile::Seek(int64 amount, Framework::STREAM_SEEK_DIRECTION whence)
|
||||||
|
@ -65,9 +64,9 @@ uint64 CFile::Read(void* data, uint64 length)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
SyncBlock();
|
SyncBlock();
|
||||||
uint64 blockPosition = (m_start + m_position) % CBlockProvider::BLOCKSIZE;
|
uint64 blockPosition = (m_start + m_position) % CBlockProvider::BLOCKSIZE;
|
||||||
uint64 blockRemain = CBlockProvider::BLOCKSIZE - blockPosition;
|
uint64 blockRemain = CBlockProvider::BLOCKSIZE - blockPosition;
|
||||||
uint64 toRead = (length > blockRemain) ? (blockRemain) : (length);
|
uint64 toRead = (length > blockRemain) ? (blockRemain) : (length);
|
||||||
|
|
||||||
memcpy(data, m_block + blockPosition, static_cast<uint32>(toRead));
|
memcpy(data, m_block + blockPosition, static_cast<uint32>(toRead));
|
||||||
|
|
||||||
|
|
|
@ -8,26 +8,25 @@ namespace ISO9660
|
||||||
class CFile : public Framework::CStream
|
class CFile : public Framework::CStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CFile(CBlockProvider*, uint64);
|
CFile(CBlockProvider*, uint64);
|
||||||
CFile(CBlockProvider*, uint64, uint64);
|
CFile(CBlockProvider*, uint64, uint64);
|
||||||
~CFile();
|
~CFile();
|
||||||
void Seek(int64, Framework::STREAM_SEEK_DIRECTION) override;
|
void Seek(int64, Framework::STREAM_SEEK_DIRECTION) override;
|
||||||
uint64 Tell() override;
|
uint64 Tell() override;
|
||||||
uint64 Read(void*, uint64) override;
|
uint64 Read(void*, uint64) override;
|
||||||
uint64 Write(const void*, uint64) override;
|
uint64 Write(const void*, uint64) override;
|
||||||
bool IsEOF() override;
|
bool IsEOF() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitBlock();
|
void InitBlock();
|
||||||
void SyncBlock();
|
void SyncBlock();
|
||||||
|
|
||||||
CBlockProvider* m_blockProvider = nullptr;
|
CBlockProvider* m_blockProvider = nullptr;
|
||||||
uint64 m_start = 0;
|
uint64 m_start = 0;
|
||||||
uint64 m_end = 0;
|
uint64 m_end = 0;
|
||||||
uint64 m_position = 0;
|
uint64 m_position = 0;
|
||||||
uint32 m_blockPosition = 0;
|
uint32 m_blockPosition = 0;
|
||||||
uint8 m_block[CBlockProvider::BLOCKSIZE];
|
uint8 m_block[CBlockProvider::BLOCKSIZE];
|
||||||
bool m_isEof = false;
|
bool m_isEof = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,14 @@
|
||||||
using namespace ISO9660;
|
using namespace ISO9660;
|
||||||
|
|
||||||
CISO9660::CISO9660(const BlockProviderPtr& blockProvider)
|
CISO9660::CISO9660(const BlockProviderPtr& blockProvider)
|
||||||
: m_blockProvider(blockProvider)
|
: m_blockProvider(blockProvider)
|
||||||
, m_volumeDescriptor(blockProvider.get())
|
, m_volumeDescriptor(blockProvider.get())
|
||||||
, m_pathTable(blockProvider.get(), m_volumeDescriptor.GetLPathTableAddress())
|
, m_pathTable(blockProvider.get(), m_volumeDescriptor.GetLPathTableAddress())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CISO9660::~CISO9660()
|
CISO9660::~CISO9660()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CISO9660::ReadBlock(uint32 address, void* data)
|
void CISO9660::ReadBlock(uint32 address, void* data)
|
||||||
|
|
|
@ -11,20 +11,20 @@ class CISO9660
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<ISO9660::CBlockProvider> BlockProviderPtr;
|
typedef std::shared_ptr<ISO9660::CBlockProvider> BlockProviderPtr;
|
||||||
|
|
||||||
CISO9660(const BlockProviderPtr&);
|
CISO9660(const BlockProviderPtr&);
|
||||||
~CISO9660();
|
~CISO9660();
|
||||||
|
|
||||||
void ReadBlock(uint32, void*);
|
void ReadBlock(uint32, void*);
|
||||||
|
|
||||||
Framework::CStream* Open(const char*);
|
Framework::CStream* Open(const char*);
|
||||||
bool GetFileRecord(ISO9660::CDirectoryRecord*, const char*);
|
bool GetFileRecord(ISO9660::CDirectoryRecord*, const char*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GetFileRecordFromDirectory(ISO9660::CDirectoryRecord*, uint32, const char*);
|
bool GetFileRecordFromDirectory(ISO9660::CDirectoryRecord*, uint32, const char*);
|
||||||
|
|
||||||
BlockProviderPtr m_blockProvider;
|
BlockProviderPtr m_blockProvider;
|
||||||
ISO9660::CVolumeDescriptor m_volumeDescriptor;
|
ISO9660::CVolumeDescriptor m_volumeDescriptor;
|
||||||
ISO9660::CPathTable m_pathTable;
|
ISO9660::CPathTable m_pathTable;
|
||||||
|
|
||||||
uint8 m_blockBuffer[ISO9660::CBlockProvider::BLOCKSIZE];
|
uint8 m_blockBuffer[ISO9660::CBlockProvider::BLOCKSIZE];
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,6 @@ CPathTable::CPathTable(CBlockProvider* blockProvider, uint32 tableLba)
|
||||||
|
|
||||||
CPathTable::~CPathTable()
|
CPathTable::~CPathTable()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 CPathTable::GetDirectoryAddress(unsigned int recordIndex) const
|
uint32 CPathTable::GetDirectoryAddress(unsigned int recordIndex) const
|
||||||
|
|
|
@ -11,17 +11,16 @@ namespace ISO9660
|
||||||
class CPathTable
|
class CPathTable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPathTable(CBlockProvider*, uint32);
|
CPathTable(CBlockProvider*, uint32);
|
||||||
~CPathTable();
|
~CPathTable();
|
||||||
|
|
||||||
unsigned int FindRoot() const;
|
unsigned int FindRoot() const;
|
||||||
unsigned int FindDirectory(const char*, unsigned int) const;
|
unsigned int FindDirectory(const char*, unsigned int) const;
|
||||||
uint32 GetDirectoryAddress(unsigned int) const;
|
uint32 GetDirectoryAddress(unsigned int) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<size_t, CPathTableRecord> RecordMapType;
|
typedef std::map<size_t, CPathTableRecord> RecordMapType;
|
||||||
|
|
||||||
RecordMapType m_records;
|
RecordMapType m_records;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ CPathTableRecord::CPathTableRecord(Framework::CStream& stream)
|
||||||
|
|
||||||
CPathTableRecord::~CPathTableRecord()
|
CPathTableRecord::~CPathTableRecord()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 CPathTableRecord::GetNameLength() const
|
uint8 CPathTableRecord::GetNameLength() const
|
||||||
|
|
|
@ -9,19 +9,19 @@ namespace ISO9660
|
||||||
class CPathTableRecord
|
class CPathTableRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPathTableRecord(Framework::CStream&);
|
CPathTableRecord(Framework::CStream&);
|
||||||
~CPathTableRecord();
|
~CPathTableRecord();
|
||||||
|
|
||||||
uint8 GetNameLength() const;
|
uint8 GetNameLength() const;
|
||||||
uint32 GetAddress() const;
|
uint32 GetAddress() const;
|
||||||
uint32 GetParentRecord() const;
|
uint32 GetParentRecord() const;
|
||||||
const char* GetName() const;
|
const char* GetName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 m_nameLength = 0;
|
uint8 m_nameLength = 0;
|
||||||
uint8 m_exLength = 0;
|
uint8 m_exLength = 0;
|
||||||
uint32 m_location = 0;
|
uint32 m_location = 0;
|
||||||
uint16 m_parentDir = 0;
|
uint16 m_parentDir = 0;
|
||||||
std::string m_directory;
|
std::string m_directory;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ using namespace ISO9660;
|
||||||
CVolumeDescriptor::CVolumeDescriptor(CBlockProvider* blockProvider)
|
CVolumeDescriptor::CVolumeDescriptor(CBlockProvider* blockProvider)
|
||||||
{
|
{
|
||||||
CFile stream(blockProvider, VOLUME_DESCRIPTOR_LBA * CBlockProvider::BLOCKSIZE);
|
CFile stream(blockProvider, VOLUME_DESCRIPTOR_LBA * CBlockProvider::BLOCKSIZE);
|
||||||
|
|
||||||
stream.Read(&m_type, 1);
|
stream.Read(&m_type, 1);
|
||||||
|
|
||||||
if(m_type != 0x01)
|
if(m_type != 0x01)
|
||||||
|
@ -39,7 +39,6 @@ CVolumeDescriptor::CVolumeDescriptor(CBlockProvider* blockProvider)
|
||||||
|
|
||||||
CVolumeDescriptor::~CVolumeDescriptor()
|
CVolumeDescriptor::~CVolumeDescriptor()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 CVolumeDescriptor::GetLPathTableAddress() const
|
uint32 CVolumeDescriptor::GetLPathTableAddress() const
|
||||||
|
|
|
@ -8,18 +8,17 @@ namespace ISO9660
|
||||||
class CVolumeDescriptor
|
class CVolumeDescriptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CVolumeDescriptor(CBlockProvider*);
|
CVolumeDescriptor(CBlockProvider*);
|
||||||
~CVolumeDescriptor();
|
~CVolumeDescriptor();
|
||||||
|
|
||||||
uint32 GetLPathTableAddress() const;
|
uint32 GetLPathTableAddress() const;
|
||||||
uint32 GetMPathTableAddress() const;
|
uint32 GetMPathTableAddress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 m_type = 0;
|
uint8 m_type = 0;
|
||||||
char m_stdId[6];
|
char m_stdId[6];
|
||||||
char m_volumeId[33];
|
char m_volumeId[33];
|
||||||
uint32 m_LPathTableAddress = 0;
|
uint32 m_LPathTableAddress = 0;
|
||||||
uint32 m_MPathTableAddress = 0;
|
uint32 m_MPathTableAddress = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
|
|
||||||
struct INTEGER64
|
struct INTEGER64
|
||||||
{
|
{
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
uint64 q;
|
uint64 q;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "StdStream.h"
|
#include "StdStream.h"
|
||||||
|
|
||||||
CIszImageStream::CIszImageStream(CStream* baseStream)
|
CIszImageStream::CIszImageStream(CStream* baseStream)
|
||||||
: m_baseStream(baseStream)
|
: m_baseStream(baseStream)
|
||||||
{
|
{
|
||||||
if(baseStream == nullptr)
|
if(baseStream == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -36,9 +36,9 @@ CIszImageStream::CIszImageStream(CStream* baseStream)
|
||||||
|
|
||||||
CIszImageStream::~CIszImageStream()
|
CIszImageStream::~CIszImageStream()
|
||||||
{
|
{
|
||||||
delete [] m_cachedBlock;
|
delete[] m_cachedBlock;
|
||||||
delete [] m_readBuffer;
|
delete[] m_readBuffer;
|
||||||
delete [] m_blockDescriptorTable;
|
delete[] m_blockDescriptorTable;
|
||||||
delete m_baseStream;
|
delete m_baseStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void CIszImageStream::ReadBlockDescriptorTable()
|
||||||
m_blockDescriptorTable[i].storageType = static_cast<uint8>(value >> 22);
|
m_blockDescriptorTable[i].storageType = static_cast<uint8>(value >> 22);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] cryptedTable;
|
delete[] cryptedTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 CIszImageStream::GetTotalSize() const
|
uint64 CIszImageStream::GetTotalSize() const
|
||||||
|
@ -199,8 +199,8 @@ void CIszImageStream::ReadGzipBlock(uint32 compressedBlockSize)
|
||||||
m_baseStream->Read(m_readBuffer, compressedBlockSize);
|
m_baseStream->Read(m_readBuffer, compressedBlockSize);
|
||||||
uLongf destLength = m_header.blockSize;
|
uLongf destLength = m_header.blockSize;
|
||||||
if(uncompress(
|
if(uncompress(
|
||||||
reinterpret_cast<Bytef*>(m_cachedBlock), &destLength,
|
reinterpret_cast<Bytef*>(m_cachedBlock), &destLength,
|
||||||
reinterpret_cast<Bytef*>(m_readBuffer), compressedBlockSize) != Z_OK)
|
reinterpret_cast<Bytef*>(m_readBuffer), compressedBlockSize) != Z_OK)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Error decompressing zlib block.");
|
throw std::runtime_error("Error decompressing zlib block.");
|
||||||
}
|
}
|
||||||
|
@ -215,8 +215,8 @@ void CIszImageStream::ReadBz2Block(uint32 compressedBlockSize)
|
||||||
m_readBuffer[2] = 'h';
|
m_readBuffer[2] = 'h';
|
||||||
unsigned int destLength = m_header.blockSize;
|
unsigned int destLength = m_header.blockSize;
|
||||||
if(BZ2_bzBuffToBuffDecompress(
|
if(BZ2_bzBuffToBuffDecompress(
|
||||||
reinterpret_cast<char*>(m_cachedBlock), &destLength,
|
reinterpret_cast<char*>(m_cachedBlock), &destLength,
|
||||||
reinterpret_cast<char*>(m_readBuffer), compressedBlockSize, 0, 0) != BZ_OK)
|
reinterpret_cast<char*>(m_readBuffer), compressedBlockSize, 0, 0) != BZ_OK)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Error decompressing bz2 block.");
|
throw std::runtime_error("Error decompressing bz2 block.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,49 +6,49 @@
|
||||||
class CIszImageStream : public Framework::CStream
|
class CIszImageStream : public Framework::CStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CIszImageStream(Framework::CStream*);
|
CIszImageStream(Framework::CStream*);
|
||||||
virtual ~CIszImageStream();
|
virtual ~CIszImageStream();
|
||||||
|
|
||||||
virtual void Seek(int64, Framework::STREAM_SEEK_DIRECTION) override;
|
virtual void Seek(int64, Framework::STREAM_SEEK_DIRECTION) override;
|
||||||
virtual uint64 Tell() override;
|
virtual uint64 Tell() override;
|
||||||
virtual uint64 Read(void*, uint64) override;
|
virtual uint64 Read(void*, uint64) override;
|
||||||
virtual uint64 Write(const void*, uint64) override;
|
virtual uint64 Write(const void*, uint64) override;
|
||||||
virtual bool IsEOF() override;
|
virtual bool IsEOF() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct HEADER
|
struct HEADER
|
||||||
{
|
{
|
||||||
char signature[4];
|
char signature[4];
|
||||||
uint8 headerSize;
|
uint8 headerSize;
|
||||||
int8 version;
|
int8 version;
|
||||||
uint32 volumeSerialNumber;
|
uint32 volumeSerialNumber;
|
||||||
|
|
||||||
uint16 sectorSize;
|
uint16 sectorSize;
|
||||||
uint32 totalSectors;
|
uint32 totalSectors;
|
||||||
|
|
||||||
int8 hasPassword;
|
int8 hasPassword;
|
||||||
|
|
||||||
int64 segmentSize;
|
int64 segmentSize;
|
||||||
|
|
||||||
uint32 blockNumber;
|
uint32 blockNumber;
|
||||||
uint32 blockSize;
|
uint32 blockSize;
|
||||||
uint8 blockPtrLength;
|
uint8 blockPtrLength;
|
||||||
|
|
||||||
int8 segmentNumber;
|
int8 segmentNumber;
|
||||||
|
|
||||||
uint32 blockPtrOffset;
|
uint32 blockPtrOffset;
|
||||||
uint32 segmentPtrOffset;
|
uint32 segmentPtrOffset;
|
||||||
uint32 dataOffset;
|
uint32 dataOffset;
|
||||||
|
|
||||||
int8 reserved;
|
int8 reserved;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct BLOCKDESCRIPTOR
|
struct BLOCKDESCRIPTOR
|
||||||
{
|
{
|
||||||
uint32 size;
|
uint32 size;
|
||||||
uint8 storageType;
|
uint8 storageType;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HASPASSWORD
|
enum HASPASSWORD
|
||||||
|
@ -68,21 +68,21 @@ private:
|
||||||
ADI_BZ2 = 3
|
ADI_BZ2 = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
void ReadBlockDescriptorTable();
|
void ReadBlockDescriptorTable();
|
||||||
uint64 GetTotalSize() const;
|
uint64 GetTotalSize() const;
|
||||||
const BLOCKDESCRIPTOR& SeekToBlock(uint64);
|
const BLOCKDESCRIPTOR& SeekToBlock(uint64);
|
||||||
void SyncCache();
|
void SyncCache();
|
||||||
|
|
||||||
void ReadZeroBlock(uint32);
|
void ReadZeroBlock(uint32);
|
||||||
void ReadDataBlock(uint32);
|
void ReadDataBlock(uint32);
|
||||||
void ReadGzipBlock(uint32);
|
void ReadGzipBlock(uint32);
|
||||||
void ReadBz2Block(uint32);
|
void ReadBz2Block(uint32);
|
||||||
|
|
||||||
Framework::CStream* m_baseStream = nullptr;
|
Framework::CStream* m_baseStream = nullptr;
|
||||||
HEADER m_header;
|
HEADER m_header;
|
||||||
BLOCKDESCRIPTOR* m_blockDescriptorTable = nullptr;
|
BLOCKDESCRIPTOR* m_blockDescriptorTable = nullptr;
|
||||||
int64 m_cachedBlockNumber = -1;
|
int64 m_cachedBlockNumber = -1;
|
||||||
uint8* m_cachedBlock = nullptr;
|
uint8* m_cachedBlock = nullptr;
|
||||||
uint8* m_readBuffer = nullptr;
|
uint8* m_readBuffer = nullptr;
|
||||||
uint64 m_position = 0;
|
uint64 m_position = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,6 @@ CLog::CLog()
|
||||||
|
|
||||||
CLog::~CLog()
|
CLog::~CLog()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::Print(const char* logName, const char* format, ...)
|
void CLog::Print(const char* logName, const char* format, ...)
|
||||||
|
|
12
Source/Log.h
12
Source/Log.h
|
@ -10,18 +10,18 @@
|
||||||
class CLog : public CSingleton<CLog>
|
class CLog : public CSingleton<CLog>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CLog();
|
CLog();
|
||||||
virtual ~CLog();
|
virtual ~CLog();
|
||||||
|
|
||||||
void Print(const char*, const char*, ...);
|
void Print(const char*, const char*, ...);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, Framework::CStdStream> LogMapType;
|
typedef std::map<std::string, Framework::CStdStream> LogMapType;
|
||||||
|
|
||||||
Framework::CStdStream& GetLog(const char*);
|
Framework::CStdStream& GetLog(const char*);
|
||||||
|
|
||||||
boost::filesystem::path m_logBasePath;
|
boost::filesystem::path m_logBasePath;
|
||||||
LogMapType m_logs;
|
LogMapType m_logs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,43 +8,43 @@
|
||||||
#include "placeholder_def.h"
|
#include "placeholder_def.h"
|
||||||
|
|
||||||
uint32 g_LWMaskRight[4] =
|
uint32 g_LWMaskRight[4] =
|
||||||
{
|
{
|
||||||
0x00FFFFFF,
|
0x00FFFFFF,
|
||||||
0x0000FFFF,
|
0x0000FFFF,
|
||||||
0x000000FF,
|
0x000000FF,
|
||||||
0x00000000,
|
0x00000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 g_LWMaskLeft[4] =
|
uint32 g_LWMaskLeft[4] =
|
||||||
{
|
{
|
||||||
0xFFFFFF00,
|
0xFFFFFF00,
|
||||||
0xFFFF0000,
|
0xFFFF0000,
|
||||||
0xFF000000,
|
0xFF000000,
|
||||||
0x00000000,
|
0x00000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64 g_LDMaskRight[8] =
|
uint64 g_LDMaskRight[8] =
|
||||||
{
|
{
|
||||||
0x00FFFFFFFFFFFFFFULL,
|
0x00FFFFFFFFFFFFFFULL,
|
||||||
0x0000FFFFFFFFFFFFULL,
|
0x0000FFFFFFFFFFFFULL,
|
||||||
0x000000FFFFFFFFFFULL,
|
0x000000FFFFFFFFFFULL,
|
||||||
0x00000000FFFFFFFFULL,
|
0x00000000FFFFFFFFULL,
|
||||||
0x0000000000FFFFFFULL,
|
0x0000000000FFFFFFULL,
|
||||||
0x000000000000FFFFULL,
|
0x000000000000FFFFULL,
|
||||||
0x00000000000000FFULL,
|
0x00000000000000FFULL,
|
||||||
0x0000000000000000ULL,
|
0x0000000000000000ULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64 g_LDMaskLeft[8] =
|
uint64 g_LDMaskLeft[8] =
|
||||||
{
|
{
|
||||||
0xFFFFFFFFFFFFFF00ULL,
|
0xFFFFFFFFFFFFFF00ULL,
|
||||||
0xFFFFFFFFFFFF0000ULL,
|
0xFFFFFFFFFFFF0000ULL,
|
||||||
0xFFFFFFFFFF000000ULL,
|
0xFFFFFFFFFF000000ULL,
|
||||||
0xFFFFFFFF00000000ULL,
|
0xFFFFFFFF00000000ULL,
|
||||||
0xFFFFFF0000000000ULL,
|
0xFFFFFF0000000000ULL,
|
||||||
0xFFFF000000000000ULL,
|
0xFFFF000000000000ULL,
|
||||||
0xFF00000000000000ULL,
|
0xFF00000000000000ULL,
|
||||||
0x0000000000000000ULL,
|
0x0000000000000000ULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" uint32 LWL_Proxy(uint32 address, uint32 rt, CMIPS* context)
|
extern "C" uint32 LWL_Proxy(uint32 address, uint32 rt, CMIPS* context)
|
||||||
|
@ -143,8 +143,8 @@ extern "C" void SDR_Proxy(uint32 address, uint64 rt, CMIPS* context)
|
||||||
MemoryUtils_SetDoubleProxy(context, memory, alignedAddress);
|
MemoryUtils_SetDoubleProxy(context, memory, alignedAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMA_MIPSIV::CMA_MIPSIV(MIPS_REGSIZE nRegSize) :
|
CMA_MIPSIV::CMA_MIPSIV(MIPS_REGSIZE nRegSize)
|
||||||
CMIPSArchitecture(nRegSize)
|
: CMIPSArchitecture(nRegSize)
|
||||||
{
|
{
|
||||||
SetupInstructionTables();
|
SetupInstructionTables();
|
||||||
SetupReflectionTables();
|
SetupReflectionTables();
|
||||||
|
@ -152,7 +152,6 @@ CMIPSArchitecture(nRegSize)
|
||||||
|
|
||||||
CMA_MIPSIV::~CMA_MIPSIV()
|
CMA_MIPSIV::~CMA_MIPSIV()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMA_MIPSIV::SetupInstructionTables()
|
void CMA_MIPSIV::SetupInstructionTables()
|
||||||
|
@ -182,11 +181,11 @@ void CMA_MIPSIV::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, CMIPS
|
||||||
{
|
{
|
||||||
SetupQuickVariables(nAddress, codeGen, pCtx);
|
SetupQuickVariables(nAddress, codeGen, pCtx);
|
||||||
|
|
||||||
m_nRS = (uint8)((m_nOpcode >> 21) & 0x1F);
|
m_nRS = (uint8)((m_nOpcode >> 21) & 0x1F);
|
||||||
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
|
m_nRT = (uint8)((m_nOpcode >> 16) & 0x1F);
|
||||||
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);
|
m_nRD = (uint8)((m_nOpcode >> 11) & 0x1F);
|
||||||
m_nSA = (uint8)((m_nOpcode >> 6) & 0x1F);
|
m_nSA = (uint8)((m_nOpcode >> 6) & 0x1F);
|
||||||
m_nImmediate = (uint16)(m_nOpcode & 0xFFFF);
|
m_nImmediate = (uint16)(m_nOpcode & 0xFFFF);
|
||||||
|
|
||||||
if(m_nOpcode)
|
if(m_nOpcode)
|
||||||
{
|
{
|
||||||
|
@ -278,7 +277,7 @@ void CMA_MIPSIV::ADDI()
|
||||||
//09
|
//09
|
||||||
void CMA_MIPSIV::ADDIU()
|
void CMA_MIPSIV::ADDIU()
|
||||||
{
|
{
|
||||||
if(m_nRT == 0 && m_nRS == 0)
|
if(m_nRT == 0 && m_nRS == 0)
|
||||||
{
|
{
|
||||||
//Hack: PS2 IOP uses ADDIU R0, R0, $x for dynamic linking
|
//Hack: PS2 IOP uses ADDIU R0, R0, $x for dynamic linking
|
||||||
m_codeGen->PushCst(m_nAddress);
|
m_codeGen->PushCst(m_nAddress);
|
||||||
|
@ -323,7 +322,7 @@ void CMA_MIPSIV::ANDI()
|
||||||
|
|
||||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
||||||
m_codeGen->PushCst(m_nImmediate);
|
m_codeGen->PushCst(m_nImmediate);
|
||||||
|
|
||||||
m_codeGen->And();
|
m_codeGen->And();
|
||||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
|
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
|
||||||
|
|
||||||
|
@ -805,14 +804,14 @@ void CMA_MIPSIV::SLL()
|
||||||
//02
|
//02
|
||||||
void CMA_MIPSIV::SRL()
|
void CMA_MIPSIV::SRL()
|
||||||
{
|
{
|
||||||
void (Jitter::CJitter::*shiftFunction)(uint8) = &Jitter::CJitter::Srl;
|
void (Jitter::CJitter::*shiftFunction)(uint8) = &Jitter::CJitter::Srl;
|
||||||
Template_ShiftCst32(std::bind(shiftFunction, m_codeGen, std::placeholders::_1));
|
Template_ShiftCst32(std::bind(shiftFunction, m_codeGen, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
//03
|
//03
|
||||||
void CMA_MIPSIV::SRA()
|
void CMA_MIPSIV::SRA()
|
||||||
{
|
{
|
||||||
void (Jitter::CJitter::*shiftFunction)(uint8) = &Jitter::CJitter::Sra;
|
void (Jitter::CJitter::*shiftFunction)(uint8) = &Jitter::CJitter::Sra;
|
||||||
Template_ShiftCst32(std::bind(shiftFunction, m_codeGen, std::placeholders::_1));
|
Template_ShiftCst32(std::bind(shiftFunction, m_codeGen, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,7 +825,7 @@ void CMA_MIPSIV::SLLV()
|
||||||
//06
|
//06
|
||||||
void CMA_MIPSIV::SRLV()
|
void CMA_MIPSIV::SRLV()
|
||||||
{
|
{
|
||||||
void (Jitter::CJitter::*shiftFunction)() = &Jitter::CJitter::Srl;
|
void (Jitter::CJitter::*shiftFunction)() = &Jitter::CJitter::Srl;
|
||||||
Template_ShiftVar32(std::bind(shiftFunction, m_codeGen));
|
Template_ShiftVar32(std::bind(shiftFunction, m_codeGen));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
class CMA_MIPSIV : public CMIPSArchitecture
|
class CMA_MIPSIV : public CMIPSArchitecture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMA_MIPSIV(MIPS_REGSIZE);
|
CMA_MIPSIV(MIPS_REGSIZE);
|
||||||
virtual ~CMA_MIPSIV();
|
virtual ~CMA_MIPSIV();
|
||||||
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*);
|
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*);
|
||||||
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
|
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
|
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
virtual MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);
|
virtual MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32);
|
||||||
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
|
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum
|
enum
|
||||||
|
@ -24,55 +24,55 @@ protected:
|
||||||
MAX_REGIMM_OPS = 0x20,
|
MAX_REGIMM_OPS = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<void ()> InstructionFunction;
|
typedef std::function<void()> InstructionFunction;
|
||||||
|
|
||||||
InstructionFunction m_pOpGeneral[MAX_GENERAL_OPS];
|
InstructionFunction m_pOpGeneral[MAX_GENERAL_OPS];
|
||||||
InstructionFunction m_pOpSpecial[MAX_SPECIAL_OPS];
|
InstructionFunction m_pOpSpecial[MAX_SPECIAL_OPS];
|
||||||
InstructionFunction m_pOpSpecial2[MAX_SPECIAL2_OPS];
|
InstructionFunction m_pOpSpecial2[MAX_SPECIAL2_OPS];
|
||||||
InstructionFunction m_pOpRegImm[MAX_REGIMM_OPS];
|
InstructionFunction m_pOpRegImm[MAX_REGIMM_OPS];
|
||||||
|
|
||||||
static void ReflOpTarget(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpTarget(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRtRsImm(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtRsImm(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRtImm(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtImm(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRsRtOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRsRtOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRsOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRsOff(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRtOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRtOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpHintOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpHintOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpIdOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpIdOffRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRdRsRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRdRsRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRdRtSa(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRdRtSa(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRdRtRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRdRtRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRd(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRd(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRdRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRdRs(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static void ReflOpRsRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflOpRsRt(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
|
|
||||||
static uint32 ReflEaTarget(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
static uint32 ReflEaTarget(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
static uint32 ReflEaOffset(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
|
|
||||||
static void ReflCOPMnemonic(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
static void ReflCOPMnemonic(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||||
static void ReflCOPOperands(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
static void ReflCOPOperands(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
static MIPS_BRANCH_TYPE ReflCOPIsBranch(MIPSReflection::INSTRUCTION*, CMIPS*, uint32);
|
static MIPS_BRANCH_TYPE ReflCOPIsBranch(MIPSReflection::INSTRUCTION*, CMIPS*, uint32);
|
||||||
static uint32 ReflCOPEffeAddr(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
static uint32 ReflCOPEffeAddr(MIPSReflection::INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
|
|
||||||
MIPSReflection::INSTRUCTION m_ReflGeneral[MAX_GENERAL_OPS];
|
MIPSReflection::INSTRUCTION m_ReflGeneral[MAX_GENERAL_OPS];
|
||||||
MIPSReflection::INSTRUCTION m_ReflSpecial[MAX_SPECIAL_OPS];
|
MIPSReflection::INSTRUCTION m_ReflSpecial[MAX_SPECIAL_OPS];
|
||||||
MIPSReflection::INSTRUCTION m_ReflRegImm[MAX_REGIMM_OPS];
|
MIPSReflection::INSTRUCTION m_ReflRegImm[MAX_REGIMM_OPS];
|
||||||
|
|
||||||
MIPSReflection::SUBTABLE m_ReflGeneralTable;
|
MIPSReflection::SUBTABLE m_ReflGeneralTable;
|
||||||
MIPSReflection::SUBTABLE m_ReflSpecialTable;
|
MIPSReflection::SUBTABLE m_ReflSpecialTable;
|
||||||
MIPSReflection::SUBTABLE m_ReflRegImmTable;
|
MIPSReflection::SUBTABLE m_ReflRegImmTable;
|
||||||
|
|
||||||
uint8 m_nRS;
|
uint8 m_nRS;
|
||||||
uint8 m_nRT;
|
uint8 m_nRT;
|
||||||
uint8 m_nRD;
|
uint8 m_nRD;
|
||||||
uint8 m_nSA;
|
uint8 m_nSA;
|
||||||
uint16 m_nImmediate;
|
uint16 m_nImmediate;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//Instruction compiler templates
|
//Instruction compiler templates
|
||||||
typedef std::function<void (uint8)> TemplateParamedOperationFunctionType;
|
typedef std::function<void(uint8)> TemplateParamedOperationFunctionType;
|
||||||
typedef std::function<void ()> TemplateOperationFunctionType;
|
typedef std::function<void()> TemplateOperationFunctionType;
|
||||||
|
|
||||||
void Template_Add32(bool);
|
void Template_Add32(bool);
|
||||||
void Template_Add64(bool);
|
void Template_Add64(bool);
|
||||||
|
@ -91,131 +91,131 @@ protected:
|
||||||
void Template_BranchLez(bool, bool);
|
void Template_BranchLez(bool, bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupInstructionTables();
|
void SetupInstructionTables();
|
||||||
void SetupReflectionTables();
|
void SetupReflectionTables();
|
||||||
|
|
||||||
void SPECIAL();
|
void SPECIAL();
|
||||||
void SPECIAL2();
|
void SPECIAL2();
|
||||||
void REGIMM();
|
void REGIMM();
|
||||||
|
|
||||||
//General
|
//General
|
||||||
void J();
|
void J();
|
||||||
void JAL();
|
void JAL();
|
||||||
void BEQ();
|
void BEQ();
|
||||||
void BNE();
|
void BNE();
|
||||||
void BLEZ();
|
void BLEZ();
|
||||||
void BGTZ();
|
void BGTZ();
|
||||||
void ADDI();
|
void ADDI();
|
||||||
void ADDIU();
|
void ADDIU();
|
||||||
void SLTI();
|
void SLTI();
|
||||||
void SLTIU();
|
void SLTIU();
|
||||||
void ANDI();
|
void ANDI();
|
||||||
void ORI();
|
void ORI();
|
||||||
void XORI();
|
void XORI();
|
||||||
void LUI();
|
void LUI();
|
||||||
void COP0();
|
void COP0();
|
||||||
void COP1();
|
void COP1();
|
||||||
void COP2();
|
void COP2();
|
||||||
void BEQL();
|
void BEQL();
|
||||||
void BNEL();
|
void BNEL();
|
||||||
void BLEZL();
|
void BLEZL();
|
||||||
void BGTZL();
|
void BGTZL();
|
||||||
void DADDI();
|
void DADDI();
|
||||||
void DADDIU();
|
void DADDIU();
|
||||||
void LDL();
|
void LDL();
|
||||||
void LDR();
|
void LDR();
|
||||||
void LB();
|
void LB();
|
||||||
void LH();
|
void LH();
|
||||||
void LWL();
|
void LWL();
|
||||||
void LW();
|
void LW();
|
||||||
void LBU();
|
void LBU();
|
||||||
void LHU();
|
void LHU();
|
||||||
void LWR();
|
void LWR();
|
||||||
void LWU();
|
void LWU();
|
||||||
void SB();
|
void SB();
|
||||||
void SH();
|
void SH();
|
||||||
void SWL();
|
void SWL();
|
||||||
void SW();
|
void SW();
|
||||||
void SDL();
|
void SDL();
|
||||||
void SDR();
|
void SDR();
|
||||||
void SWR();
|
void SWR();
|
||||||
void CACHE();
|
void CACHE();
|
||||||
void LWC1();
|
void LWC1();
|
||||||
void PREF();
|
void PREF();
|
||||||
void LDC2();
|
void LDC2();
|
||||||
void LD();
|
void LD();
|
||||||
void SWC1();
|
void SWC1();
|
||||||
void SDC2();
|
void SDC2();
|
||||||
void SD();
|
void SD();
|
||||||
|
|
||||||
//Special
|
//Special
|
||||||
void SLL();
|
void SLL();
|
||||||
void SRL();
|
void SRL();
|
||||||
void SRA();
|
void SRA();
|
||||||
void SLLV();
|
void SLLV();
|
||||||
void SRLV();
|
void SRLV();
|
||||||
void SRAV();
|
void SRAV();
|
||||||
void JR();
|
void JR();
|
||||||
void JALR();
|
void JALR();
|
||||||
void MOVZ();
|
void MOVZ();
|
||||||
void MOVN();
|
void MOVN();
|
||||||
void SYSCALL();
|
void SYSCALL();
|
||||||
void BREAK();
|
void BREAK();
|
||||||
void SYNC();
|
void SYNC();
|
||||||
void DSLLV();
|
void DSLLV();
|
||||||
void DSRLV();
|
void DSRLV();
|
||||||
void DSRAV();
|
void DSRAV();
|
||||||
void MFHI();
|
void MFHI();
|
||||||
void MTHI();
|
void MTHI();
|
||||||
void MFLO();
|
void MFLO();
|
||||||
void MTLO();
|
void MTLO();
|
||||||
void MULT();
|
void MULT();
|
||||||
void MULTU();
|
void MULTU();
|
||||||
void DIV();
|
void DIV();
|
||||||
void DIVU();
|
void DIVU();
|
||||||
void ADD();
|
void ADD();
|
||||||
void ADDU();
|
void ADDU();
|
||||||
void SUB();
|
void SUB();
|
||||||
void SUBU();
|
void SUBU();
|
||||||
void AND();
|
void AND();
|
||||||
void OR();
|
void OR();
|
||||||
void XOR();
|
void XOR();
|
||||||
void NOR();
|
void NOR();
|
||||||
void SLT();
|
void SLT();
|
||||||
void SLTU();
|
void SLTU();
|
||||||
void DADD();
|
void DADD();
|
||||||
void DADDU();
|
void DADDU();
|
||||||
void DSUB();
|
void DSUB();
|
||||||
void DSUBU();
|
void DSUBU();
|
||||||
void TEQ();
|
void TEQ();
|
||||||
void DSLL();
|
void DSLL();
|
||||||
void DSRL();
|
void DSRL();
|
||||||
void DSRA();
|
void DSRA();
|
||||||
void DSLL32();
|
void DSLL32();
|
||||||
void DSRL32();
|
void DSRL32();
|
||||||
void DSRA32();
|
void DSRA32();
|
||||||
|
|
||||||
//Special2
|
//Special2
|
||||||
|
|
||||||
//RegImm
|
//RegImm
|
||||||
void BLTZ();
|
void BLTZ();
|
||||||
void BGEZ();
|
void BGEZ();
|
||||||
void BLTZL();
|
void BLTZL();
|
||||||
void BGEZL();
|
void BGEZL();
|
||||||
void BLTZAL();
|
void BLTZAL();
|
||||||
void BGEZAL();
|
void BGEZAL();
|
||||||
void BLTZALL();
|
void BLTZALL();
|
||||||
void BGEZALL();
|
void BGEZALL();
|
||||||
|
|
||||||
//Opcode tables
|
//Opcode tables
|
||||||
typedef void (CMA_MIPSIV::*InstructionFuncConstant)();
|
typedef void (CMA_MIPSIV::*InstructionFuncConstant)();
|
||||||
|
|
||||||
static InstructionFuncConstant m_cOpGeneral[MAX_GENERAL_OPS];
|
static InstructionFuncConstant m_cOpGeneral[MAX_GENERAL_OPS];
|
||||||
static InstructionFuncConstant m_cOpSpecial[MAX_SPECIAL_OPS];
|
static InstructionFuncConstant m_cOpSpecial[MAX_SPECIAL_OPS];
|
||||||
static InstructionFuncConstant m_cOpRegImm[MAX_REGIMM_OPS];
|
static InstructionFuncConstant m_cOpRegImm[MAX_REGIMM_OPS];
|
||||||
|
|
||||||
//Reflection tables
|
//Reflection tables
|
||||||
static MIPSReflection::INSTRUCTION m_cReflGeneral[MAX_GENERAL_OPS];
|
static MIPSReflection::INSTRUCTION m_cReflGeneral[MAX_GENERAL_OPS];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflSpecial[MAX_SPECIAL_OPS];
|
static MIPSReflection::INSTRUCTION m_cReflSpecial[MAX_SPECIAL_OPS];
|
||||||
static MIPSReflection::INSTRUCTION m_cReflRegImm[MAX_REGIMM_OPS];
|
static MIPSReflection::INSTRUCTION m_cReflRegImm[MAX_REGIMM_OPS];
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,9 +16,9 @@ void CMA_MIPSIV::ReflOpRtRsImm(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress
|
||||||
uint8 nRS, nRT;
|
uint8 nRS, nRT;
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
nRS = (uint8)((nOpcode >> 21) & 0x001F);
|
||||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
sprintf(sText, "%s, %s, $%04X", CMIPS::m_sGPRName[nRT], CMIPS::m_sGPRName[nRS], nImm);
|
sprintf(sText, "%s, %s, $%04X", CMIPS::m_sGPRName[nRT], CMIPS::m_sGPRName[nRS], nImm);
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ void CMA_MIPSIV::ReflOpRtImm(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress,
|
||||||
uint8 nRT;
|
uint8 nRT;
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
sprintf(sText, "%s, $%04X", CMIPS::m_sGPRName[nRT], nImm);
|
sprintf(sText, "%s, $%04X", CMIPS::m_sGPRName[nRT], nImm);
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,9 @@ void CMA_MIPSIV::ReflOpRsRtOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress
|
||||||
uint8 nRS, nRT;
|
uint8 nRS, nRT;
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
nRS = (uint8)((nOpcode >> 21) & 0x001F);
|
||||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "%s, %s, $%08X", CMIPS::m_sGPRName[nRS], CMIPS::m_sGPRName[nRT], (nAddress + CMIPS::GetBranch(nImm)));
|
sprintf(sText, "%s, %s, $%08X", CMIPS::m_sGPRName[nRS], CMIPS::m_sGPRName[nRT], (nAddress + CMIPS::GetBranch(nImm)));
|
||||||
|
@ -52,8 +52,8 @@ void CMA_MIPSIV::ReflOpRsOff(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress,
|
||||||
uint8 nRS;
|
uint8 nRS;
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
nRS = (uint8)((nOpcode >> 21) & 0x001F);
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "%s, $%08X", CMIPS::m_sGPRName[nRS], (nAddress + CMIPS::GetBranch(nImm)));
|
sprintf(sText, "%s, $%08X", CMIPS::m_sGPRName[nRS], (nAddress + CMIPS::GetBranch(nImm)));
|
||||||
|
@ -64,9 +64,9 @@ void CMA_MIPSIV::ReflOpRtOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress
|
||||||
uint8 nRS, nRT;
|
uint8 nRS, nRT;
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
nRS = (uint8)((nOpcode >> 21) & 0x001F);
|
||||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "%s, $%04X(%s)", CMIPS::m_sGPRName[nRT], nImm, CMIPS::m_sGPRName[nRS]);
|
sprintf(sText, "%s, $%04X(%s)", CMIPS::m_sGPRName[nRT], nImm, CMIPS::m_sGPRName[nRS]);
|
||||||
|
@ -74,9 +74,9 @@ void CMA_MIPSIV::ReflOpRtOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress
|
||||||
|
|
||||||
void CMA_MIPSIV::ReflOpHintOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CMA_MIPSIV::ReflOpHintOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
uint8 nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
uint8 nRS = (uint8)((nOpcode >> 21) & 0x001F);
|
||||||
uint8 nHint = (uint8) ((nOpcode >> 16) & 0x001F);
|
uint8 nHint = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
uint16 nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
uint16 nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "%i, $%04X(%s)", nHint, nImm, CMIPS::m_sGPRName[nRS]);
|
sprintf(sText, "%i, $%04X(%s)", nHint, nImm, CMIPS::m_sGPRName[nRS]);
|
||||||
|
@ -87,9 +87,9 @@ void CMA_MIPSIV::ReflOpIdOffRs(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress
|
||||||
uint8 nRS, nRT;
|
uint8 nRS, nRT;
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nRS = (uint8) ((nOpcode >> 21) & 0x001F);
|
nRS = (uint8)((nOpcode >> 21) & 0x001F);
|
||||||
nRT = (uint8) ((nOpcode >> 16) & 0x001F);
|
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
sprintf(sText, "$%02X, $%04X(%s)", nRT, nImm, CMIPS::m_sGPRName[nRS]);
|
sprintf(sText, "$%02X, $%04X(%s)", nRT, nImm, CMIPS::m_sGPRName[nRS]);
|
||||||
|
@ -112,7 +112,7 @@ void CMA_MIPSIV::ReflOpRdRtSa(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress,
|
||||||
|
|
||||||
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
nRT = (uint8)((nOpcode >> 16) & 0x001F);
|
||||||
nRD = (uint8)((nOpcode >> 11) & 0x001F);
|
nRD = (uint8)((nOpcode >> 11) & 0x001F);
|
||||||
nSA = (uint8)((nOpcode >> 6) & 0x001F);
|
nSA = (uint8)((nOpcode >> 6) & 0x001F);
|
||||||
|
|
||||||
sprintf(sText, "%s, %s, %i", CMIPS::m_sGPRName[nRD], CMIPS::m_sGPRName[nRT], nSA);
|
sprintf(sText, "%s, %s, %i", CMIPS::m_sGPRName[nRD], CMIPS::m_sGPRName[nRT], nSA);
|
||||||
}
|
}
|
||||||
|
@ -175,8 +175,8 @@ uint32 CMA_MIPSIV::ReflEaTarget(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddres
|
||||||
uint32 CMA_MIPSIV::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
uint32 CMA_MIPSIV::ReflEaOffset(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode)
|
||||||
{
|
{
|
||||||
uint16 nImm;
|
uint16 nImm;
|
||||||
|
|
||||||
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
nImm = (uint16)((nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
nAddress += 4;
|
nAddress += 4;
|
||||||
return (nAddress + CMIPS::GetBranch(nImm));
|
return (nAddress + CMIPS::GetBranch(nImm));
|
||||||
|
@ -430,28 +430,28 @@ INSTRUCTION CMA_MIPSIV::m_cReflRegImm[32] =
|
||||||
|
|
||||||
void CMA_MIPSIV::SetupReflectionTables()
|
void CMA_MIPSIV::SetupReflectionTables()
|
||||||
{
|
{
|
||||||
static_assert(sizeof(m_ReflGeneral) == sizeof(m_cReflGeneral), "Array sizes don't match");
|
static_assert(sizeof(m_ReflGeneral) == sizeof(m_cReflGeneral), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflSpecial) == sizeof(m_cReflSpecial), "Array sizes don't match");
|
static_assert(sizeof(m_ReflSpecial) == sizeof(m_cReflSpecial), "Array sizes don't match");
|
||||||
static_assert(sizeof(m_ReflRegImm) == sizeof(m_cReflRegImm), "Array sizes don't match");
|
static_assert(sizeof(m_ReflRegImm) == sizeof(m_cReflRegImm), "Array sizes don't match");
|
||||||
|
|
||||||
memcpy(m_ReflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
memcpy(m_ReflGeneral, m_cReflGeneral, sizeof(m_cReflGeneral));
|
||||||
memcpy(m_ReflSpecial, m_cReflSpecial, sizeof(m_cReflSpecial));
|
memcpy(m_ReflSpecial, m_cReflSpecial, sizeof(m_cReflSpecial));
|
||||||
memcpy(m_ReflRegImm, m_cReflRegImm, sizeof(m_cReflRegImm));
|
memcpy(m_ReflRegImm, m_cReflRegImm, sizeof(m_cReflRegImm));
|
||||||
|
|
||||||
m_ReflGeneralTable.nShift = 26;
|
m_ReflGeneralTable.nShift = 26;
|
||||||
m_ReflGeneralTable.nMask = 0x3F;
|
m_ReflGeneralTable.nMask = 0x3F;
|
||||||
m_ReflGeneralTable.pTable = m_ReflGeneral;
|
m_ReflGeneralTable.pTable = m_ReflGeneral;
|
||||||
|
|
||||||
m_ReflSpecialTable.nShift = 0;
|
m_ReflSpecialTable.nShift = 0;
|
||||||
m_ReflSpecialTable.nMask = 0x3F;
|
m_ReflSpecialTable.nMask = 0x3F;
|
||||||
m_ReflSpecialTable.pTable = m_ReflSpecial;
|
m_ReflSpecialTable.pTable = m_ReflSpecial;
|
||||||
|
|
||||||
m_ReflRegImmTable.nShift = 16;
|
m_ReflRegImmTable.nShift = 16;
|
||||||
m_ReflRegImmTable.nMask = 0x1F;
|
m_ReflRegImmTable.nMask = 0x1F;
|
||||||
m_ReflRegImmTable.pTable = m_ReflRegImm;
|
m_ReflRegImmTable.pTable = m_ReflRegImm;
|
||||||
|
|
||||||
m_ReflGeneral[0x00].pSubTable = &m_ReflSpecialTable;
|
m_ReflGeneral[0x00].pSubTable = &m_ReflSpecialTable;
|
||||||
m_ReflGeneral[0x01].pSubTable = &m_ReflRegImmTable;
|
m_ReflGeneral[0x01].pSubTable = &m_ReflRegImmTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMA_MIPSIV::GetInstructionMnemonic(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void CMA_MIPSIV::GetInstructionMnemonic(CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
|
@ -464,8 +464,8 @@ void CMA_MIPSIV::GetInstructionMnemonic(CMIPS* pCtx, uint32 nAddress, uint32 nOp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instr.pGetMnemonic = SubTableMnemonic;
|
Instr.pGetMnemonic = SubTableMnemonic;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
Instr.pGetMnemonic(&Instr, pCtx, nOpcode, sText, nCount);
|
Instr.pGetMnemonic(&Instr, pCtx, nOpcode, sText, nCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,8 +479,8 @@ void CMA_MIPSIV::GetInstructionOperands(CMIPS* pCtx, uint32 nAddress, uint32 nOp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instr.pGetOperands = SubTableOperands;
|
Instr.pGetOperands = SubTableOperands;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, nCount);
|
Instr.pGetOperands(&Instr, pCtx, nAddress, nOpcode, sText, nCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,8 +490,8 @@ MIPS_BRANCH_TYPE CMA_MIPSIV::IsInstructionBranch(CMIPS* pCtx, uint32 nAddress, u
|
||||||
|
|
||||||
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
if(nOpcode == 0) return MIPS_BRANCH_NONE;
|
||||||
|
|
||||||
Instr.pIsBranch = SubTableIsBranch;
|
Instr.pIsBranch = SubTableIsBranch;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
return Instr.pIsBranch(&Instr, pCtx, nOpcode);
|
return Instr.pIsBranch(&Instr, pCtx, nOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ uint32 CMA_MIPSIV::GetInstructionEffectiveAddress(CMIPS* pCtx, uint32 nAddress,
|
||||||
|
|
||||||
if(nOpcode == 0) return 0;
|
if(nOpcode == 0) return 0;
|
||||||
|
|
||||||
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
Instr.pGetEffectiveAddress = SubTableEffAddr;
|
||||||
Instr.pSubTable = &m_ReflGeneralTable;
|
Instr.pSubTable = &m_ReflGeneralTable;
|
||||||
return Instr.pGetEffectiveAddress(&Instr, pCtx, nAddress, nOpcode);
|
return Instr.pGetEffectiveAddress(&Instr, pCtx, nAddress, nOpcode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,7 +400,7 @@ void CMA_MIPSIV::Template_BranchEq(bool condition, bool likely)
|
||||||
m_codeGen->PushRel64(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
m_codeGen->PushRel64(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0]));
|
||||||
m_codeGen->PushRel64(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
|
m_codeGen->PushRel64(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0]));
|
||||||
m_codeGen->Cmp64(Jitter::CONDITION_NE);
|
m_codeGen->Cmp64(Jitter::CONDITION_NE);
|
||||||
|
|
||||||
m_codeGen->PushCst(0);
|
m_codeGen->PushCst(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,13 @@
|
||||||
#include "COP_SCU.h"
|
#include "COP_SCU.h"
|
||||||
|
|
||||||
const char* CMIPS::m_sGPRName[] =
|
const char* CMIPS::m_sGPRName[] =
|
||||||
{
|
{
|
||||||
"R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3",
|
"R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3",
|
||||||
"T0", "T1", "T2", "T3", "T4", "T5", "T6", "T7",
|
"T0", "T1", "T2", "T3", "T4", "T5", "T6", "T7",
|
||||||
"S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7",
|
"S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7",
|
||||||
"T8", "T9", "K0", "K1", "GP", "SP", "FP", "RA"
|
"T8", "T9", "K0", "K1", "GP", "SP", "FP", "RA"};
|
||||||
};
|
|
||||||
|
|
||||||
CMIPS::CMIPS(MEMORYMAP_ENDIANESS nEnd)
|
CMIPS::CMIPS(MEMORYMAP_ENDIANESS nEnd)
|
||||||
{
|
{
|
||||||
m_analysis = new CMIPSAnalysis(this);
|
m_analysis = new CMIPSAnalysis(this);
|
||||||
switch(nEnd)
|
switch(nEnd)
|
||||||
|
|
188
Source/MIPS.h
188
Source/MIPS.h
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
struct REGISTER_PIPELINE
|
struct REGISTER_PIPELINE
|
||||||
{
|
{
|
||||||
uint32 counter;
|
uint32 counter;
|
||||||
uint32 heldValue;
|
uint32 heldValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -27,9 +27,9 @@ enum
|
||||||
//- The value at index - 1 is the latest value
|
//- The value at index - 1 is the latest value
|
||||||
struct FLAG_PIPELINE
|
struct FLAG_PIPELINE
|
||||||
{
|
{
|
||||||
uint32 index;
|
uint32 index;
|
||||||
uint32 values[FLAG_PIPELINE_SLOTS];
|
uint32 values[FLAG_PIPELINE_SLOTS];
|
||||||
uint32 pipeTimes[FLAG_PIPELINE_SLOTS];
|
uint32 pipeTimes[FLAG_PIPELINE_SLOTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -44,127 +44,155 @@ enum
|
||||||
|
|
||||||
struct MIPSSTATE
|
struct MIPSSTATE
|
||||||
{
|
{
|
||||||
uint32 nPC;
|
uint32 nPC;
|
||||||
uint32 nDelayedJumpAddr;
|
uint32 nDelayedJumpAddr;
|
||||||
uint32 nHasException;
|
uint32 nHasException;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(align(16))
|
__declspec(align(16))
|
||||||
#else
|
#else
|
||||||
__attribute__((aligned(16)))
|
__attribute__((aligned(16)))
|
||||||
#endif
|
#endif
|
||||||
uint128 nGPR[32];
|
uint128 nGPR[32];
|
||||||
|
|
||||||
uint32 nHI[2];
|
uint32 nHI[2];
|
||||||
uint32 nLO[2];
|
uint32 nLO[2];
|
||||||
uint32 nHI1[2];
|
uint32 nHI1[2];
|
||||||
uint32 nLO1[2];
|
uint32 nLO1[2];
|
||||||
uint32 nSA;
|
uint32 nSA;
|
||||||
|
|
||||||
//COP0
|
//COP0
|
||||||
uint32 nCOP0[32];
|
uint32 nCOP0[32];
|
||||||
|
|
||||||
uint32 cop0_pccr;
|
uint32 cop0_pccr;
|
||||||
uint32 cop0_pcr[2];
|
uint32 cop0_pcr[2];
|
||||||
|
|
||||||
//COP1
|
//COP1
|
||||||
uint32 nCOP1[32];
|
uint32 nCOP1[32];
|
||||||
uint32 nCOP1A;
|
uint32 nCOP1A;
|
||||||
uint32 nFCSR;
|
uint32 nFCSR;
|
||||||
|
|
||||||
//COP2
|
//COP2
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(align(16))
|
__declspec(align(16))
|
||||||
#else
|
#else
|
||||||
__attribute__((aligned(16)))
|
__attribute__((aligned(16)))
|
||||||
#endif
|
#endif
|
||||||
uint128 nCOP2[33];
|
uint128 nCOP2[33];
|
||||||
|
|
||||||
uint128 nCOP2A;
|
uint128 nCOP2A;
|
||||||
|
|
||||||
uint128 nCOP2VF_PreUp;
|
uint128 nCOP2VF_PreUp;
|
||||||
uint128 nCOP2VF_UpRes;
|
uint128 nCOP2VF_UpRes;
|
||||||
|
|
||||||
uint32 nCOP2Q;
|
uint32 nCOP2Q;
|
||||||
uint32 nCOP2I;
|
uint32 nCOP2I;
|
||||||
uint32 nCOP2P;
|
uint32 nCOP2P;
|
||||||
uint32 nCOP2R;
|
uint32 nCOP2R;
|
||||||
uint32 nCOP2CF; //Mirror of CLIP flag (computed with values from pipeClip)
|
uint32 nCOP2CF; //Mirror of CLIP flag (computed with values from pipeClip)
|
||||||
uint32 nCOP2MF; //Mirror of MACflag (computed with values from pipeMac)
|
uint32 nCOP2MF; //Mirror of MACflag (computed with values from pipeMac)
|
||||||
uint32 nCOP2SF; //Sticky values of sign and zero MACflag (ie.: SxSySzSw ZxZyZzZw)
|
uint32 nCOP2SF; //Sticky values of sign and zero MACflag (ie.: SxSySzSw ZxZyZzZw)
|
||||||
uint32 nCOP2T;
|
uint32 nCOP2T;
|
||||||
|
|
||||||
uint32 nCOP2VI[16];
|
uint32 nCOP2VI[16];
|
||||||
|
|
||||||
REGISTER_PIPELINE pipeQ;
|
REGISTER_PIPELINE pipeQ;
|
||||||
REGISTER_PIPELINE pipeP;
|
REGISTER_PIPELINE pipeP;
|
||||||
FLAG_PIPELINE pipeMac;
|
FLAG_PIPELINE pipeMac;
|
||||||
FLAG_PIPELINE pipeClip;
|
FLAG_PIPELINE pipeClip;
|
||||||
|
|
||||||
uint32 pipeTime;
|
uint32 pipeTime;
|
||||||
|
|
||||||
uint32 cmsar0;
|
uint32 cmsar0;
|
||||||
uint32 callMsEnabled;
|
uint32 callMsEnabled;
|
||||||
uint32 callMsAddr;
|
uint32 callMsAddr;
|
||||||
|
|
||||||
uint32 savedIntReg;
|
uint32 savedIntReg;
|
||||||
uint32 savedIntRegTemp;
|
uint32 savedIntRegTemp;
|
||||||
uint32 xgkickAddress;
|
uint32 xgkickAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MIPS_INVALID_PC (0x00000001)
|
#define MIPS_INVALID_PC (0x00000001)
|
||||||
|
|
||||||
class CMIPS
|
class CMIPS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef uint32 (*AddressTranslator)(CMIPS*, uint32);
|
typedef uint32 (*AddressTranslator)(CMIPS*, uint32);
|
||||||
typedef std::set<uint32> BreakpointSet;
|
typedef std::set<uint32> BreakpointSet;
|
||||||
|
|
||||||
CMIPS(MEMORYMAP_ENDIANESS);
|
CMIPS(MEMORYMAP_ENDIANESS);
|
||||||
~CMIPS();
|
~CMIPS();
|
||||||
void ToggleBreakpoint(uint32);
|
void ToggleBreakpoint(uint32);
|
||||||
bool IsBranch(uint32);
|
bool IsBranch(uint32);
|
||||||
static int32 GetBranch(uint16);
|
static int32 GetBranch(uint16);
|
||||||
static uint32 TranslateAddress64(CMIPS*, uint32);
|
static uint32 TranslateAddress64(CMIPS*, uint32);
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
bool CanGenerateInterrupt() const;
|
bool CanGenerateInterrupt() const;
|
||||||
bool GenerateInterrupt(uint32);
|
bool GenerateInterrupt(uint32);
|
||||||
bool GenerateException(uint32);
|
bool GenerateException(uint32);
|
||||||
|
|
||||||
MIPSSTATE m_State;
|
MIPSSTATE m_State;
|
||||||
|
|
||||||
void* m_vuMem = nullptr;
|
void* m_vuMem = nullptr;
|
||||||
|
|
||||||
CMIPSArchitecture* m_pArch = nullptr;
|
CMIPSArchitecture* m_pArch = nullptr;
|
||||||
CMIPSCoprocessor* m_pCOP[4];
|
CMIPSCoprocessor* m_pCOP[4];
|
||||||
CMemoryMap* m_pMemoryMap = nullptr;
|
CMemoryMap* m_pMemoryMap = nullptr;
|
||||||
BreakpointSet m_breakpoints;
|
BreakpointSet m_breakpoints;
|
||||||
|
|
||||||
CMIPSAnalysis* m_analysis = nullptr;
|
CMIPSAnalysis* m_analysis = nullptr;
|
||||||
CMIPSTags m_Comments;
|
CMIPSTags m_Comments;
|
||||||
CMIPSTags m_Functions;
|
CMIPSTags m_Functions;
|
||||||
|
|
||||||
AddressTranslator m_pAddrTranslator = nullptr;
|
AddressTranslator m_pAddrTranslator = nullptr;
|
||||||
|
|
||||||
enum REGISTER
|
enum REGISTER
|
||||||
{
|
{
|
||||||
R0 = 0, AT, V0, V1, A0, A1, A2, A3,
|
R0 = 0,
|
||||||
T0, T1, T2, T3, T4, T5, T6, T7,
|
AT,
|
||||||
S0, S1, S2, S3, S4, S5, S6, S7,
|
V0,
|
||||||
T8, T9, K0, K1, GP, SP, FP, RA
|
V1,
|
||||||
|
A0,
|
||||||
|
A1,
|
||||||
|
A2,
|
||||||
|
A3,
|
||||||
|
T0,
|
||||||
|
T1,
|
||||||
|
T2,
|
||||||
|
T3,
|
||||||
|
T4,
|
||||||
|
T5,
|
||||||
|
T6,
|
||||||
|
T7,
|
||||||
|
S0,
|
||||||
|
S1,
|
||||||
|
S2,
|
||||||
|
S3,
|
||||||
|
S4,
|
||||||
|
S5,
|
||||||
|
S6,
|
||||||
|
S7,
|
||||||
|
T8,
|
||||||
|
T9,
|
||||||
|
K0,
|
||||||
|
K1,
|
||||||
|
GP,
|
||||||
|
SP,
|
||||||
|
FP,
|
||||||
|
RA
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
STATUS_IE = (1 << 0),
|
STATUS_IE = (1 << 0),
|
||||||
STATUS_EXL = (1 << 1),
|
STATUS_EXL = (1 << 1),
|
||||||
STATUS_ERL = (1 << 2),
|
STATUS_ERL = (1 << 2),
|
||||||
STATUS_EIE = (1 << 16), //PS2 EE specific
|
STATUS_EIE = (1 << 16), //PS2 EE specific
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* m_sGPRName[];
|
static const char* m_sGPRName[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
#include "MIPS.h"
|
#include "MIPS.h"
|
||||||
|
|
||||||
CMIPSAnalysis::CMIPSAnalysis(CMIPS* ctx)
|
CMIPSAnalysis::CMIPSAnalysis(CMIPS* ctx)
|
||||||
: m_ctx(ctx)
|
: m_ctx(ctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMIPSAnalysis::~CMIPSAnalysis()
|
CMIPSAnalysis::~CMIPSAnalysis()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMIPSAnalysis::Clear()
|
void CMIPSAnalysis::Clear()
|
||||||
|
@ -30,12 +28,12 @@ void CMIPSAnalysis::InsertSubroutine(uint32 start, uint32 end, uint32 stackAlloc
|
||||||
assert(FindSubroutine(end) == nullptr);
|
assert(FindSubroutine(end) == nullptr);
|
||||||
|
|
||||||
SUBROUTINE subroutine;
|
SUBROUTINE subroutine;
|
||||||
subroutine.start = start;
|
subroutine.start = start;
|
||||||
subroutine.end = end;
|
subroutine.end = end;
|
||||||
subroutine.stackAllocStart = stackAllocStart;
|
subroutine.stackAllocStart = stackAllocStart;
|
||||||
subroutine.stackAllocEnd = stackAllocEnd;
|
subroutine.stackAllocEnd = stackAllocEnd;
|
||||||
subroutine.stackSize = stackSize;
|
subroutine.stackSize = stackSize;
|
||||||
subroutine.returnAddrPos = returnAddrPos;
|
subroutine.returnAddrPos = returnAddrPos;
|
||||||
|
|
||||||
m_subroutines.insert(std::make_pair(start, subroutine));
|
m_subroutines.insert(std::make_pair(start, subroutine));
|
||||||
}
|
}
|
||||||
|
@ -118,9 +116,9 @@ void CMIPSAnalysis::FindSubroutinesByStackAllocation(uint32 start, uint32 end)
|
||||||
|
|
||||||
//Check SW/SD/SQ RA, 0x????(SP)
|
//Check SW/SD/SQ RA, 0x????(SP)
|
||||||
if(
|
if(
|
||||||
((opcode & 0xFFFF0000) == 0xAFBF0000) || //SW
|
((opcode & 0xFFFF0000) == 0xAFBF0000) || //SW
|
||||||
((opcode & 0xFFFF0000) == 0xFFBF0000) || //SD
|
((opcode & 0xFFFF0000) == 0xFFBF0000) || //SD
|
||||||
((opcode & 0xFFFF0000) == 0x7FBF0000)) //SQ
|
((opcode & 0xFFFF0000) == 0x7FBF0000)) //SQ
|
||||||
{
|
{
|
||||||
returnAddr = (opcode & 0xFFFF);
|
returnAddr = (opcode & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +131,7 @@ void CMIPSAnalysis::FindSubroutinesByStackAllocation(uint32 start, uint32 end)
|
||||||
//Check above
|
//Check above
|
||||||
//ADDIU SP, SP, 0x????
|
//ADDIU SP, SP, 0x????
|
||||||
//JR RA
|
//JR RA
|
||||||
|
|
||||||
opcode = m_ctx->m_pMemoryMap->GetInstruction(tempAddr - 4);
|
opcode = m_ctx->m_pMemoryMap->GetInstruction(tempAddr - 4);
|
||||||
if(IsStackFreeingInstruction(opcode))
|
if(IsStackFreeingInstruction(opcode))
|
||||||
{
|
{
|
||||||
|
@ -179,8 +177,8 @@ void CMIPSAnalysis::FindSubroutinesByJumpTargets(uint32 start, uint32 end, uint3
|
||||||
{
|
{
|
||||||
uint32 opcode = m_ctx->m_pMemoryMap->GetInstruction(address);
|
uint32 opcode = m_ctx->m_pMemoryMap->GetInstruction(address);
|
||||||
if(
|
if(
|
||||||
(opcode & 0xFC000000) == 0x0C000000 ||
|
(opcode & 0xFC000000) == 0x0C000000 ||
|
||||||
(opcode & 0xFC000000) == 0x08000000)
|
(opcode & 0xFC000000) == 0x08000000)
|
||||||
{
|
{
|
||||||
uint32 jumpTarget = (opcode & 0x03FFFFFF) * 4;
|
uint32 jumpTarget = (opcode & 0x03FFFFFF) * 4;
|
||||||
if(jumpTarget < start) continue;
|
if(jumpTarget < start) continue;
|
||||||
|
@ -229,31 +227,30 @@ void CMIPSAnalysis::ExpandSubroutines(uint32 executableStart, uint32 executableE
|
||||||
static const uint32 searchLimit = 0x1000;
|
static const uint32 searchLimit = 0x1000;
|
||||||
|
|
||||||
const auto& findFreeSubroutineEnd =
|
const auto& findFreeSubroutineEnd =
|
||||||
[this](uint32 begin, uint32 end) -> uint32
|
[this](uint32 begin, uint32 end) -> uint32 {
|
||||||
|
for(uint32 address = begin; address <= begin + searchLimit; address += 4)
|
||||||
{
|
{
|
||||||
for(uint32 address = begin; address <= begin + searchLimit; address += 4)
|
if(FindSubroutine(address) != nullptr) return MIPS_INVALID_PC;
|
||||||
|
|
||||||
|
uint32 opcode = m_ctx->m_pMemoryMap->GetInstruction(address);
|
||||||
|
|
||||||
|
//Check for JR RA or J
|
||||||
|
if((opcode == 0x03E00008) || ((opcode & 0xFC000000) == 0x08000000))
|
||||||
{
|
{
|
||||||
if(FindSubroutine(address) != nullptr) return MIPS_INVALID_PC;
|
//+4 for delay slot
|
||||||
|
return address + 4;
|
||||||
uint32 opcode = m_ctx->m_pMemoryMap->GetInstruction(address);
|
|
||||||
|
|
||||||
//Check for JR RA or J
|
|
||||||
if((opcode == 0x03E00008) || ((opcode & 0xFC000000) == 0x08000000))
|
|
||||||
{
|
|
||||||
//+4 for delay slot
|
|
||||||
return address + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check for BEQ R0, R0, $label
|
|
||||||
if((opcode & 0xFFFF0000) == 0x10000000)
|
|
||||||
{
|
|
||||||
//+4 for delay slot
|
|
||||||
return address + 4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MIPS_INVALID_PC;
|
//Check for BEQ R0, R0, $label
|
||||||
};
|
if((opcode & 0xFFFF0000) == 0x10000000)
|
||||||
|
{
|
||||||
|
//+4 for delay slot
|
||||||
|
return address + 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MIPS_INVALID_PC;
|
||||||
|
};
|
||||||
|
|
||||||
for(auto& subroutinePair : m_subroutines)
|
for(auto& subroutinePair : m_subroutines)
|
||||||
{
|
{
|
||||||
|
@ -267,10 +264,10 @@ void CMIPSAnalysis::ExpandSubroutines(uint32 executableStart, uint32 executableE
|
||||||
for(uint32 address = subroutine.start; address <= subroutine.end; address += 4)
|
for(uint32 address = subroutine.start; address <= subroutine.end; address += 4)
|
||||||
{
|
{
|
||||||
uint32 opcode = m_ctx->m_pMemoryMap->GetInstruction(address);
|
uint32 opcode = m_ctx->m_pMemoryMap->GetInstruction(address);
|
||||||
|
|
||||||
auto branchType = m_ctx->m_pArch->IsInstructionBranch(m_ctx, address, opcode);
|
auto branchType = m_ctx->m_pArch->IsInstructionBranch(m_ctx, address, opcode);
|
||||||
if(branchType != MIPS_BRANCH_NORMAL) continue;
|
if(branchType != MIPS_BRANCH_NORMAL) continue;
|
||||||
|
|
||||||
uint32 branchTarget = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode);
|
uint32 branchTarget = m_ctx->m_pArch->GetInstructionEffectiveAddress(m_ctx, address, opcode);
|
||||||
|
|
||||||
//Check if pointing inside our subroutine. If so, don't bother
|
//Check if pointing inside our subroutine. If so, don't bother
|
||||||
|
@ -289,7 +286,7 @@ void CMIPSAnalysis::ExpandSubroutines(uint32 executableStart, uint32 executableE
|
||||||
if(FindSubroutine(branchTarget) != nullptr) continue;
|
if(FindSubroutine(branchTarget) != nullptr) continue;
|
||||||
|
|
||||||
uint32 routineEnd = findFreeSubroutineEnd(branchTarget, executableEnd);
|
uint32 routineEnd = findFreeSubroutineEnd(branchTarget, executableEnd);
|
||||||
if(routineEnd == MIPS_INVALID_PC)
|
if(routineEnd == MIPS_INVALID_PC)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -323,10 +320,10 @@ static bool TryGetStringAtAddress(CMIPS* context, uint32 address, std::string& r
|
||||||
uint8 byte = context->m_pMemoryMap->GetByte(address);
|
uint8 byte = context->m_pMemoryMap->GetByte(address);
|
||||||
if(byte == 0) break;
|
if(byte == 0) break;
|
||||||
if(byte > 0x7F) return false;
|
if(byte > 0x7F) return false;
|
||||||
if((byte < 0x20) &&
|
if((byte < 0x20) &&
|
||||||
(byte != '\t') &&
|
(byte != '\t') &&
|
||||||
(byte != '\n') &&
|
(byte != '\n') &&
|
||||||
(byte != '\r'))
|
(byte != '\r'))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +338,8 @@ void CMIPSAnalysis::AnalyseStringReferences()
|
||||||
for(auto subroutinePair : m_subroutines)
|
for(auto subroutinePair : m_subroutines)
|
||||||
{
|
{
|
||||||
const auto& subroutine = subroutinePair.second;
|
const auto& subroutine = subroutinePair.second;
|
||||||
uint32 registerValue[0x20] = { 0 };
|
uint32 registerValue[0x20] = {0};
|
||||||
bool registerWritten[0x20] = { false };
|
bool registerWritten[0x20] = {false};
|
||||||
for(uint32 address = subroutine.start; address <= subroutine.end; address += 4)
|
for(uint32 address = subroutine.start; address <= subroutine.end; address += 4)
|
||||||
{
|
{
|
||||||
uint32 op = m_ctx->m_pMemoryMap->GetInstruction(address);
|
uint32 op = m_ctx->m_pMemoryMap->GetInstruction(address);
|
||||||
|
@ -416,7 +413,7 @@ CMIPSAnalysis::CallStackItemArray CMIPSAnalysis::GetCallStack(CMIPS* context, ui
|
||||||
{
|
{
|
||||||
//We haven't called a sub routine yet... The RA is good, but we
|
//We haven't called a sub routine yet... The RA is good, but we
|
||||||
//don't know wether stack memory has been allocated or not
|
//don't know wether stack memory has been allocated or not
|
||||||
|
|
||||||
//ADDIU SP, SP, 0x????
|
//ADDIU SP, SP, 0x????
|
||||||
//If the PC is after this instruction, then, we've allocated stack
|
//If the PC is after this instruction, then, we've allocated stack
|
||||||
|
|
||||||
|
|
|
@ -12,38 +12,38 @@ class CMIPSAnalysis
|
||||||
public:
|
public:
|
||||||
struct SUBROUTINE
|
struct SUBROUTINE
|
||||||
{
|
{
|
||||||
uint32 start;
|
uint32 start;
|
||||||
uint32 end;
|
uint32 end;
|
||||||
uint32 stackAllocStart;
|
uint32 stackAllocStart;
|
||||||
uint32 stackAllocEnd;
|
uint32 stackAllocEnd;
|
||||||
uint32 stackSize;
|
uint32 stackSize;
|
||||||
uint32 returnAddrPos;
|
uint32 returnAddrPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<uint32> CallStackItemArray;
|
typedef std::vector<uint32> CallStackItemArray;
|
||||||
|
|
||||||
CMIPSAnalysis(CMIPS*);
|
CMIPSAnalysis(CMIPS*);
|
||||||
~CMIPSAnalysis();
|
~CMIPSAnalysis();
|
||||||
void Analyse(uint32, uint32, uint32 = -1);
|
void Analyse(uint32, uint32, uint32 = -1);
|
||||||
const SUBROUTINE* FindSubroutine(uint32) const;
|
const SUBROUTINE* FindSubroutine(uint32) const;
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
void InsertSubroutine(uint32, uint32, uint32, uint32, uint32, uint32);
|
void InsertSubroutine(uint32, uint32, uint32, uint32, uint32, uint32);
|
||||||
void ChangeSubroutineStart(uint32, uint32);
|
void ChangeSubroutineStart(uint32, uint32);
|
||||||
void ChangeSubroutineEnd(uint32, uint32);
|
void ChangeSubroutineEnd(uint32, uint32);
|
||||||
|
|
||||||
static CallStackItemArray GetCallStack(CMIPS*, uint32 pc, uint32 sp, uint32 ra);
|
static CallStackItemArray GetCallStack(CMIPS*, uint32 pc, uint32 sp, uint32 ra);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<uint32, SUBROUTINE, std::greater<uint32>> SubroutineList;
|
typedef std::map<uint32, SUBROUTINE, std::greater<uint32>> SubroutineList;
|
||||||
|
|
||||||
void AnalyseSubroutines(uint32, uint32, uint32);
|
void AnalyseSubroutines(uint32, uint32, uint32);
|
||||||
void AnalyseStringReferences();
|
void AnalyseStringReferences();
|
||||||
|
|
||||||
void FindSubroutinesByStackAllocation(uint32, uint32);
|
void FindSubroutinesByStackAllocation(uint32, uint32);
|
||||||
void FindSubroutinesByJumpTargets(uint32, uint32, uint32);
|
void FindSubroutinesByJumpTargets(uint32, uint32, uint32);
|
||||||
void ExpandSubroutines(uint32, uint32);
|
void ExpandSubroutines(uint32, uint32);
|
||||||
|
|
||||||
CMIPS* m_ctx;
|
CMIPS* m_ctx;
|
||||||
SubroutineList m_subroutines;
|
SubroutineList m_subroutines;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "MIPSArchitecture.h"
|
#include "MIPSArchitecture.h"
|
||||||
|
|
||||||
CMIPSArchitecture::CMIPSArchitecture(MIPS_REGSIZE regSize)
|
CMIPSArchitecture::CMIPSArchitecture(MIPS_REGSIZE regSize)
|
||||||
: CMIPSInstructionFactory(regSize)
|
: CMIPSInstructionFactory(regSize)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
class CMIPSArchitecture : public CMIPSInstructionFactory
|
class CMIPSArchitecture : public CMIPSInstructionFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMIPSArchitecture(MIPS_REGSIZE);
|
CMIPSArchitecture(MIPS_REGSIZE);
|
||||||
virtual ~CMIPSArchitecture() = default;
|
virtual ~CMIPSArchitecture() = default;
|
||||||
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
virtual void GetInstructionMnemonic(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
||||||
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
virtual void GetInstructionOperands(CMIPS*, uint32, uint32, char*, unsigned int) = 0;
|
||||||
virtual MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) = 0;
|
virtual MIPS_BRANCH_TYPE IsInstructionBranch(CMIPS*, uint32, uint32) = 0;
|
||||||
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32) = 0;
|
virtual uint32 GetInstructionEffectiveAddress(CMIPS*, uint32, uint32) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,11 +4,10 @@
|
||||||
#include "lexical_cast_ex.h"
|
#include "lexical_cast_ex.h"
|
||||||
|
|
||||||
CMIPSAssembler::CMIPSAssembler(uint32* ptr)
|
CMIPSAssembler::CMIPSAssembler(uint32* ptr)
|
||||||
: m_ptr(ptr)
|
: m_ptr(ptr)
|
||||||
, m_startPtr(ptr)
|
, m_startPtr(ptr)
|
||||||
, m_nextLabelId(1)
|
, m_nextLabelId(1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMIPSAssembler::~CMIPSAssembler()
|
CMIPSAssembler::~CMIPSAssembler()
|
||||||
|
@ -71,13 +70,13 @@ void CMIPSAssembler::ADDIU(unsigned int rt, unsigned int rs, uint16 immediate)
|
||||||
|
|
||||||
void CMIPSAssembler::ADDU(unsigned int rd, unsigned int rs, unsigned int rt)
|
void CMIPSAssembler::ADDU(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||||
{
|
{
|
||||||
(*m_ptr) = (rs << 21) | (rt << 16) | (rd << 11) | (0x21);
|
(*m_ptr) = (rs << 21) | (rt << 16) | (rd << 11) | (0x21);
|
||||||
m_ptr++;
|
m_ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMIPSAssembler::AND(unsigned int rd, unsigned int rs, unsigned int rt)
|
void CMIPSAssembler::AND(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||||
{
|
{
|
||||||
(*m_ptr) = (rs << 21) | (rt << 16) | (rd << 11) | (0x24);
|
(*m_ptr) = (rs << 21) | (rt << 16) | (rd << 11) | (0x24);
|
||||||
m_ptr++;
|
m_ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,92 +10,92 @@ public:
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
bool operator < (const LABEL& rhs) const
|
bool operator<(const LABEL& rhs) const
|
||||||
{
|
{
|
||||||
return id < rhs.id;
|
return id < rhs.id;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
CMIPSAssembler(uint32*);
|
CMIPSAssembler(uint32*);
|
||||||
~CMIPSAssembler();
|
~CMIPSAssembler();
|
||||||
|
|
||||||
unsigned int GetProgramSize();
|
unsigned int GetProgramSize();
|
||||||
LABEL CreateLabel();
|
LABEL CreateLabel();
|
||||||
void MarkLabel(LABEL);
|
void MarkLabel(LABEL);
|
||||||
|
|
||||||
void ADDIU(unsigned int, unsigned int, uint16);
|
void ADDIU(unsigned int, unsigned int, uint16);
|
||||||
void ADDU(unsigned int, unsigned int, unsigned int);
|
void ADDU(unsigned int, unsigned int, unsigned int);
|
||||||
void AND(unsigned int, unsigned int, unsigned int);
|
void AND(unsigned int, unsigned int, unsigned int);
|
||||||
void ANDI(unsigned int, unsigned int, uint16);
|
void ANDI(unsigned int, unsigned int, uint16);
|
||||||
void BEQ(unsigned int, unsigned int, uint16);
|
void BEQ(unsigned int, unsigned int, uint16);
|
||||||
void BEQ(unsigned int, unsigned int, LABEL);
|
void BEQ(unsigned int, unsigned int, LABEL);
|
||||||
void BGEZ(unsigned int, uint16);
|
void BGEZ(unsigned int, uint16);
|
||||||
void BGEZ(unsigned int, LABEL);
|
void BGEZ(unsigned int, LABEL);
|
||||||
void BGTZ(unsigned int, uint16);
|
void BGTZ(unsigned int, uint16);
|
||||||
void BNE(unsigned int, unsigned int, uint16);
|
void BNE(unsigned int, unsigned int, uint16);
|
||||||
void BNE(unsigned int, unsigned int, LABEL);
|
void BNE(unsigned int, unsigned int, LABEL);
|
||||||
void BLEZ(unsigned int, uint16);
|
void BLEZ(unsigned int, uint16);
|
||||||
void BLTZ(unsigned int, uint16);
|
void BLTZ(unsigned int, uint16);
|
||||||
void DADDU(unsigned int, unsigned int, unsigned int);
|
void DADDU(unsigned int, unsigned int, unsigned int);
|
||||||
void DADDIU(unsigned int, unsigned int, uint16);
|
void DADDIU(unsigned int, unsigned int, uint16);
|
||||||
void DSLL(unsigned int, unsigned int, unsigned int);
|
void DSLL(unsigned int, unsigned int, unsigned int);
|
||||||
void DSLL32(unsigned int, unsigned int, unsigned int);
|
void DSLL32(unsigned int, unsigned int, unsigned int);
|
||||||
void DSLLV(unsigned int, unsigned int, unsigned int);
|
void DSLLV(unsigned int, unsigned int, unsigned int);
|
||||||
void DSRA(unsigned int, unsigned int, unsigned int);
|
void DSRA(unsigned int, unsigned int, unsigned int);
|
||||||
void DSRA32(unsigned int, unsigned int, unsigned int);
|
void DSRA32(unsigned int, unsigned int, unsigned int);
|
||||||
void DSRAV(unsigned int, unsigned int, unsigned int);
|
void DSRAV(unsigned int, unsigned int, unsigned int);
|
||||||
void DSRL(unsigned int, unsigned int, unsigned int);
|
void DSRL(unsigned int, unsigned int, unsigned int);
|
||||||
void DSRL32(unsigned int, unsigned int, unsigned int);
|
void DSRL32(unsigned int, unsigned int, unsigned int);
|
||||||
void DSRLV(unsigned int, unsigned int, unsigned int);
|
void DSRLV(unsigned int, unsigned int, unsigned int);
|
||||||
void DSUBU(unsigned int, unsigned int, unsigned int);
|
void DSUBU(unsigned int, unsigned int, unsigned int);
|
||||||
void ERET();
|
void ERET();
|
||||||
void JR(unsigned int);
|
void JR(unsigned int);
|
||||||
void JAL(uint32);
|
void JAL(uint32);
|
||||||
void JALR(unsigned int, unsigned int = 31);
|
void JALR(unsigned int, unsigned int = 31);
|
||||||
void LBU(unsigned int, uint16, unsigned int);
|
void LBU(unsigned int, uint16, unsigned int);
|
||||||
void LD(unsigned int, uint16, unsigned int);
|
void LD(unsigned int, uint16, unsigned int);
|
||||||
void LDL(unsigned int, uint16, unsigned int);
|
void LDL(unsigned int, uint16, unsigned int);
|
||||||
void LDR(unsigned int, uint16, unsigned int);
|
void LDR(unsigned int, uint16, unsigned int);
|
||||||
void LHU(unsigned int, uint16, unsigned int);
|
void LHU(unsigned int, uint16, unsigned int);
|
||||||
void LI(unsigned int, uint32);
|
void LI(unsigned int, uint32);
|
||||||
void LUI(unsigned int, uint16);
|
void LUI(unsigned int, uint16);
|
||||||
void LW(unsigned int, uint16, unsigned int);
|
void LW(unsigned int, uint16, unsigned int);
|
||||||
void LWL(unsigned int, uint16, unsigned int);
|
void LWL(unsigned int, uint16, unsigned int);
|
||||||
void LWR(unsigned int, uint16, unsigned int);
|
void LWR(unsigned int, uint16, unsigned int);
|
||||||
void MFC0(unsigned int, unsigned int);
|
void MFC0(unsigned int, unsigned int);
|
||||||
void MFHI(unsigned int);
|
void MFHI(unsigned int);
|
||||||
void MFLO(unsigned int);
|
void MFLO(unsigned int);
|
||||||
void MTC0(unsigned int, unsigned int);
|
void MTC0(unsigned int, unsigned int);
|
||||||
void MTHI(unsigned int);
|
void MTHI(unsigned int);
|
||||||
void MTLO(unsigned int);
|
void MTLO(unsigned int);
|
||||||
void MOV(unsigned int, unsigned int);
|
void MOV(unsigned int, unsigned int);
|
||||||
void MULT(unsigned int, unsigned int, unsigned int);
|
void MULT(unsigned int, unsigned int, unsigned int);
|
||||||
void MULTU(unsigned int, unsigned int, unsigned int);
|
void MULTU(unsigned int, unsigned int, unsigned int);
|
||||||
void NOP();
|
void NOP();
|
||||||
void NOR(unsigned int, unsigned int, unsigned int);
|
void NOR(unsigned int, unsigned int, unsigned int);
|
||||||
void OR(unsigned int, unsigned int, unsigned int);
|
void OR(unsigned int, unsigned int, unsigned int);
|
||||||
void ORI(unsigned int, unsigned int, uint16);
|
void ORI(unsigned int, unsigned int, uint16);
|
||||||
void SD(unsigned int, uint16, unsigned int);
|
void SD(unsigned int, uint16, unsigned int);
|
||||||
void SLL(unsigned int, unsigned int, unsigned int);
|
void SLL(unsigned int, unsigned int, unsigned int);
|
||||||
void SLLV(unsigned int, unsigned int, unsigned int);
|
void SLLV(unsigned int, unsigned int, unsigned int);
|
||||||
void SLT(unsigned int, unsigned int, unsigned int);
|
void SLT(unsigned int, unsigned int, unsigned int);
|
||||||
void SLTI(unsigned int, unsigned int, uint16);
|
void SLTI(unsigned int, unsigned int, uint16);
|
||||||
void SLTIU(unsigned int, unsigned int, uint16);
|
void SLTIU(unsigned int, unsigned int, uint16);
|
||||||
void SLTU(unsigned int, unsigned int, unsigned int);
|
void SLTU(unsigned int, unsigned int, unsigned int);
|
||||||
void SRA(unsigned int, unsigned int, unsigned int);
|
void SRA(unsigned int, unsigned int, unsigned int);
|
||||||
void SRAV(unsigned int, unsigned int, unsigned int);
|
void SRAV(unsigned int, unsigned int, unsigned int);
|
||||||
void SRL(unsigned int, unsigned int, unsigned int);
|
void SRL(unsigned int, unsigned int, unsigned int);
|
||||||
void SRLV(unsigned int, unsigned int, unsigned int);
|
void SRLV(unsigned int, unsigned int, unsigned int);
|
||||||
void SB(unsigned int, uint16, unsigned int);
|
void SB(unsigned int, uint16, unsigned int);
|
||||||
void SW(unsigned int, uint16, unsigned int);
|
void SW(unsigned int, uint16, unsigned int);
|
||||||
void SYSCALL();
|
void SYSCALL();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32* m_ptr = nullptr;
|
uint32* m_ptr = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ResolveLabelReferences();
|
void ResolveLabelReferences();
|
||||||
void CreateLabelReference(LABEL);
|
void CreateLabelReference(LABEL);
|
||||||
|
|
||||||
struct LABELREF
|
struct LABELREF
|
||||||
{
|
{
|
||||||
|
@ -105,8 +105,8 @@ private:
|
||||||
typedef std::map<LABEL, size_t> LabelMapType;
|
typedef std::map<LABEL, size_t> LabelMapType;
|
||||||
typedef std::multimap<LABEL, LABELREF> LabelReferenceMapType;
|
typedef std::multimap<LABEL, LABELREF> LabelReferenceMapType;
|
||||||
|
|
||||||
uint32* m_startPtr = nullptr;
|
uint32* m_startPtr = nullptr;
|
||||||
LabelMapType m_labels;
|
LabelMapType m_labels;
|
||||||
LabelReferenceMapType m_labelReferences;
|
LabelReferenceMapType m_labelReferences;
|
||||||
unsigned int m_nextLabelId;
|
unsigned int m_nextLabelId;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#include "MIPSCoprocessor.h"
|
#include "MIPSCoprocessor.h"
|
||||||
|
|
||||||
CMIPSCoprocessor::CMIPSCoprocessor(MIPS_REGSIZE nRegSize) :
|
CMIPSCoprocessor::CMIPSCoprocessor(MIPS_REGSIZE nRegSize)
|
||||||
CMIPSInstructionFactory(nRegSize)
|
: CMIPSInstructionFactory(nRegSize)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMIPSCoprocessor::~CMIPSCoprocessor()
|
CMIPSCoprocessor::~CMIPSCoprocessor()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
class CMIPSCoprocessor : public CMIPSInstructionFactory
|
class CMIPSCoprocessor : public CMIPSInstructionFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMIPSCoprocessor(MIPS_REGSIZE);
|
CMIPSCoprocessor(MIPS_REGSIZE);
|
||||||
virtual ~CMIPSCoprocessor();
|
virtual ~CMIPSCoprocessor();
|
||||||
virtual void GetInstruction(uint32, char*) = 0;
|
virtual void GetInstruction(uint32, char*) = 0;
|
||||||
virtual void GetArguments(uint32, uint32, char*) = 0;
|
virtual void GetArguments(uint32, uint32, char*) = 0;
|
||||||
virtual uint32 GetEffectiveAddress(uint32, uint32) = 0;
|
virtual uint32 GetEffectiveAddress(uint32, uint32) = 0;
|
||||||
virtual MIPS_BRANCH_TYPE IsBranch(uint32) = 0;
|
virtual MIPS_BRANCH_TYPE IsBranch(uint32) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,24 +5,23 @@
|
||||||
#include "offsetof_def.h"
|
#include "offsetof_def.h"
|
||||||
|
|
||||||
CMIPSInstructionFactory::CMIPSInstructionFactory(MIPS_REGSIZE nRegSize)
|
CMIPSInstructionFactory::CMIPSInstructionFactory(MIPS_REGSIZE nRegSize)
|
||||||
: m_regSize(nRegSize)
|
: m_regSize(nRegSize)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMIPSInstructionFactory::SetupQuickVariables(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx)
|
void CMIPSInstructionFactory::SetupQuickVariables(uint32 nAddress, CMipsJitter* codeGen, CMIPS* pCtx)
|
||||||
{
|
{
|
||||||
m_pCtx = pCtx;
|
m_pCtx = pCtx;
|
||||||
m_codeGen = codeGen;
|
m_codeGen = codeGen;
|
||||||
m_nAddress = nAddress;
|
m_nAddress = nAddress;
|
||||||
|
|
||||||
m_nOpcode = m_pCtx->m_pMemoryMap->GetInstruction(m_nAddress);
|
m_nOpcode = m_pCtx->m_pMemoryMap->GetInstruction(m_nAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMIPSInstructionFactory::ComputeMemAccessAddr()
|
void CMIPSInstructionFactory::ComputeMemAccessAddr()
|
||||||
{
|
{
|
||||||
uint8 nRS = (uint8) ((m_nOpcode >> 21) & 0x001F);
|
uint8 nRS = (uint8)((m_nOpcode >> 21) & 0x001F);
|
||||||
uint16 nImmediate = (uint16)((m_nOpcode >> 0) & 0xFFFF);
|
uint16 nImmediate = (uint16)((m_nOpcode >> 0) & 0xFFFF);
|
||||||
|
|
||||||
if(m_pCtx->m_pAddrTranslator == &CMIPS::TranslateAddress64)
|
if(m_pCtx->m_pAddrTranslator == &CMIPS::TranslateAddress64)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,35 +7,35 @@ class CMIPS;
|
||||||
|
|
||||||
enum MIPS_REGSIZE
|
enum MIPS_REGSIZE
|
||||||
{
|
{
|
||||||
MIPS_REGSIZE_32 = 0,
|
MIPS_REGSIZE_32 = 0,
|
||||||
MIPS_REGSIZE_64 = 1,
|
MIPS_REGSIZE_64 = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MIPS_BRANCH_TYPE
|
enum MIPS_BRANCH_TYPE
|
||||||
{
|
{
|
||||||
MIPS_BRANCH_NONE = 0,
|
MIPS_BRANCH_NONE = 0,
|
||||||
MIPS_BRANCH_NORMAL = 1,
|
MIPS_BRANCH_NORMAL = 1,
|
||||||
MIPS_BRANCH_NODELAY = 2,
|
MIPS_BRANCH_NODELAY = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMIPSInstructionFactory
|
class CMIPSInstructionFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMIPSInstructionFactory(MIPS_REGSIZE);
|
CMIPSInstructionFactory(MIPS_REGSIZE);
|
||||||
virtual ~CMIPSInstructionFactory() = default;
|
virtual ~CMIPSInstructionFactory() = default;
|
||||||
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*) = 0;
|
virtual void CompileInstruction(uint32, CMipsJitter*, CMIPS*) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ComputeMemAccessAddr();
|
void ComputeMemAccessAddr();
|
||||||
void Branch(Jitter::CONDITION);
|
void Branch(Jitter::CONDITION);
|
||||||
void BranchLikely(Jitter::CONDITION);
|
void BranchLikely(Jitter::CONDITION);
|
||||||
|
|
||||||
void Illegal();
|
void Illegal();
|
||||||
void SetupQuickVariables(uint32, CMipsJitter*, CMIPS*);
|
void SetupQuickVariables(uint32, CMipsJitter*, CMIPS*);
|
||||||
|
|
||||||
CMipsJitter* m_codeGen = nullptr;
|
CMipsJitter* m_codeGen = nullptr;
|
||||||
CMIPS* m_pCtx = nullptr;
|
CMIPS* m_pCtx = nullptr;
|
||||||
uint32 m_nOpcode = 0;
|
uint32 m_nOpcode = 0;
|
||||||
uint32 m_nAddress = 0;
|
uint32 m_nAddress = 0;
|
||||||
MIPS_REGSIZE m_regSize;
|
MIPS_REGSIZE m_regSize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,9 +20,9 @@ void MIPSReflection::CopyMnemonic(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpco
|
||||||
void MIPSReflection::SubTableMnemonic(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode, char* sText, unsigned int nCount)
|
void MIPSReflection::SubTableMnemonic(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
pInstr = DereferenceInstruction(pInstr->pSubTable, nOpcode);
|
pInstr = DereferenceInstruction(pInstr->pSubTable, nOpcode);
|
||||||
if(pInstr->pGetMnemonic == NULL)
|
if(pInstr->pGetMnemonic == NULL)
|
||||||
{
|
{
|
||||||
strncpy(sText, "???", nCount);
|
strncpy(sText, "???", nCount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pInstr->pGetMnemonic(pInstr, pCtx, nOpcode, sText, nCount);
|
pInstr->pGetMnemonic(pInstr, pCtx, nOpcode, sText, nCount);
|
||||||
|
@ -31,9 +31,9 @@ void MIPSReflection::SubTableMnemonic(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 n
|
||||||
void MIPSReflection::SubTableOperands(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
void MIPSReflection::SubTableOperands(INSTRUCTION* pInstr, CMIPS* pCtx, uint32 nAddress, uint32 nOpcode, char* sText, unsigned int nCount)
|
||||||
{
|
{
|
||||||
pInstr = DereferenceInstruction(pInstr->pSubTable, nOpcode);
|
pInstr = DereferenceInstruction(pInstr->pSubTable, nOpcode);
|
||||||
if(pInstr->pGetOperands == NULL)
|
if(pInstr->pGetOperands == NULL)
|
||||||
{
|
{
|
||||||
strncpy(sText, "", nCount);
|
strncpy(sText, "", nCount);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pInstr->pGetOperands(pInstr, pCtx, nAddress, nOpcode, sText, nCount);
|
pInstr->pGetOperands(pInstr, pCtx, nAddress, nOpcode, sText, nCount);
|
||||||
|
|
|
@ -12,33 +12,34 @@ namespace MIPSReflection
|
||||||
|
|
||||||
struct SUBTABLE
|
struct SUBTABLE
|
||||||
{
|
{
|
||||||
uint32 nShift;
|
uint32 nShift;
|
||||||
uint32 nMask;
|
uint32 nMask;
|
||||||
INSTRUCTION* pTable;
|
INSTRUCTION* pTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct INSTRUCTION
|
struct INSTRUCTION
|
||||||
{
|
{
|
||||||
const char* sMnemonic;
|
const char* sMnemonic;
|
||||||
SUBTABLE* pSubTable;
|
SUBTABLE* pSubTable;
|
||||||
void (*pGetMnemonic)(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
void (*pGetMnemonic)(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||||
void (*pGetOperands)(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
void (*pGetOperands)(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
MIPS_BRANCH_TYPE (*pIsBranch)(INSTRUCTION*, CMIPS*, uint32);
|
MIPS_BRANCH_TYPE(*pIsBranch)
|
||||||
uint32 (*pGetEffectiveAddress)(INSTRUCTION*, CMIPS*, uint32, uint32);
|
(INSTRUCTION*, CMIPS*, uint32);
|
||||||
|
uint32 (*pGetEffectiveAddress)(INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTRUCTION* DereferenceInstruction(SUBTABLE*, uint32);
|
INSTRUCTION* DereferenceInstruction(SUBTABLE*, uint32);
|
||||||
|
|
||||||
void CopyMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
void CopyMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||||
void SubTableMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
void SubTableMnemonic(INSTRUCTION*, CMIPS*, uint32, char*, unsigned int);
|
||||||
|
|
||||||
void SubTableOperands(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
void SubTableOperands(INSTRUCTION*, CMIPS*, uint32, uint32, char*, unsigned int);
|
||||||
|
|
||||||
MIPS_BRANCH_TYPE IsBranch(INSTRUCTION*, CMIPS*, uint32);
|
MIPS_BRANCH_TYPE IsBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||||
MIPS_BRANCH_TYPE IsNoDelayBranch(INSTRUCTION*, CMIPS*, uint32);
|
MIPS_BRANCH_TYPE IsNoDelayBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||||
MIPS_BRANCH_TYPE SubTableIsBranch(INSTRUCTION*, CMIPS*, uint32);
|
MIPS_BRANCH_TYPE SubTableIsBranch(INSTRUCTION*, CMIPS*, uint32);
|
||||||
|
|
||||||
uint32 SubTableEffAddr(INSTRUCTION*, CMIPS*, uint32, uint32);
|
uint32 SubTableEffAddr(INSTRUCTION*, CMIPS*, uint32, uint32);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
#include "lexical_cast_ex.h"
|
#include "lexical_cast_ex.h"
|
||||||
#include "xml/FilteringNodeIterator.h"
|
#include "xml/FilteringNodeIterator.h"
|
||||||
|
|
||||||
#define TAG_ELEMENT_NAME ("tag")
|
#define TAG_ELEMENT_NAME ("tag")
|
||||||
#define TAG_ELEMENT_ATTRIBUTE_ADDRESS ("address")
|
#define TAG_ELEMENT_ATTRIBUTE_ADDRESS ("address")
|
||||||
#define TAG_ELEMENT_ATTRIBUTE_VALUE ("value")
|
#define TAG_ELEMENT_ATTRIBUTE_VALUE ("value")
|
||||||
|
|
||||||
void CMIPSTags::InsertTag(uint32 nAddress, const char* sTag)
|
void CMIPSTags::InsertTag(uint32 nAddress, const char* sTag)
|
||||||
{
|
{
|
||||||
|
@ -75,8 +75,8 @@ void CMIPSTags::Unserialize(const char* sPath)
|
||||||
{
|
{
|
||||||
char sTag[256];
|
char sTag[256];
|
||||||
|
|
||||||
uint32 nKey = Stream.Read32();
|
uint32 nKey = Stream.Read32();
|
||||||
uint8 nLength = Stream.Read8();
|
uint8 nLength = Stream.Read8();
|
||||||
|
|
||||||
Stream.Read(sTag, nLength);
|
Stream.Read(sTag, nLength);
|
||||||
sTag[nLength] = 0;
|
sTag[nLength] = 0;
|
||||||
|
@ -86,15 +86,14 @@ void CMIPSTags::Unserialize(const char* sPath)
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMIPSTags::Serialize(Framework::Xml::CNode* parentNode, const char* sectionName) const
|
void CMIPSTags::Serialize(Framework::Xml::CNode* parentNode, const char* sectionName) const
|
||||||
{
|
{
|
||||||
auto section = new Framework::Xml::CNode(sectionName, true);
|
auto section = new Framework::Xml::CNode(sectionName, true);
|
||||||
Serialize(section);
|
Serialize(section);
|
||||||
parentNode->InsertNode(section);
|
parentNode->InsertNode(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMIPSTags::Unserialize(Framework::Xml::CNode* parentNode, const char* sectionName)
|
void CMIPSTags::Unserialize(Framework::Xml::CNode* parentNode, const char* sectionName)
|
||||||
|
@ -118,11 +117,11 @@ void CMIPSTags::Serialize(Framework::Xml::CNode* parentNode) const
|
||||||
void CMIPSTags::Unserialize(Framework::Xml::CNode* parentNode)
|
void CMIPSTags::Unserialize(Framework::Xml::CNode* parentNode)
|
||||||
{
|
{
|
||||||
for(Framework::Xml::CFilteringNodeIterator nodeIterator(parentNode, TAG_ELEMENT_NAME);
|
for(Framework::Xml::CFilteringNodeIterator nodeIterator(parentNode, TAG_ELEMENT_NAME);
|
||||||
!nodeIterator.IsEnd(); nodeIterator++)
|
!nodeIterator.IsEnd(); nodeIterator++)
|
||||||
{
|
{
|
||||||
auto node = *nodeIterator;
|
auto node = *nodeIterator;
|
||||||
auto addressText = node->GetAttribute(TAG_ELEMENT_ATTRIBUTE_ADDRESS);
|
auto addressText = node->GetAttribute(TAG_ELEMENT_ATTRIBUTE_ADDRESS);
|
||||||
auto valueText = node->GetAttribute(TAG_ELEMENT_ATTRIBUTE_VALUE);
|
auto valueText = node->GetAttribute(TAG_ELEMENT_ATTRIBUTE_VALUE);
|
||||||
if(!addressText || !valueText) continue;
|
if(!addressText || !valueText) continue;
|
||||||
uint32 address = lexical_cast_hex<std::string>(addressText);
|
uint32 address = lexical_cast_hex<std::string>(addressText);
|
||||||
InsertTag(address, valueText);
|
InsertTag(address, valueText);
|
||||||
|
|
|
@ -9,27 +9,27 @@
|
||||||
class CMIPSTags
|
class CMIPSTags
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<uint32, std::string> TagMap;
|
typedef std::map<uint32, std::string> TagMap;
|
||||||
typedef TagMap::const_iterator TagIterator;
|
typedef TagMap::const_iterator TagIterator;
|
||||||
|
|
||||||
boost::signals2::signal<void ()> OnTagListChange;
|
boost::signals2::signal<void()> OnTagListChange;
|
||||||
|
|
||||||
void InsertTag(uint32, const char*);
|
void InsertTag(uint32, const char*);
|
||||||
void RemoveTags();
|
void RemoveTags();
|
||||||
const char* Find(uint32) const;
|
const char* Find(uint32) const;
|
||||||
|
|
||||||
void Serialize(Framework::Xml::CNode*, const char*) const;
|
void Serialize(Framework::Xml::CNode*, const char*) const;
|
||||||
void Unserialize(Framework::Xml::CNode*, const char*);
|
void Unserialize(Framework::Xml::CNode*, const char*);
|
||||||
|
|
||||||
void Serialize(Framework::Xml::CNode*) const;
|
void Serialize(Framework::Xml::CNode*) const;
|
||||||
void Unserialize(Framework::Xml::CNode*);
|
void Unserialize(Framework::Xml::CNode*);
|
||||||
|
|
||||||
void Serialize(const char*) const;
|
void Serialize(const char*) const;
|
||||||
void Unserialize(const char*);
|
void Unserialize(const char*);
|
||||||
|
|
||||||
TagIterator GetTagsBegin() const;
|
TagIterator GetTagsBegin() const;
|
||||||
TagIterator GetTagsEnd() const;
|
TagIterator GetTagsEnd() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TagMap m_tags;
|
TagMap m_tags;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ void CMailBox::WaitForCall(unsigned int timeOut)
|
||||||
|
|
||||||
void CMailBox::FlushCalls()
|
void CMailBox::FlushCalls()
|
||||||
{
|
{
|
||||||
SendCall([] () { }, true);
|
SendCall([]() {}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMailBox::SendCall(const FunctionType& function, bool waitForCompletion)
|
void CMailBox::SendCall(const FunctionType& function, bool waitForCompletion)
|
||||||
|
@ -36,10 +36,10 @@ void CMailBox::SendCall(const FunctionType& function, bool waitForCompletion)
|
||||||
{
|
{
|
||||||
MESSAGE message;
|
MESSAGE message;
|
||||||
message.function = function;
|
message.function = function;
|
||||||
message.sync = waitForCompletion;
|
message.sync = waitForCompletion;
|
||||||
m_calls.push_back(std::move(message));
|
m_calls.push_back(std::move(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_waitCondition.notify_all();
|
m_waitCondition.notify_all();
|
||||||
|
|
||||||
if(waitForCompletion)
|
if(waitForCompletion)
|
||||||
|
@ -65,14 +65,14 @@ void CMailBox::SendCall(const FunctionType& function, bool waitForCompletion)
|
||||||
void CMailBox::SendCall(FunctionType&& function)
|
void CMailBox::SendCall(FunctionType&& function)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> callLock(m_callMutex);
|
std::lock_guard<std::mutex> callLock(m_callMutex);
|
||||||
|
|
||||||
{
|
{
|
||||||
MESSAGE message;
|
MESSAGE message;
|
||||||
message.function = std::move(function);
|
message.function = std::move(function);
|
||||||
message.sync = false;
|
message.sync = false;
|
||||||
m_calls.push_back(std::move(message));
|
m_calls.push_back(std::move(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_waitCondition.notify_all();
|
m_waitCondition.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,18 @@
|
||||||
class CMailBox
|
class CMailBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~CMailBox() = default;
|
virtual ~CMailBox() = default;
|
||||||
|
|
||||||
typedef std::function<void ()> FunctionType;
|
typedef std::function<void()> FunctionType;
|
||||||
|
|
||||||
void SendCall(const FunctionType&, bool = false);
|
void SendCall(const FunctionType&, bool = false);
|
||||||
void SendCall(FunctionType&&);
|
void SendCall(FunctionType&&);
|
||||||
void FlushCalls();
|
void FlushCalls();
|
||||||
|
|
||||||
bool IsPending() const;
|
bool IsPending() const;
|
||||||
void ReceiveCall();
|
void ReceiveCall();
|
||||||
void WaitForCall();
|
void WaitForCall();
|
||||||
void WaitForCall(unsigned int);
|
void WaitForCall(unsigned int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MESSAGE
|
struct MESSAGE
|
||||||
|
@ -29,18 +29,18 @@ private:
|
||||||
MESSAGE(MESSAGE&&) = default;
|
MESSAGE(MESSAGE&&) = default;
|
||||||
MESSAGE(const MESSAGE&) = delete;
|
MESSAGE(const MESSAGE&) = delete;
|
||||||
|
|
||||||
MESSAGE& operator =(MESSAGE&&) = default;
|
MESSAGE& operator=(MESSAGE&&) = default;
|
||||||
MESSAGE& operator =(const MESSAGE&) = delete;
|
MESSAGE& operator=(const MESSAGE&) = delete;
|
||||||
|
|
||||||
FunctionType function;
|
FunctionType function;
|
||||||
bool sync;
|
bool sync;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::deque<MESSAGE> FunctionCallQueue;
|
typedef std::deque<MESSAGE> FunctionCallQueue;
|
||||||
|
|
||||||
FunctionCallQueue m_calls;
|
FunctionCallQueue m_calls;
|
||||||
std::mutex m_callMutex;
|
std::mutex m_callMutex;
|
||||||
std::condition_variable m_callFinished;
|
std::condition_variable m_callFinished;
|
||||||
std::condition_variable m_waitCondition;
|
std::condition_variable m_waitCondition;
|
||||||
bool m_callDone;
|
bool m_callDone;
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,21 +47,21 @@ const CMemoryMap::MEMORYMAPELEMENT* CMemoryMap::GetWriteMap(uint32 address) cons
|
||||||
void CMemoryMap::InsertMap(MemoryMapListType& memoryMap, uint32 start, uint32 end, void* pointer, unsigned char key)
|
void CMemoryMap::InsertMap(MemoryMapListType& memoryMap, uint32 start, uint32 end, void* pointer, unsigned char key)
|
||||||
{
|
{
|
||||||
MEMORYMAPELEMENT element;
|
MEMORYMAPELEMENT element;
|
||||||
element.nStart = start;
|
element.nStart = start;
|
||||||
element.nEnd = end;
|
element.nEnd = end;
|
||||||
element.pPointer = pointer;
|
element.pPointer = pointer;
|
||||||
element.nType = MEMORYMAP_TYPE_MEMORY;
|
element.nType = MEMORYMAP_TYPE_MEMORY;
|
||||||
memoryMap.push_back(element);
|
memoryMap.push_back(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryMap::InsertMap(MemoryMapListType& memoryMap, uint32 start, uint32 end, const MemoryMapHandlerType& handler, unsigned char key)
|
void CMemoryMap::InsertMap(MemoryMapListType& memoryMap, uint32 start, uint32 end, const MemoryMapHandlerType& handler, unsigned char key)
|
||||||
{
|
{
|
||||||
MEMORYMAPELEMENT element;
|
MEMORYMAPELEMENT element;
|
||||||
element.nStart = start;
|
element.nStart = start;
|
||||||
element.nEnd = end;
|
element.nEnd = end;
|
||||||
element.handler = handler;
|
element.handler = handler;
|
||||||
element.pPointer = nullptr;
|
element.pPointer = nullptr;
|
||||||
element.nType = MEMORYMAP_TYPE_FUNCTION;
|
element.nType = MEMORYMAP_TYPE_FUNCTION;
|
||||||
memoryMap.push_back(element);
|
memoryMap.push_back(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ enum MEMORYMAP_ENDIANESS
|
||||||
class CMemoryMap
|
class CMemoryMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<uint32 (uint32, uint32)> MemoryMapHandlerType;
|
typedef std::function<uint32(uint32, uint32)> MemoryMapHandlerType;
|
||||||
|
|
||||||
enum MEMORYMAP_TYPE
|
enum MEMORYMAP_TYPE
|
||||||
{
|
{
|
||||||
|
@ -24,51 +24,51 @@ public:
|
||||||
|
|
||||||
struct MEMORYMAPELEMENT
|
struct MEMORYMAPELEMENT
|
||||||
{
|
{
|
||||||
uint32 nStart;
|
uint32 nStart;
|
||||||
uint32 nEnd;
|
uint32 nEnd;
|
||||||
void* pPointer;
|
void* pPointer;
|
||||||
MemoryMapHandlerType handler;
|
MemoryMapHandlerType handler;
|
||||||
MEMORYMAP_TYPE nType;
|
MEMORYMAP_TYPE nType;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~CMemoryMap() = default;
|
virtual ~CMemoryMap() = default;
|
||||||
uint8 GetByte(uint32);
|
uint8 GetByte(uint32);
|
||||||
virtual uint16 GetHalf(uint32) = 0;
|
virtual uint16 GetHalf(uint32) = 0;
|
||||||
virtual uint32 GetWord(uint32) = 0;
|
virtual uint32 GetWord(uint32) = 0;
|
||||||
virtual uint32 GetInstruction(uint32) = 0;
|
virtual uint32 GetInstruction(uint32) = 0;
|
||||||
virtual void SetByte(uint32, uint8);
|
virtual void SetByte(uint32, uint8);
|
||||||
virtual void SetHalf(uint32, uint16) = 0;
|
virtual void SetHalf(uint32, uint16) = 0;
|
||||||
virtual void SetWord(uint32, uint32) = 0;
|
virtual void SetWord(uint32, uint32) = 0;
|
||||||
void InsertReadMap(uint32, uint32, void*, unsigned char);
|
void InsertReadMap(uint32, uint32, void*, unsigned char);
|
||||||
void InsertReadMap(uint32, uint32, const MemoryMapHandlerType&, unsigned char);
|
void InsertReadMap(uint32, uint32, const MemoryMapHandlerType&, unsigned char);
|
||||||
void InsertWriteMap(uint32, uint32, void*, unsigned char);
|
void InsertWriteMap(uint32, uint32, void*, unsigned char);
|
||||||
void InsertWriteMap(uint32, uint32, const MemoryMapHandlerType&, unsigned char);
|
void InsertWriteMap(uint32, uint32, const MemoryMapHandlerType&, unsigned char);
|
||||||
void InsertInstructionMap(uint32, uint32, void*, unsigned char);
|
void InsertInstructionMap(uint32, uint32, void*, unsigned char);
|
||||||
const MEMORYMAPELEMENT* GetReadMap(uint32) const;
|
const MEMORYMAPELEMENT* GetReadMap(uint32) const;
|
||||||
const MEMORYMAPELEMENT* GetWriteMap(uint32) const;
|
const MEMORYMAPELEMENT* GetWriteMap(uint32) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<MEMORYMAPELEMENT> MemoryMapListType;
|
typedef std::vector<MEMORYMAPELEMENT> MemoryMapListType;
|
||||||
|
|
||||||
static const MEMORYMAPELEMENT* GetMap(const MemoryMapListType&, uint32);
|
static const MEMORYMAPELEMENT* GetMap(const MemoryMapListType&, uint32);
|
||||||
|
|
||||||
MemoryMapListType m_instructionMap;
|
MemoryMapListType m_instructionMap;
|
||||||
MemoryMapListType m_readMap;
|
MemoryMapListType m_readMap;
|
||||||
MemoryMapListType m_writeMap;
|
MemoryMapListType m_writeMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void InsertMap(MemoryMapListType&, uint32, uint32, void*, unsigned char);
|
static void InsertMap(MemoryMapListType&, uint32, uint32, void*, unsigned char);
|
||||||
static void InsertMap(MemoryMapListType&, uint32, uint32, const MemoryMapHandlerType&, unsigned char);
|
static void InsertMap(MemoryMapListType&, uint32, uint32, const MemoryMapHandlerType&, unsigned char);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CMemoryMap_LSBF : public CMemoryMap
|
class CMemoryMap_LSBF : public CMemoryMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint16 GetHalf(uint32);
|
uint16 GetHalf(uint32);
|
||||||
uint32 GetWord(uint32);
|
uint32 GetWord(uint32);
|
||||||
uint32 GetInstruction(uint32);
|
uint32 GetInstruction(uint32);
|
||||||
void SetHalf(uint32, uint16);
|
void SetHalf(uint32, uint16);
|
||||||
void SetWord(uint32, uint32);
|
void SetWord(uint32, uint32);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#include "MemoryStateFile.h"
|
#include "MemoryStateFile.h"
|
||||||
|
|
||||||
CMemoryStateFile::CMemoryStateFile(const char* name, const void* memory, size_t size)
|
CMemoryStateFile::CMemoryStateFile(const char* name, const void* memory, size_t size)
|
||||||
: CZipFile(name)
|
: CZipFile(name)
|
||||||
, m_memory(memory)
|
, m_memory(memory)
|
||||||
, m_size(size)
|
, m_size(size)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemoryStateFile::Write(Framework::CStream& stream)
|
void CMemoryStateFile::Write(Framework::CStream& stream)
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
class CMemoryStateFile : public Framework::CZipFile
|
class CMemoryStateFile : public Framework::CZipFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMemoryStateFile(const char*, const void*, size_t);
|
CMemoryStateFile(const char*, const void*, size_t);
|
||||||
virtual ~CMemoryStateFile() = default;
|
virtual ~CMemoryStateFile() = default;
|
||||||
|
|
||||||
void Write(Framework::CStream&) override;
|
void Write(Framework::CStream&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const void* m_memory = nullptr;
|
const void* m_memory = nullptr;
|
||||||
size_t m_size = 0;
|
size_t m_size = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,7 +101,7 @@ void MemoryUtils_SetDoubleProxy(CMIPS* context, uint64 value64, uint32 address)
|
||||||
if(!e)
|
if(!e)
|
||||||
{
|
{
|
||||||
CLog::GetInstance().Print(LOG_NAME, "Wrote to unmapped memory (0x%08X, [0x%08X, 0x%08X]).\r\n",
|
CLog::GetInstance().Print(LOG_NAME, "Wrote to unmapped memory (0x%08X, [0x%08X, 0x%08X]).\r\n",
|
||||||
address, value.d0, value.d1);
|
address, value.d0, value.d1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(e->nType)
|
switch(e->nType)
|
||||||
|
@ -127,8 +127,8 @@ void MemoryUtils_SetQuadProxy(CMIPS* context, const uint128& value, uint32 addre
|
||||||
auto e = context->m_pMemoryMap->GetWriteMap(address);
|
auto e = context->m_pMemoryMap->GetWriteMap(address);
|
||||||
if(!e)
|
if(!e)
|
||||||
{
|
{
|
||||||
CLog::GetInstance().Print(LOG_NAME, "Wrote to unmapped memory (0x%08X, [0x%08X, 0x%08X, 0x%08X, 0x%08X]).\r\n",
|
CLog::GetInstance().Print(LOG_NAME, "Wrote to unmapped memory (0x%08X, [0x%08X, 0x%08X, 0x%08X, 0x%08X]).\r\n",
|
||||||
address, value.nV0, value.nV1, value.nV2, value.nV3);
|
address, value.nV0, value.nV1, value.nV2, value.nV3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(e->nType)
|
switch(e->nType)
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
uint32 MemoryUtils_GetByteProxy(CMIPS*, uint32);
|
uint32 MemoryUtils_GetByteProxy(CMIPS*, uint32);
|
||||||
uint32 MemoryUtils_GetHalfProxy(CMIPS*, uint32);
|
uint32 MemoryUtils_GetHalfProxy(CMIPS*, uint32);
|
||||||
uint32 MemoryUtils_GetWordProxy(CMIPS*, uint32);
|
uint32 MemoryUtils_GetWordProxy(CMIPS*, uint32);
|
||||||
uint64 MemoryUtils_GetDoubleProxy(CMIPS*, uint32);
|
uint64 MemoryUtils_GetDoubleProxy(CMIPS*, uint32);
|
||||||
uint128 MemoryUtils_GetQuadProxy(CMIPS*, uint32);
|
uint128 MemoryUtils_GetQuadProxy(CMIPS*, uint32);
|
||||||
|
|
||||||
void MemoryUtils_SetByteProxy(CMIPS*, uint32, uint32);
|
void MemoryUtils_SetByteProxy(CMIPS*, uint32, uint32);
|
||||||
void MemoryUtils_SetHalfProxy(CMIPS*, uint32, uint32);
|
void MemoryUtils_SetHalfProxy(CMIPS*, uint32, uint32);
|
||||||
void MemoryUtils_SetWordProxy(CMIPS*, uint32, uint32);
|
void MemoryUtils_SetWordProxy(CMIPS*, uint32, uint32);
|
||||||
void MemoryUtils_SetDoubleProxy(CMIPS*, uint64, uint32);
|
void MemoryUtils_SetDoubleProxy(CMIPS*, uint64, uint32);
|
||||||
void MemoryUtils_SetQuadProxy(CMIPS*, const uint128&, uint32);
|
void MemoryUtils_SetQuadProxy(CMIPS*, const uint128&, uint32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ static bool IsInsideRange(uint32 address, uint32 start, uint32 end)
|
||||||
#define SUBTABLE_MASK (SUBTABLE_SIZE - 1)
|
#define SUBTABLE_MASK (SUBTABLE_SIZE - 1)
|
||||||
|
|
||||||
CMipsExecutor::CMipsExecutor(CMIPS& context, uint32 maxAddress)
|
CMipsExecutor::CMipsExecutor(CMIPS& context, uint32 maxAddress)
|
||||||
: m_context(context)
|
: m_context(context)
|
||||||
, m_maxAddress(maxAddress)
|
, m_maxAddress(maxAddress)
|
||||||
{
|
{
|
||||||
m_subTableCount = (m_maxAddress + SUBTABLE_MASK) / SUBTABLE_SIZE;
|
m_subTableCount = (m_maxAddress + SUBTABLE_MASK) / SUBTABLE_SIZE;
|
||||||
assert(m_subTableCount != 0);
|
assert(m_subTableCount != 0);
|
||||||
|
@ -26,10 +26,10 @@ CMipsExecutor::~CMipsExecutor()
|
||||||
CBasicBlock** subTable = m_blockTable[i];
|
CBasicBlock** subTable = m_blockTable[i];
|
||||||
if(subTable != NULL)
|
if(subTable != NULL)
|
||||||
{
|
{
|
||||||
delete [] subTable;
|
delete[] subTable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] m_blockTable;
|
delete[] m_blockTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMipsExecutor::Reset()
|
void CMipsExecutor::Reset()
|
||||||
|
@ -44,11 +44,11 @@ void CMipsExecutor::ClearActiveBlocks()
|
||||||
CBasicBlock** subTable = m_blockTable[i];
|
CBasicBlock** subTable = m_blockTable[i];
|
||||||
if(subTable != NULL)
|
if(subTable != NULL)
|
||||||
{
|
{
|
||||||
delete [] subTable;
|
delete[] subTable;
|
||||||
m_blockTable[i] = NULL;
|
m_blockTable[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_blocks.clear();
|
m_blocks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +80,7 @@ void CMipsExecutor::ClearActiveBlocksInRangeInternal(uint32 start, uint32 end, C
|
||||||
auto block = table[lo / 4];
|
auto block = table[lo / 4];
|
||||||
if(block == nullptr) continue;
|
if(block == nullptr) continue;
|
||||||
if(block == protectedBlock) continue;
|
if(block == protectedBlock) continue;
|
||||||
if(!IsInsideRange(block->GetBeginAddress(), start, end)
|
if(!IsInsideRange(block->GetBeginAddress(), start, end) && !IsInsideRange(block->GetEndAddress(), start, end)) continue;
|
||||||
&& !IsInsideRange(block->GetEndAddress(), start, end)) continue;
|
|
||||||
table[lo / 4] = nullptr;
|
table[lo / 4] = nullptr;
|
||||||
blocksToDelete.insert(block);
|
blocksToDelete.insert(block);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +88,7 @@ void CMipsExecutor::ClearActiveBlocksInRangeInternal(uint32 start, uint32 end, C
|
||||||
|
|
||||||
if(!blocksToDelete.empty())
|
if(!blocksToDelete.empty())
|
||||||
{
|
{
|
||||||
m_blocks.remove_if([&] (const BasicBlockPtr& block) { return blocksToDelete.find(block.get()) != std::end(blocksToDelete); });
|
m_blocks.remove_if([&](const BasicBlockPtr& block) { return blocksToDelete.find(block.get()) != std::end(blocksToDelete); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +213,7 @@ void CMipsExecutor::DeleteBlock(CBasicBlock* block)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove block from our lists
|
//Remove block from our lists
|
||||||
auto blockIterator = std::find_if(std::begin(m_blocks), std::end(m_blocks), [&] (const BasicBlockPtr& blockPtr) { return blockPtr.get() == block; });
|
auto blockIterator = std::find_if(std::begin(m_blocks), std::end(m_blocks), [&](const BasicBlockPtr& blockPtr) { return blockPtr.get() == block; });
|
||||||
assert(blockIterator != std::end(m_blocks));
|
assert(blockIterator != std::end(m_blocks));
|
||||||
m_blocks.erase(blockIterator);
|
m_blocks.erase(blockIterator);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +235,7 @@ void CMipsExecutor::PartitionFunction(uint32 functionAddress)
|
||||||
partitionPoints.insert(functionAddress);
|
partitionPoints.insert(functionAddress);
|
||||||
|
|
||||||
//Find the end
|
//Find the end
|
||||||
for(uint32 address = functionAddress; ; address += 4)
|
for(uint32 address = functionAddress;; address += 4)
|
||||||
{
|
{
|
||||||
//Probably going too far...
|
//Probably going too far...
|
||||||
if((address - functionAddress) > 0x10000)
|
if((address - functionAddress) > 0x10000)
|
||||||
|
@ -292,7 +291,7 @@ void CMipsExecutor::PartitionFunction(uint32 functionAddress)
|
||||||
{
|
{
|
||||||
uint32 currentPoint = -1;
|
uint32 currentPoint = -1;
|
||||||
for(PartitionPointSet::const_iterator pointIterator(partitionPoints.begin());
|
for(PartitionPointSet::const_iterator pointIterator(partitionPoints.begin());
|
||||||
pointIterator != partitionPoints.end(); ++pointIterator)
|
pointIterator != partitionPoints.end(); ++pointIterator)
|
||||||
{
|
{
|
||||||
if(currentPoint != -1)
|
if(currentPoint != -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
class CMipsExecutor
|
class CMipsExecutor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMipsExecutor(CMIPS&, uint32);
|
CMipsExecutor(CMIPS&, uint32);
|
||||||
virtual ~CMipsExecutor();
|
virtual ~CMipsExecutor();
|
||||||
|
|
||||||
template <uint32 (*TranslateFunction)(CMIPS*, uint32) = CMIPS::TranslateAddress64>
|
template <uint32 (*TranslateFunction)(CMIPS*, uint32) = CMIPS::TranslateAddress64>
|
||||||
int Execute(int cycles)
|
int Execute(int cycles)
|
||||||
|
@ -40,36 +40,36 @@ public:
|
||||||
return cycles;
|
return cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBasicBlock* FindBlockAt(uint32) const;
|
CBasicBlock* FindBlockAt(uint32) const;
|
||||||
CBasicBlock* FindBlockStartingAt(uint32) const;
|
CBasicBlock* FindBlockStartingAt(uint32) const;
|
||||||
void DeleteBlock(CBasicBlock*);
|
void DeleteBlock(CBasicBlock*);
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
void ClearActiveBlocks();
|
void ClearActiveBlocks();
|
||||||
virtual void ClearActiveBlocksInRange(uint32, uint32);
|
virtual void ClearActiveBlocksInRange(uint32, uint32);
|
||||||
|
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
bool MustBreak() const;
|
bool MustBreak() const;
|
||||||
void DisableBreakpointsOnce();
|
void DisableBreakpointsOnce();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::shared_ptr<CBasicBlock> BasicBlockPtr;
|
typedef std::shared_ptr<CBasicBlock> BasicBlockPtr;
|
||||||
typedef std::list<BasicBlockPtr> BlockList;
|
typedef std::list<BasicBlockPtr> BlockList;
|
||||||
|
|
||||||
void CreateBlock(uint32, uint32);
|
void CreateBlock(uint32, uint32);
|
||||||
virtual BasicBlockPtr BlockFactory(CMIPS&, uint32, uint32);
|
virtual BasicBlockPtr BlockFactory(CMIPS&, uint32, uint32);
|
||||||
virtual void PartitionFunction(uint32);
|
virtual void PartitionFunction(uint32);
|
||||||
|
|
||||||
void ClearActiveBlocksInRangeInternal(uint32, uint32, CBasicBlock*);
|
|
||||||
|
|
||||||
BlockList m_blocks;
|
void ClearActiveBlocksInRangeInternal(uint32, uint32, CBasicBlock*);
|
||||||
CMIPS& m_context;
|
|
||||||
uint32 m_maxAddress = 0;
|
|
||||||
|
|
||||||
CBasicBlock*** m_blockTable = nullptr;
|
BlockList m_blocks;
|
||||||
uint32 m_subTableCount = 0;
|
CMIPS& m_context;
|
||||||
|
uint32 m_maxAddress = 0;
|
||||||
|
|
||||||
|
CBasicBlock*** m_blockTable = nullptr;
|
||||||
|
uint32 m_subTableCount = 0;
|
||||||
|
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
bool m_breakpointsDisabledOnce = false;
|
bool m_breakpointsDisabledOnce = false;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,6 @@ CMipsFunctionPatternDb::CMipsFunctionPatternDb(Framework::Xml::CNode* node)
|
||||||
|
|
||||||
CMipsFunctionPatternDb::~CMipsFunctionPatternDb()
|
CMipsFunctionPatternDb::~CMipsFunctionPatternDb()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CMipsFunctionPatternDb::PatternArray& CMipsFunctionPatternDb::GetPatterns() const
|
const CMipsFunctionPatternDb::PatternArray& CMipsFunctionPatternDb::GetPatterns() const
|
||||||
|
@ -24,8 +23,8 @@ void CMipsFunctionPatternDb::Read(Framework::Xml::CNode* node)
|
||||||
|
|
||||||
m_patterns.reserve(patternsNode->GetChildCount());
|
m_patterns.reserve(patternsNode->GetChildCount());
|
||||||
|
|
||||||
for(Framework::Xml::CFilteringNodeIterator patternNodeIterator(patternsNode, "FunctionPattern");
|
for(Framework::Xml::CFilteringNodeIterator patternNodeIterator(patternsNode, "FunctionPattern");
|
||||||
!patternNodeIterator.IsEnd(); patternNodeIterator++)
|
!patternNodeIterator.IsEnd(); patternNodeIterator++)
|
||||||
{
|
{
|
||||||
auto patternNode = (*patternNodeIterator);
|
auto patternNode = (*patternNodeIterator);
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ void CMipsFunctionPatternDb::Read(Framework::Xml::CNode* node)
|
||||||
if(patternName == NULL) continue;
|
if(patternName == NULL) continue;
|
||||||
|
|
||||||
const char* patternSource = patternNode->GetInnerText();
|
const char* patternSource = patternNode->GetInnerText();
|
||||||
|
|
||||||
Pattern pattern = ParsePattern(patternSource);
|
Pattern pattern = ParsePattern(patternSource);
|
||||||
pattern.name = patternName;
|
pattern.name = patternName;
|
||||||
m_patterns.push_back(pattern);
|
m_patterns.push_back(pattern);
|
||||||
|
@ -69,7 +68,7 @@ CMipsFunctionPatternDb::Pattern CMipsFunctionPatternDb::ParsePattern(const char*
|
||||||
if(currValue.length() != 0)
|
if(currValue.length() != 0)
|
||||||
{
|
{
|
||||||
//Parse value
|
//Parse value
|
||||||
PATTERNITEM item = { 0 };
|
PATTERNITEM item = {0};
|
||||||
if(ParsePatternItem(currValue.c_str(), item))
|
if(ParsePatternItem(currValue.c_str(), item))
|
||||||
{
|
{
|
||||||
result.items.push_back(item);
|
result.items.push_back(item);
|
||||||
|
|
|
@ -11,8 +11,8 @@ class CMipsFunctionPatternDb
|
||||||
public:
|
public:
|
||||||
struct PATTERNITEM
|
struct PATTERNITEM
|
||||||
{
|
{
|
||||||
uint32 value;
|
uint32 value;
|
||||||
uint32 mask;
|
uint32 mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pattern
|
class Pattern
|
||||||
|
@ -20,26 +20,25 @@ public:
|
||||||
public:
|
public:
|
||||||
typedef std::vector<PATTERNITEM> ItemArray;
|
typedef std::vector<PATTERNITEM> ItemArray;
|
||||||
|
|
||||||
bool Matches(uint32*, uint32) const;
|
bool Matches(uint32*, uint32) const;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
ItemArray items;
|
ItemArray items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<Pattern> PatternArray;
|
typedef std::vector<Pattern> PatternArray;
|
||||||
|
|
||||||
CMipsFunctionPatternDb(Framework::Xml::CNode*);
|
CMipsFunctionPatternDb(Framework::Xml::CNode*);
|
||||||
virtual ~CMipsFunctionPatternDb();
|
virtual ~CMipsFunctionPatternDb();
|
||||||
|
|
||||||
const PatternArray& GetPatterns() const;
|
const PatternArray& GetPatterns() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Read(Framework::Xml::CNode*);
|
void Read(Framework::Xml::CNode*);
|
||||||
Pattern ParsePattern(const char*);
|
Pattern ParsePattern(const char*);
|
||||||
bool ParsePatternItem(const char*, PATTERNITEM&);
|
bool ParsePatternItem(const char*, PATTERNITEM&);
|
||||||
|
|
||||||
PatternArray m_patterns;
|
PatternArray m_patterns;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,15 +2,13 @@
|
||||||
#include "MipsJitter.h"
|
#include "MipsJitter.h"
|
||||||
|
|
||||||
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
||||||
: CJitter(codeGen)
|
: CJitter(codeGen)
|
||||||
, m_lastBlockLabel(-1)
|
, m_lastBlockLabel(-1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMipsJitter::~CMipsJitter()
|
CMipsJitter::~CMipsJitter()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMipsJitter::Begin()
|
void CMipsJitter::Begin()
|
||||||
|
|
|
@ -6,30 +6,30 @@
|
||||||
class CMipsJitter : public Jitter::CJitter
|
class CMipsJitter : public Jitter::CJitter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMipsJitter(Jitter::CCodeGen*);
|
CMipsJitter(Jitter::CCodeGen*);
|
||||||
virtual ~CMipsJitter();
|
virtual ~CMipsJitter();
|
||||||
|
|
||||||
virtual void Begin();
|
virtual void Begin();
|
||||||
virtual void End();
|
virtual void End();
|
||||||
virtual void PushRel(size_t);
|
virtual void PushRel(size_t);
|
||||||
virtual void PushRel64(size_t);
|
virtual void PushRel64(size_t);
|
||||||
|
|
||||||
void SetVariableAsConstant(size_t, uint32);
|
void SetVariableAsConstant(size_t, uint32);
|
||||||
LABEL GetFinalBlockLabel();
|
LABEL GetFinalBlockLabel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VARIABLESTATUS
|
struct VARIABLESTATUS
|
||||||
{
|
{
|
||||||
uint32 operandType;
|
uint32 operandType;
|
||||||
uint32 operandValue;
|
uint32 operandValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<size_t, VARIABLESTATUS> VariableStatusMap;
|
typedef std::map<size_t, VARIABLESTATUS> VariableStatusMap;
|
||||||
|
|
||||||
VARIABLESTATUS* GetVariableStatus(size_t);
|
VARIABLESTATUS* GetVariableStatus(size_t);
|
||||||
void SetVariableStatus(size_t, const VARIABLESTATUS&);
|
void SetVariableStatus(size_t, const VARIABLESTATUS&);
|
||||||
void SaveVariableStatus(size_t, const VARIABLESTATUS&);
|
void SaveVariableStatus(size_t, const VARIABLESTATUS&);
|
||||||
|
|
||||||
VariableStatusMap m_variableStatus;
|
VariableStatusMap m_variableStatus;
|
||||||
LABEL m_lastBlockLabel;
|
LABEL m_lastBlockLabel;
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,9 +81,8 @@ void COpticalMedia::CheckDualLayerDvd(const StreamPtr& stream)
|
||||||
char blockHeader[blockHeaderSize];
|
char blockHeader[blockHeaderSize];
|
||||||
stream->Read(blockHeader, blockHeaderSize);
|
stream->Read(blockHeader, blockHeaderSize);
|
||||||
if(
|
if(
|
||||||
(blockHeader[0] == 0x01) &&
|
(blockHeader[0] == 0x01) &&
|
||||||
(!strncmp(blockHeader + 1, "CD001", 5))
|
(!strncmp(blockHeader + 1, "CD001", 5)))
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//We've found a valid ISO9660 descriptor
|
//We've found a valid ISO9660 descriptor
|
||||||
m_dvdSecondLayerStart = lba;
|
m_dvdSecondLayerStart = lba;
|
||||||
|
|
|
@ -18,19 +18,19 @@ public:
|
||||||
COpticalMedia(const StreamPtr&);
|
COpticalMedia(const StreamPtr&);
|
||||||
|
|
||||||
//TODO: Get Track Count
|
//TODO: Get Track Count
|
||||||
TRACK_DATA_TYPE GetTrackDataType(uint32) const;
|
TRACK_DATA_TYPE GetTrackDataType(uint32) const;
|
||||||
CISO9660* GetFileSystem();
|
CISO9660* GetFileSystem();
|
||||||
|
|
||||||
bool GetDvdIsDualLayer() const;
|
bool GetDvdIsDualLayer() const;
|
||||||
uint32 GetDvdSecondLayerStart() const;
|
uint32 GetDvdSecondLayerStart() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::unique_ptr<CISO9660> Iso9660Ptr;
|
typedef std::unique_ptr<CISO9660> Iso9660Ptr;
|
||||||
|
|
||||||
void CheckDualLayerDvd(const StreamPtr&);
|
void CheckDualLayerDvd(const StreamPtr&);
|
||||||
|
|
||||||
TRACK_DATA_TYPE m_track0DataType = TRACK_DATA_TYPE_MODE1_2048;
|
TRACK_DATA_TYPE m_track0DataType = TRACK_DATA_TYPE_MODE1_2048;
|
||||||
bool m_dvdIsDualLayer = false;
|
bool m_dvdIsDualLayer = false;
|
||||||
uint32 m_dvdSecondLayerStart = 0;
|
uint32 m_dvdSecondLayerStart = 0;
|
||||||
Iso9660Ptr m_fileSystem;
|
Iso9660Ptr m_fileSystem;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,34 +1,38 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
template<typename StructType>
|
template <typename StructType>
|
||||||
class COsStructManager
|
class COsStructManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
iterator(const COsStructManager& container, uint32 id) : m_container(container), m_id(id) {}
|
iterator(const COsStructManager& container, uint32 id)
|
||||||
|
: m_container(container)
|
||||||
|
, m_id(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
iterator& operator ++()
|
iterator& operator++()
|
||||||
{
|
{
|
||||||
m_id++;
|
m_id++;
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator operator ++(int)
|
iterator operator++(int)
|
||||||
{
|
{
|
||||||
iterator copy(*this);
|
iterator copy(*this);
|
||||||
m_id++;
|
m_id++;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const iterator& rhs) const
|
bool operator!=(const iterator& rhs) const
|
||||||
{
|
{
|
||||||
return m_id != rhs.m_id;
|
return m_id != rhs.m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructType* operator *() const
|
StructType* operator*() const
|
||||||
{
|
{
|
||||||
return m_container[m_id];
|
return m_container[m_id];
|
||||||
}
|
}
|
||||||
|
@ -49,22 +53,22 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
COsStructManager(StructType* structBase, uint32 idBase, uint32 structMax)
|
COsStructManager(StructType* structBase, uint32 idBase, uint32 structMax)
|
||||||
: m_structBase(structBase)
|
: m_structBase(structBase)
|
||||||
, m_structMax(structMax)
|
, m_structMax(structMax)
|
||||||
, m_idBase(idBase)
|
, m_idBase(idBase)
|
||||||
{
|
{
|
||||||
assert(m_idBase != 0);
|
assert(m_idBase != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
COsStructManager(const COsStructManager&) = delete;
|
COsStructManager(const COsStructManager&) = delete;
|
||||||
COsStructManager& operator =(const COsStructManager) = delete;
|
COsStructManager& operator=(const COsStructManager) = delete;
|
||||||
|
|
||||||
StructType* GetBase() const
|
StructType* GetBase() const
|
||||||
{
|
{
|
||||||
return m_structBase;
|
return m_structBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructType* operator [](uint32 index) const
|
StructType* operator[](uint32 index) const
|
||||||
{
|
{
|
||||||
index -= m_idBase;
|
index -= m_idBase;
|
||||||
if(index >= m_structMax)
|
if(index >= m_structMax)
|
||||||
|
@ -121,7 +125,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StructType* m_structBase = nullptr;
|
StructType* m_structBase = nullptr;
|
||||||
uint32 m_structMax = 0;
|
uint32 m_structMax = 0;
|
||||||
uint32 m_idBase = 0;
|
uint32 m_idBase = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,27 +9,31 @@ public:
|
||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
iterator(const StructManager& container, uint32* idPtr) : m_container(container), m_idPtr(idPtr) {}
|
iterator(const StructManager& container, uint32* idPtr)
|
||||||
|
: m_container(container)
|
||||||
|
, m_idPtr(idPtr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
iterator& operator ++()
|
iterator& operator++()
|
||||||
{
|
{
|
||||||
MoveNext();
|
MoveNext();
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator operator ++(int)
|
iterator operator++(int)
|
||||||
{
|
{
|
||||||
iterator copy(*this);
|
iterator copy(*this);
|
||||||
MoveNext();
|
MoveNext();
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const iterator& rhs) const
|
bool operator!=(const iterator& rhs) const
|
||||||
{
|
{
|
||||||
return m_idPtr != rhs.m_idPtr;
|
return m_idPtr != rhs.m_idPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint32, StructType*> operator *() const
|
std::pair<uint32, StructType*> operator*() const
|
||||||
{
|
{
|
||||||
assert(m_idPtr);
|
assert(m_idPtr);
|
||||||
return std::make_pair(*m_idPtr, m_container[*m_idPtr]);
|
return std::make_pair(*m_idPtr, m_container[*m_idPtr]);
|
||||||
|
@ -52,14 +56,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
COsStructQueue(StructManager& items, uint32* headIdPtr)
|
COsStructQueue(StructManager& items, uint32* headIdPtr)
|
||||||
: m_items(items)
|
: m_items(items)
|
||||||
, m_headIdPtr(headIdPtr)
|
, m_headIdPtr(headIdPtr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COsStructQueue(const COsStructQueue&) = delete;
|
COsStructQueue(const COsStructQueue&) = delete;
|
||||||
COsStructQueue& operator =(const COsStructQueue) = delete;
|
COsStructQueue& operator=(const COsStructQueue) = delete;
|
||||||
|
|
||||||
bool IsEmpty() const
|
bool IsEmpty() const
|
||||||
{
|
{
|
||||||
|
@ -142,6 +145,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StructManager& m_items;
|
StructManager& m_items;
|
||||||
uint32* m_headIdPtr = nullptr;
|
uint32* m_headIdPtr = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,18 +4,21 @@ template <typename Type>
|
||||||
struct OsVariableWrapper
|
struct OsVariableWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit OsVariableWrapper(Type* storage) : m_storage(storage) { }
|
explicit OsVariableWrapper(Type* storage)
|
||||||
|
: m_storage(storage)
|
||||||
|
{
|
||||||
|
}
|
||||||
OsVariableWrapper(const OsVariableWrapper&) = delete;
|
OsVariableWrapper(const OsVariableWrapper&) = delete;
|
||||||
|
|
||||||
OsVariableWrapper& operator =(const OsVariableWrapper&) = delete;
|
OsVariableWrapper& operator=(const OsVariableWrapper&) = delete;
|
||||||
|
|
||||||
OsVariableWrapper& operator =(const Type& value)
|
OsVariableWrapper& operator=(const Type& value)
|
||||||
{
|
{
|
||||||
(*m_storage) = value;
|
(*m_storage) = value;
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type& operator +=(const Type& addend)
|
Type& operator+=(const Type& addend)
|
||||||
{
|
{
|
||||||
(*m_storage) += addend;
|
(*m_storage) += addend;
|
||||||
return (*m_storage);
|
return (*m_storage);
|
||||||
|
@ -32,5 +35,5 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type* m_storage;
|
Type* m_storage;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,12 +10,11 @@ CPH_Generic::CPH_Generic()
|
||||||
|
|
||||||
CPH_Generic::~CPH_Generic()
|
CPH_Generic::~CPH_Generic()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPadHandler::FactoryFunction CPH_Generic::GetFactoryFunction()
|
CPadHandler::FactoryFunction CPH_Generic::GetFactoryFunction()
|
||||||
{
|
{
|
||||||
return [] () { return new CPH_Generic(); };
|
return []() { return new CPH_Generic(); };
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPH_Generic::Update(uint8* ram)
|
void CPH_Generic::Update(uint8* ram)
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
class CPH_Generic : public CPadHandler
|
class CPH_Generic : public CPadHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPH_Generic();
|
CPH_Generic();
|
||||||
virtual ~CPH_Generic();
|
virtual ~CPH_Generic();
|
||||||
|
|
||||||
static FactoryFunction GetFactoryFunction();
|
|
||||||
|
|
||||||
void Update(uint8*) override;
|
static FactoryFunction GetFactoryFunction();
|
||||||
|
|
||||||
|
void Update(uint8*) override;
|
||||||
|
|
||||||
|
void SetButtonState(uint32, bool);
|
||||||
|
void SetAxisState(uint32, float);
|
||||||
|
|
||||||
void SetButtonState(uint32, bool);
|
|
||||||
void SetAxisState(uint32, float);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_buttonStates[PS2::CControllerInfo::MAX_BUTTONS];
|
bool m_buttonStates[PS2::CControllerInfo::MAX_BUTTONS];
|
||||||
float m_axisStates[PS2::CControllerInfo::MAX_BUTTONS];
|
float m_axisStates[PS2::CControllerInfo::MAX_BUTTONS];
|
||||||
};
|
};
|
||||||
|
|
144
Source/PS2VM.cpp
144
Source/PS2VM.cpp
|
@ -28,43 +28,43 @@
|
||||||
#include "ISO9660/BlockProvider.h"
|
#include "ISO9660/BlockProvider.h"
|
||||||
#include "DiskUtils.h"
|
#include "DiskUtils.h"
|
||||||
|
|
||||||
#define LOG_NAME ("ps2vm")
|
#define LOG_NAME ("ps2vm")
|
||||||
|
|
||||||
#define PREF_PS2_HOST_DIRECTORY_DEFAULT ("vfs/host")
|
#define PREF_PS2_HOST_DIRECTORY_DEFAULT ("vfs/host")
|
||||||
#define PREF_PS2_MC0_DIRECTORY_DEFAULT ("vfs/mc0")
|
#define PREF_PS2_MC0_DIRECTORY_DEFAULT ("vfs/mc0")
|
||||||
#define PREF_PS2_MC1_DIRECTORY_DEFAULT ("vfs/mc1")
|
#define PREF_PS2_MC1_DIRECTORY_DEFAULT ("vfs/mc1")
|
||||||
|
|
||||||
#define FRAME_TICKS (PS2::EE_CLOCK_FREQ / 60)
|
#define FRAME_TICKS (PS2::EE_CLOCK_FREQ / 60)
|
||||||
#define ONSCREEN_TICKS (FRAME_TICKS * 9 / 10)
|
#define ONSCREEN_TICKS (FRAME_TICKS * 9 / 10)
|
||||||
#define VBLANK_TICKS (FRAME_TICKS / 10)
|
#define VBLANK_TICKS (FRAME_TICKS / 10)
|
||||||
|
|
||||||
namespace filesystem = boost::filesystem;
|
namespace filesystem = boost::filesystem;
|
||||||
|
|
||||||
CPS2VM::CPS2VM()
|
CPS2VM::CPS2VM()
|
||||||
: m_nStatus(PAUSED)
|
: m_nStatus(PAUSED)
|
||||||
, m_nEnd(false)
|
, m_nEnd(false)
|
||||||
, m_pad(NULL)
|
, m_pad(NULL)
|
||||||
, m_singleStepEe(false)
|
, m_singleStepEe(false)
|
||||||
, m_singleStepIop(false)
|
, m_singleStepIop(false)
|
||||||
, m_singleStepVu0(false)
|
, m_singleStepVu0(false)
|
||||||
, m_singleStepVu1(false)
|
, m_singleStepVu1(false)
|
||||||
, m_vblankTicks(0)
|
, m_vblankTicks(0)
|
||||||
, m_inVblank(false)
|
, m_inVblank(false)
|
||||||
, m_eeExecutionTicks(0)
|
, m_eeExecutionTicks(0)
|
||||||
, m_iopExecutionTicks(0)
|
, m_iopExecutionTicks(0)
|
||||||
, m_spuUpdateTicks(SPU_UPDATE_TICKS)
|
, m_spuUpdateTicks(SPU_UPDATE_TICKS)
|
||||||
, m_eeProfilerZone(CProfiler::GetInstance().RegisterZone("EE"))
|
, m_eeProfilerZone(CProfiler::GetInstance().RegisterZone("EE"))
|
||||||
, m_iopProfilerZone(CProfiler::GetInstance().RegisterZone("IOP"))
|
, m_iopProfilerZone(CProfiler::GetInstance().RegisterZone("IOP"))
|
||||||
, m_spuProfilerZone(CProfiler::GetInstance().RegisterZone("SPU"))
|
, m_spuProfilerZone(CProfiler::GetInstance().RegisterZone("SPU"))
|
||||||
, m_gsSyncProfilerZone(CProfiler::GetInstance().RegisterZone("GSSYNC"))
|
, m_gsSyncProfilerZone(CProfiler::GetInstance().RegisterZone("GSSYNC"))
|
||||||
, m_otherProfilerZone(CProfiler::GetInstance().RegisterZone("OTHER"))
|
, m_otherProfilerZone(CProfiler::GetInstance().RegisterZone("OTHER"))
|
||||||
{
|
{
|
||||||
static const std::pair<const char*, const char*> basicDirectorySettings[] =
|
static const std::pair<const char*, const char*> basicDirectorySettings[] =
|
||||||
{
|
{
|
||||||
std::make_pair(PREF_PS2_HOST_DIRECTORY, PREF_PS2_HOST_DIRECTORY_DEFAULT),
|
std::make_pair(PREF_PS2_HOST_DIRECTORY, PREF_PS2_HOST_DIRECTORY_DEFAULT),
|
||||||
std::make_pair(PREF_PS2_MC0_DIRECTORY, PREF_PS2_MC0_DIRECTORY_DEFAULT),
|
std::make_pair(PREF_PS2_MC0_DIRECTORY, PREF_PS2_MC0_DIRECTORY_DEFAULT),
|
||||||
std::make_pair(PREF_PS2_MC1_DIRECTORY, PREF_PS2_MC1_DIRECTORY_DEFAULT),
|
std::make_pair(PREF_PS2_MC1_DIRECTORY, PREF_PS2_MC1_DIRECTORY_DEFAULT),
|
||||||
};
|
};
|
||||||
|
|
||||||
for(const auto& basicDirectorySetting : basicDirectorySettings)
|
for(const auto& basicDirectorySetting : basicDirectorySettings)
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ CPS2VM::CPS2VM()
|
||||||
Framework::PathUtils::EnsurePathExists(absolutePath);
|
Framework::PathUtils::EnsurePathExists(absolutePath);
|
||||||
CAppConfig::GetInstance().RegisterPreferencePath(setting, absolutePath);
|
CAppConfig::GetInstance().RegisterPreferencePath(setting, absolutePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAppConfig::GetInstance().RegisterPreferencePath(PREF_PS2_CDROM0_PATH, "");
|
CAppConfig::GetInstance().RegisterPreferencePath(PREF_PS2_CDROM0_PATH, "");
|
||||||
|
|
||||||
m_iop = std::make_unique<Iop::CSubSystem>(true);
|
m_iop = std::make_unique<Iop::CSubSystem>(true);
|
||||||
|
@ -101,7 +101,7 @@ CPS2VM::~CPS2VM()
|
||||||
void CPS2VM::CreateGSHandler(const CGSHandler::FactoryFunction& factoryFunction)
|
void CPS2VM::CreateGSHandler(const CGSHandler::FactoryFunction& factoryFunction)
|
||||||
{
|
{
|
||||||
if(m_ee->m_gs != nullptr) return;
|
if(m_ee->m_gs != nullptr) return;
|
||||||
m_mailBox.SendCall([this, factoryFunction] () { CreateGsHandlerImpl(factoryFunction); }, true);
|
m_mailBox.SendCall([this, factoryFunction]() { CreateGsHandlerImpl(factoryFunction); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGSHandler* CPS2VM::GetGSHandler()
|
CGSHandler* CPS2VM::GetGSHandler()
|
||||||
|
@ -112,13 +112,13 @@ CGSHandler* CPS2VM::GetGSHandler()
|
||||||
void CPS2VM::DestroyGSHandler()
|
void CPS2VM::DestroyGSHandler()
|
||||||
{
|
{
|
||||||
if(m_ee->m_gs == nullptr) return;
|
if(m_ee->m_gs == nullptr) return;
|
||||||
m_mailBox.SendCall([this] () { DestroyGsHandlerImpl(); }, true);
|
m_mailBox.SendCall([this]() { DestroyGsHandlerImpl(); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPS2VM::CreatePadHandler(const CPadHandler::FactoryFunction& factoryFunction)
|
void CPS2VM::CreatePadHandler(const CPadHandler::FactoryFunction& factoryFunction)
|
||||||
{
|
{
|
||||||
if(m_pad != nullptr) return;
|
if(m_pad != nullptr) return;
|
||||||
m_mailBox.SendCall([this, factoryFunction] () { CreatePadHandlerImpl(factoryFunction); }, true);
|
m_mailBox.SendCall([this, factoryFunction]() { CreatePadHandlerImpl(factoryFunction); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPadHandler* CPS2VM::GetPadHandler()
|
CPadHandler* CPS2VM::GetPadHandler()
|
||||||
|
@ -129,19 +129,19 @@ CPadHandler* CPS2VM::GetPadHandler()
|
||||||
void CPS2VM::DestroyPadHandler()
|
void CPS2VM::DestroyPadHandler()
|
||||||
{
|
{
|
||||||
if(m_pad == nullptr) return;
|
if(m_pad == nullptr) return;
|
||||||
m_mailBox.SendCall([this] () { DestroyPadHandlerImpl(); }, true);
|
m_mailBox.SendCall([this]() { DestroyPadHandlerImpl(); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPS2VM::CreateSoundHandler(const CSoundHandler::FactoryFunction& factoryFunction)
|
void CPS2VM::CreateSoundHandler(const CSoundHandler::FactoryFunction& factoryFunction)
|
||||||
{
|
{
|
||||||
if(m_soundHandler != nullptr) return;
|
if(m_soundHandler != nullptr) return;
|
||||||
m_mailBox.SendCall([this, factoryFunction] () { CreateSoundHandlerImpl(factoryFunction); }, true);
|
m_mailBox.SendCall([this, factoryFunction]() { CreateSoundHandlerImpl(factoryFunction); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPS2VM::DestroySoundHandler()
|
void CPS2VM::DestroySoundHandler()
|
||||||
{
|
{
|
||||||
if(m_soundHandler == nullptr) return;
|
if(m_soundHandler == nullptr) return;
|
||||||
m_mailBox.SendCall([this] () { DestroySoundHandlerImpl(); }, true);
|
m_mailBox.SendCall([this]() { DestroySoundHandlerImpl(); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CVirtualMachine::STATUS CPS2VM::GetStatus() const
|
CVirtualMachine::STATUS CPS2VM::GetStatus() const
|
||||||
|
@ -200,14 +200,14 @@ void CPS2VM::Reset()
|
||||||
|
|
||||||
void CPS2VM::DumpEEIntcHandlers()
|
void CPS2VM::DumpEEIntcHandlers()
|
||||||
{
|
{
|
||||||
// if(m_pOS == NULL) return;
|
// if(m_pOS == NULL) return;
|
||||||
if(m_nStatus != PAUSED) return;
|
if(m_nStatus != PAUSED) return;
|
||||||
m_ee->m_os->DumpIntcHandlers();
|
m_ee->m_os->DumpIntcHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPS2VM::DumpEEDmacHandlers()
|
void CPS2VM::DumpEEDmacHandlers()
|
||||||
{
|
{
|
||||||
// if(m_pOS == NULL) return;
|
// if(m_pOS == NULL) return;
|
||||||
if(m_nStatus != PAUSED) return;
|
if(m_nStatus != PAUSED) return;
|
||||||
m_ee->m_os->DumpDmacHandlers();
|
m_ee->m_os->DumpDmacHandlers();
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ void CPS2VM::Initialize()
|
||||||
{
|
{
|
||||||
CreateVM();
|
CreateVM();
|
||||||
m_nEnd = false;
|
m_nEnd = false;
|
||||||
m_thread = std::thread([&] () { EmuThread(); });
|
m_thread = std::thread([&]() { EmuThread(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPS2VM::Destroy()
|
void CPS2VM::Destroy()
|
||||||
|
@ -242,12 +242,10 @@ std::future<bool> CPS2VM::SaveState(const filesystem::path& statePath)
|
||||||
auto promise = std::make_shared<std::promise<bool>>();
|
auto promise = std::make_shared<std::promise<bool>>();
|
||||||
auto future = promise->get_future();
|
auto future = promise->get_future();
|
||||||
m_mailBox.SendCall(
|
m_mailBox.SendCall(
|
||||||
[this, promise, statePath] ()
|
[this, promise, statePath]() {
|
||||||
{
|
auto result = SaveVMState(statePath);
|
||||||
auto result = SaveVMState(statePath);
|
promise->set_value(result);
|
||||||
promise->set_value(result);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,26 +254,22 @@ std::future<bool> CPS2VM::LoadState(const filesystem::path& statePath)
|
||||||
auto promise = std::make_shared<std::promise<bool>>();
|
auto promise = std::make_shared<std::promise<bool>>();
|
||||||
auto future = promise->get_future();
|
auto future = promise->get_future();
|
||||||
m_mailBox.SendCall(
|
m_mailBox.SendCall(
|
||||||
[this, promise, statePath] ()
|
[this, promise, statePath]() {
|
||||||
{
|
auto result = LoadVMState(statePath);
|
||||||
auto result = LoadVMState(statePath);
|
promise->set_value(result);
|
||||||
promise->set_value(result);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPS2VM::TriggerFrameDump(const FrameDumpCallback& frameDumpCallback)
|
void CPS2VM::TriggerFrameDump(const FrameDumpCallback& frameDumpCallback)
|
||||||
{
|
{
|
||||||
m_mailBox.SendCall(
|
m_mailBox.SendCall(
|
||||||
[=] ()
|
[=]() {
|
||||||
{
|
std::unique_lock<std::mutex> frameDumpCallbackMutexLock(m_frameDumpCallbackMutex);
|
||||||
std::unique_lock<std::mutex> frameDumpCallbackMutexLock(m_frameDumpCallbackMutex);
|
if(m_frameDumpCallback) return;
|
||||||
if(m_frameDumpCallback) return;
|
m_frameDumpCallback = frameDumpCallback;
|
||||||
m_frameDumpCallback = frameDumpCallback;
|
},
|
||||||
},
|
false);
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPS2VM::CPU_UTILISATION_INFO CPS2VM::GetCpuUtilisationInfo() const
|
CPS2VM::CPU_UTILISATION_INFO CPS2VM::GetCpuUtilisationInfo() const
|
||||||
|
@ -285,16 +279,16 @@ CPS2VM::CPU_UTILISATION_INFO CPS2VM::GetCpuUtilisationInfo() const
|
||||||
|
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
|
|
||||||
#define TAGS_SECTION_TAGS ("tags")
|
#define TAGS_SECTION_TAGS ("tags")
|
||||||
#define TAGS_SECTION_EE_FUNCTIONS ("ee_functions")
|
#define TAGS_SECTION_EE_FUNCTIONS ("ee_functions")
|
||||||
#define TAGS_SECTION_EE_COMMENTS ("ee_comments")
|
#define TAGS_SECTION_EE_COMMENTS ("ee_comments")
|
||||||
#define TAGS_SECTION_VU1_FUNCTIONS ("vu1_functions")
|
#define TAGS_SECTION_VU1_FUNCTIONS ("vu1_functions")
|
||||||
#define TAGS_SECTION_VU1_COMMENTS ("vu1_comments")
|
#define TAGS_SECTION_VU1_COMMENTS ("vu1_comments")
|
||||||
#define TAGS_SECTION_IOP ("iop")
|
#define TAGS_SECTION_IOP ("iop")
|
||||||
#define TAGS_SECTION_IOP_FUNCTIONS ("functions")
|
#define TAGS_SECTION_IOP_FUNCTIONS ("functions")
|
||||||
#define TAGS_SECTION_IOP_COMMENTS ("comments")
|
#define TAGS_SECTION_IOP_COMMENTS ("comments")
|
||||||
|
|
||||||
#define TAGS_PATH ("tags/")
|
#define TAGS_PATH ("tags/")
|
||||||
|
|
||||||
std::string CPS2VM::MakeDebugTagsPackagePath(const char* packageName)
|
std::string CPS2VM::MakeDebugTagsPackagePath(const char* packageName)
|
||||||
{
|
{
|
||||||
|
@ -329,7 +323,6 @@ void CPS2VM::LoadDebugTags(const char* packageName)
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +332,7 @@ void CPS2VM::SaveDebugTags(const char* packageName)
|
||||||
{
|
{
|
||||||
std::string packagePath = MakeDebugTagsPackagePath(packageName);
|
std::string packagePath = MakeDebugTagsPackagePath(packageName);
|
||||||
Framework::CStdStream stream(packagePath.c_str(), "wb");
|
Framework::CStdStream stream(packagePath.c_str(), "wb");
|
||||||
boost::scoped_ptr<Framework::Xml::CNode> document(new Framework::Xml::CNode(TAGS_SECTION_TAGS, true));
|
boost::scoped_ptr<Framework::Xml::CNode> document(new Framework::Xml::CNode(TAGS_SECTION_TAGS, true));
|
||||||
m_ee->m_EE.m_Functions.Serialize(document.get(), TAGS_SECTION_EE_FUNCTIONS);
|
m_ee->m_EE.m_Functions.Serialize(document.get(), TAGS_SECTION_EE_FUNCTIONS);
|
||||||
m_ee->m_EE.m_Comments.Serialize(document.get(), TAGS_SECTION_EE_COMMENTS);
|
m_ee->m_EE.m_Comments.Serialize(document.get(), TAGS_SECTION_EE_COMMENTS);
|
||||||
m_ee->m_VU1.m_Functions.Serialize(document.get(), TAGS_SECTION_VU1_FUNCTIONS);
|
m_ee->m_VU1.m_Functions.Serialize(document.get(), TAGS_SECTION_VU1_FUNCTIONS);
|
||||||
|
@ -355,7 +348,6 @@ void CPS2VM::SaveDebugTags(const char* packageName)
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +444,7 @@ bool CPS2VM::LoadVMState(const filesystem::path& statePath)
|
||||||
{
|
{
|
||||||
auto stateStream = Framework::CreateInputStdStream(statePath.native());
|
auto stateStream = Framework::CreateInputStdStream(statePath.native());
|
||||||
Framework::CZipArchiveReader archive(stateStream);
|
Framework::CZipArchiveReader archive(stateStream);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_ee->LoadState(archive);
|
m_ee->LoadState(archive);
|
||||||
|
@ -800,10 +792,10 @@ void CPS2VM::EmuThread()
|
||||||
}
|
}
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
if(
|
if(
|
||||||
m_ee->m_executor.MustBreak() ||
|
m_ee->m_executor.MustBreak() ||
|
||||||
m_iop->m_executor.MustBreak() ||
|
m_iop->m_executor.MustBreak() ||
|
||||||
m_ee->m_vpu1->MustBreak() ||
|
m_ee->m_vpu1->MustBreak() ||
|
||||||
m_singleStepEe || m_singleStepIop || m_singleStepVu0 || m_singleStepVu1)
|
m_singleStepEe || m_singleStepIop || m_singleStepVu0 || m_singleStepVu1)
|
||||||
{
|
{
|
||||||
m_nStatus = PAUSED;
|
m_nStatus = PAUSED;
|
||||||
m_singleStepEe = false;
|
m_singleStepEe = false;
|
||||||
|
|
184
Source/PS2VM.h
184
Source/PS2VM.h
|
@ -31,146 +31,146 @@ public:
|
||||||
|
|
||||||
typedef std::unique_ptr<Ee::CSubSystem> EeSubSystemPtr;
|
typedef std::unique_ptr<Ee::CSubSystem> EeSubSystemPtr;
|
||||||
typedef std::unique_ptr<Iop::CSubSystem> IopSubSystemPtr;
|
typedef std::unique_ptr<Iop::CSubSystem> IopSubSystemPtr;
|
||||||
typedef std::function<void (const CFrameDump&)> FrameDumpCallback;
|
typedef std::function<void(const CFrameDump&)> FrameDumpCallback;
|
||||||
typedef boost::signals2::signal<void (const CProfiler::ZoneArray&)> ProfileFrameDoneSignal;
|
typedef boost::signals2::signal<void(const CProfiler::ZoneArray&)> ProfileFrameDoneSignal;
|
||||||
|
|
||||||
CPS2VM();
|
CPS2VM();
|
||||||
virtual ~CPS2VM();
|
virtual ~CPS2VM();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void StepEe();
|
void StepEe();
|
||||||
void StepIop();
|
void StepIop();
|
||||||
void StepVu0();
|
void StepVu0();
|
||||||
void StepVu1();
|
void StepVu1();
|
||||||
|
|
||||||
void Resume() override;
|
void Resume() override;
|
||||||
void Pause() override;
|
void Pause() override;
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
STATUS GetStatus() const override;
|
STATUS GetStatus() const override;
|
||||||
|
|
||||||
void DumpEEIntcHandlers();
|
void DumpEEIntcHandlers();
|
||||||
void DumpEEDmacHandlers();
|
void DumpEEDmacHandlers();
|
||||||
|
|
||||||
void CreateGSHandler(const CGSHandler::FactoryFunction&);
|
void CreateGSHandler(const CGSHandler::FactoryFunction&);
|
||||||
CGSHandler* GetGSHandler();
|
CGSHandler* GetGSHandler();
|
||||||
void DestroyGSHandler();
|
void DestroyGSHandler();
|
||||||
|
|
||||||
void CreatePadHandler(const CPadHandler::FactoryFunction&);
|
void CreatePadHandler(const CPadHandler::FactoryFunction&);
|
||||||
CPadHandler* GetPadHandler();
|
CPadHandler* GetPadHandler();
|
||||||
void DestroyPadHandler();
|
void DestroyPadHandler();
|
||||||
|
|
||||||
void CreateSoundHandler(const CSoundHandler::FactoryFunction&);
|
void CreateSoundHandler(const CSoundHandler::FactoryFunction&);
|
||||||
void DestroySoundHandler();
|
void DestroySoundHandler();
|
||||||
|
|
||||||
static boost::filesystem::path GetStateDirectoryPath();
|
static boost::filesystem::path GetStateDirectoryPath();
|
||||||
boost::filesystem::path GenerateStatePath(unsigned int) const;
|
boost::filesystem::path GenerateStatePath(unsigned int) const;
|
||||||
|
|
||||||
std::future<bool> SaveState(const boost::filesystem::path&);
|
std::future<bool> SaveState(const boost::filesystem::path&);
|
||||||
std::future<bool> LoadState(const boost::filesystem::path&);
|
std::future<bool> LoadState(const boost::filesystem::path&);
|
||||||
|
|
||||||
void TriggerFrameDump(const FrameDumpCallback&);
|
void TriggerFrameDump(const FrameDumpCallback&);
|
||||||
|
|
||||||
CPU_UTILISATION_INFO GetCpuUtilisationInfo() const;
|
CPU_UTILISATION_INFO GetCpuUtilisationInfo() const;
|
||||||
|
|
||||||
#ifdef DEBUGGER_INCLUDED
|
#ifdef DEBUGGER_INCLUDED
|
||||||
std::string MakeDebugTagsPackagePath(const char*);
|
std::string MakeDebugTagsPackagePath(const char*);
|
||||||
void LoadDebugTags(const char*);
|
void LoadDebugTags(const char*);
|
||||||
void SaveDebugTags(const char*);
|
void SaveDebugTags(const char*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CPadHandler* m_pad;
|
CPadHandler* m_pad;
|
||||||
|
|
||||||
EeSubSystemPtr m_ee;
|
EeSubSystemPtr m_ee;
|
||||||
IopSubSystemPtr m_iop;
|
IopSubSystemPtr m_iop;
|
||||||
|
|
||||||
IopBiosPtr m_iopOs;
|
IopBiosPtr m_iopOs;
|
||||||
|
|
||||||
ProfileFrameDoneSignal ProfileFrameDone;
|
ProfileFrameDoneSignal ProfileFrameDone;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::unique_ptr<COpticalMedia> OpticalMediaPtr;
|
typedef std::unique_ptr<COpticalMedia> OpticalMediaPtr;
|
||||||
|
|
||||||
void CreateVM();
|
void CreateVM();
|
||||||
void ResetVM();
|
void ResetVM();
|
||||||
void DestroyVM();
|
void DestroyVM();
|
||||||
bool SaveVMState(const boost::filesystem::path&);
|
bool SaveVMState(const boost::filesystem::path&);
|
||||||
bool LoadVMState(const boost::filesystem::path&);
|
bool LoadVMState(const boost::filesystem::path&);
|
||||||
|
|
||||||
void ReloadExecutable(const char*, const CPS2OS::ArgumentList&);
|
void ReloadExecutable(const char*, const CPS2OS::ArgumentList&);
|
||||||
|
|
||||||
void ResumeImpl();
|
void ResumeImpl();
|
||||||
void PauseImpl();
|
void PauseImpl();
|
||||||
void DestroyImpl();
|
void DestroyImpl();
|
||||||
|
|
||||||
void CreateGsHandlerImpl(const CGSHandler::FactoryFunction&);
|
|
||||||
void DestroyGsHandlerImpl();
|
|
||||||
|
|
||||||
void CreatePadHandlerImpl(const CPadHandler::FactoryFunction&);
|
void CreateGsHandlerImpl(const CGSHandler::FactoryFunction&);
|
||||||
void DestroyPadHandlerImpl();
|
void DestroyGsHandlerImpl();
|
||||||
|
|
||||||
void CreateSoundHandlerImpl(const CSoundHandler::FactoryFunction&);
|
|
||||||
void DestroySoundHandlerImpl();
|
|
||||||
|
|
||||||
void UpdateEe();
|
void CreatePadHandlerImpl(const CPadHandler::FactoryFunction&);
|
||||||
void UpdateIop();
|
void DestroyPadHandlerImpl();
|
||||||
void UpdateSpu();
|
|
||||||
|
|
||||||
void OnGsNewFrame();
|
void CreateSoundHandlerImpl(const CSoundHandler::FactoryFunction&);
|
||||||
|
void DestroySoundHandlerImpl();
|
||||||
|
|
||||||
void CDROM0_SyncPath();
|
void UpdateEe();
|
||||||
void CDROM0_Reset();
|
void UpdateIop();
|
||||||
void SetIopOpticalMedia(COpticalMedia*);
|
void UpdateSpu();
|
||||||
|
|
||||||
void RegisterModulesInPadHandler();
|
void OnGsNewFrame();
|
||||||
|
|
||||||
void EmuThread();
|
void CDROM0_SyncPath();
|
||||||
|
void CDROM0_Reset();
|
||||||
|
void SetIopOpticalMedia(COpticalMedia*);
|
||||||
|
|
||||||
std::thread m_thread;
|
void RegisterModulesInPadHandler();
|
||||||
CMailBox m_mailBox;
|
|
||||||
STATUS m_nStatus;
|
|
||||||
bool m_nEnd;
|
|
||||||
|
|
||||||
int m_vblankTicks = 0;
|
void EmuThread();
|
||||||
bool m_inVblank = 0;
|
|
||||||
int m_spuUpdateTicks = 0;
|
|
||||||
int m_eeExecutionTicks = 0;
|
|
||||||
int m_iopExecutionTicks = 0;
|
|
||||||
|
|
||||||
CPU_UTILISATION_INFO m_cpuUtilisation;
|
std::thread m_thread;
|
||||||
|
CMailBox m_mailBox;
|
||||||
|
STATUS m_nStatus;
|
||||||
|
bool m_nEnd;
|
||||||
|
|
||||||
bool m_singleStepEe;
|
int m_vblankTicks = 0;
|
||||||
bool m_singleStepIop;
|
bool m_inVblank = 0;
|
||||||
bool m_singleStepVu0;
|
int m_spuUpdateTicks = 0;
|
||||||
bool m_singleStepVu1;
|
int m_eeExecutionTicks = 0;
|
||||||
|
int m_iopExecutionTicks = 0;
|
||||||
|
|
||||||
CFrameDump m_frameDump;
|
CPU_UTILISATION_INFO m_cpuUtilisation;
|
||||||
FrameDumpCallback m_frameDumpCallback;
|
|
||||||
std::mutex m_frameDumpCallbackMutex;
|
|
||||||
bool m_dumpingFrame = false;
|
|
||||||
|
|
||||||
OpticalMediaPtr m_cdrom0;
|
bool m_singleStepEe;
|
||||||
|
bool m_singleStepIop;
|
||||||
|
bool m_singleStepVu0;
|
||||||
|
bool m_singleStepVu1;
|
||||||
|
|
||||||
|
CFrameDump m_frameDump;
|
||||||
|
FrameDumpCallback m_frameDumpCallback;
|
||||||
|
std::mutex m_frameDumpCallbackMutex;
|
||||||
|
bool m_dumpingFrame = false;
|
||||||
|
|
||||||
|
OpticalMediaPtr m_cdrom0;
|
||||||
|
|
||||||
//SPU update parameters
|
//SPU update parameters
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DST_SAMPLE_RATE = 44100,
|
DST_SAMPLE_RATE = 44100,
|
||||||
UPDATE_RATE = 1000, //Number of SPU updates per second (on PS2 time scale)
|
UPDATE_RATE = 1000, //Number of SPU updates per second (on PS2 time scale)
|
||||||
SPU_UPDATE_TICKS = PS2::IOP_CLOCK_OVER_FREQ / UPDATE_RATE,
|
SPU_UPDATE_TICKS = PS2::IOP_CLOCK_OVER_FREQ / UPDATE_RATE,
|
||||||
SAMPLE_COUNT = DST_SAMPLE_RATE / UPDATE_RATE,
|
SAMPLE_COUNT = DST_SAMPLE_RATE / UPDATE_RATE,
|
||||||
BLOCK_SIZE = SAMPLE_COUNT * 2,
|
BLOCK_SIZE = SAMPLE_COUNT * 2,
|
||||||
BLOCK_COUNT = 400,
|
BLOCK_COUNT = 400,
|
||||||
};
|
};
|
||||||
|
|
||||||
int16 m_samples[BLOCK_SIZE * BLOCK_COUNT];
|
int16 m_samples[BLOCK_SIZE * BLOCK_COUNT];
|
||||||
int m_currentSpuBlock = 0;
|
int m_currentSpuBlock = 0;
|
||||||
CSoundHandler* m_soundHandler = nullptr;
|
CSoundHandler* m_soundHandler = nullptr;
|
||||||
|
|
||||||
CProfiler::ZoneHandle m_eeProfilerZone = 0;
|
CProfiler::ZoneHandle m_eeProfilerZone = 0;
|
||||||
CProfiler::ZoneHandle m_iopProfilerZone = 0;
|
CProfiler::ZoneHandle m_iopProfilerZone = 0;
|
||||||
CProfiler::ZoneHandle m_spuProfilerZone = 0;
|
CProfiler::ZoneHandle m_spuProfilerZone = 0;
|
||||||
CProfiler::ZoneHandle m_gsSyncProfilerZone = 0;
|
CProfiler::ZoneHandle m_gsSyncProfilerZone = 0;
|
||||||
CProfiler::ZoneHandle m_otherProfilerZone = 0;
|
CProfiler::ZoneHandle m_otherProfilerZone = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define PREF_PS2_CDROM0_PATH ("ps2.cdrom0.path.v2")
|
#define PREF_PS2_CDROM0_PATH ("ps2.cdrom0.path.v2")
|
||||||
|
|
||||||
#define PREF_PS2_HOST_DIRECTORY ("ps2.host.directory.v2")
|
#define PREF_PS2_HOST_DIRECTORY ("ps2.host.directory.v2")
|
||||||
#define PREF_PS2_MC0_DIRECTORY ("ps2.mc0.directory.v2")
|
#define PREF_PS2_MC0_DIRECTORY ("ps2.mc0.directory.v2")
|
||||||
#define PREF_PS2_MC1_DIRECTORY ("ps2.mc1.directory.v2")
|
#define PREF_PS2_MC1_DIRECTORY ("ps2.mc1.directory.v2")
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
|
|
||||||
CPadHandler::CPadHandler()
|
CPadHandler::CPadHandler()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPadHandler::~CPadHandler()
|
CPadHandler::~CPadHandler()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPadHandler::InsertListener(CPadListener* pListener)
|
void CPadHandler::InsertListener(CPadListener* pListener)
|
||||||
|
@ -17,5 +15,5 @@ void CPadHandler::InsertListener(CPadListener* pListener)
|
||||||
|
|
||||||
void CPadHandler::RemoveAllListeners()
|
void CPadHandler::RemoveAllListeners()
|
||||||
{
|
{
|
||||||
m_listeners.clear();
|
m_listeners.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
class CPadHandler
|
class CPadHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<CPadHandler* (void)> FactoryFunction;
|
typedef std::function<CPadHandler*(void)> FactoryFunction;
|
||||||
|
|
||||||
CPadHandler();
|
CPadHandler();
|
||||||
virtual ~CPadHandler();
|
virtual ~CPadHandler();
|
||||||
virtual void Update(uint8*) = 0;
|
virtual void Update(uint8*) = 0;
|
||||||
void InsertListener(CPadListener*);
|
void InsertListener(CPadListener*);
|
||||||
void RemoveAllListeners();
|
void RemoveAllListeners();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::list<CPadListener*> ListenerList;
|
typedef std::list<CPadListener*> ListenerList;
|
||||||
ListenerList m_listeners;
|
ListenerList m_listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,28 +6,28 @@ using namespace PS2;
|
||||||
uint32 CPadListener::GetButtonMask(CControllerInfo::BUTTON button)
|
uint32 CPadListener::GetButtonMask(CControllerInfo::BUTTON button)
|
||||||
{
|
{
|
||||||
static uint32 buttonMask[CControllerInfo::MAX_BUTTONS] =
|
static uint32 buttonMask[CControllerInfo::MAX_BUTTONS] =
|
||||||
{
|
{
|
||||||
static_cast<uint32>(-1),
|
static_cast<uint32>(-1),
|
||||||
static_cast<uint32>(-1),
|
static_cast<uint32>(-1),
|
||||||
static_cast<uint32>(-1),
|
static_cast<uint32>(-1),
|
||||||
static_cast<uint32>(-1),
|
static_cast<uint32>(-1),
|
||||||
0x1000,
|
0x1000,
|
||||||
0x4000,
|
0x4000,
|
||||||
0x8000,
|
0x8000,
|
||||||
0x2000,
|
0x2000,
|
||||||
0x0100,
|
0x0100,
|
||||||
0x0800,
|
0x0800,
|
||||||
0x0080,
|
0x0080,
|
||||||
0x0010,
|
0x0010,
|
||||||
0x0020,
|
0x0020,
|
||||||
0x0040,
|
0x0040,
|
||||||
0x0004, //L1
|
0x0004, //L1
|
||||||
0x0001, //L2
|
0x0001, //L2
|
||||||
0x0200, //L3
|
0x0200, //L3
|
||||||
0x0008, //R1
|
0x0008, //R1
|
||||||
0x0002, //R2
|
0x0002, //R2
|
||||||
0x0400, //R3
|
0x0400, //R3
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 result = buttonMask[button];
|
uint32 result = buttonMask[button];
|
||||||
assert(result != -1);
|
assert(result != -1);
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
class CPadListener
|
class CPadListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~CPadListener() {}
|
virtual ~CPadListener()
|
||||||
virtual void SetButtonState(unsigned int, PS2::CControllerInfo::BUTTON, bool, uint8*) = 0;
|
{
|
||||||
virtual void SetAxisState(unsigned int, PS2::CControllerInfo::BUTTON, uint8, uint8*) = 0;
|
}
|
||||||
static uint32 GetButtonMask(PS2::CControllerInfo::BUTTON);
|
virtual void SetButtonState(unsigned int, PS2::CControllerInfo::BUTTON, bool, uint8*) = 0;
|
||||||
|
virtual void SetAxisState(unsigned int, PS2::CControllerInfo::BUTTON, uint8, uint8*) = 0;
|
||||||
|
static uint32 GetButtonMask(PS2::CControllerInfo::BUTTON);
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "Posix_VolumeStream.h"
|
#include "Posix_VolumeStream.h"
|
||||||
|
|
||||||
using namespace Framework::Posix;
|
using namespace Framework::Posix;
|
||||||
|
@ -21,7 +20,7 @@ using namespace Framework::Posix;
|
||||||
CVolumeStream::CVolumeStream(const char* volumePath)
|
CVolumeStream::CVolumeStream(const char* volumePath)
|
||||||
{
|
{
|
||||||
m_fd = open(volumePath, O_RDONLY);
|
m_fd = open(volumePath, O_RDONLY);
|
||||||
if(m_fd < 0)
|
if(m_fd < 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Couldn't open volume for reading.");
|
throw std::runtime_error("Couldn't open volume for reading.");
|
||||||
}
|
}
|
||||||
|
@ -76,21 +75,21 @@ uint64 CVolumeStream::Read(void* buffer, uint64 size)
|
||||||
uint64 retSize = size;
|
uint64 retSize = size;
|
||||||
uint8* dst = reinterpret_cast<uint8*>(buffer);
|
uint8* dst = reinterpret_cast<uint8*>(buffer);
|
||||||
uint8* src = reinterpret_cast<uint8*>(m_cache);
|
uint8* src = reinterpret_cast<uint8*>(m_cache);
|
||||||
|
|
||||||
while(size != 0)
|
while(size != 0)
|
||||||
{
|
{
|
||||||
SyncCache();
|
SyncCache();
|
||||||
|
|
||||||
size_t sectorOffset = static_cast<size_t>(m_position & (m_sectorSize - 1));
|
size_t sectorOffset = static_cast<size_t>(m_position & (m_sectorSize - 1));
|
||||||
size_t sectorRemain = static_cast<size_t>(m_sectorSize - sectorOffset);
|
size_t sectorRemain = static_cast<size_t>(m_sectorSize - sectorOffset);
|
||||||
size_t copy = std::min<size_t>(size, sectorRemain);
|
size_t copy = std::min<size_t>(size, sectorRemain);
|
||||||
|
|
||||||
memcpy(dst, src + sectorOffset, copy);
|
memcpy(dst, src + sectorOffset, copy);
|
||||||
m_position += copy;
|
m_position += copy;
|
||||||
size -= copy;
|
size -= copy;
|
||||||
dst += copy;
|
dst += copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retSize;
|
return retSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,24 +10,24 @@ namespace Framework
|
||||||
class CVolumeStream : public CStream
|
class CVolumeStream : public CStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CVolumeStream(const char*);
|
CVolumeStream(const char*);
|
||||||
virtual ~CVolumeStream();
|
virtual ~CVolumeStream();
|
||||||
|
|
||||||
virtual void Seek(int64, STREAM_SEEK_DIRECTION);
|
virtual void Seek(int64, STREAM_SEEK_DIRECTION);
|
||||||
virtual uint64 Tell();
|
virtual uint64 Tell();
|
||||||
virtual uint64 Read(void*, uint64);
|
virtual uint64 Read(void*, uint64);
|
||||||
virtual uint64 Write(const void*, uint64);
|
virtual uint64 Write(const void*, uint64);
|
||||||
virtual bool IsEOF();
|
virtual bool IsEOF();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SyncCache();
|
void SyncCache();
|
||||||
|
|
||||||
int m_fd;
|
int m_fd;
|
||||||
void* m_cache;
|
void* m_cache;
|
||||||
uint64 m_cacheSector;
|
uint64 m_cacheSector;
|
||||||
|
|
||||||
uint64 m_position;
|
uint64 m_position;
|
||||||
uint32 m_sectorSize;
|
uint32 m_sectorSize;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,10 @@
|
||||||
|
|
||||||
CProfiler::CProfiler()
|
CProfiler::CProfiler()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CProfiler::~CProfiler()
|
CProfiler::~CProfiler()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CProfiler::ZoneHandle CProfiler::RegisterZone(const char* name)
|
CProfiler::ZoneHandle CProfiler::RegisterZone(const char* name)
|
||||||
|
@ -49,7 +47,7 @@ void CProfiler::CountCurrentZone()
|
||||||
void CProfiler::EnterZone(ZoneHandle zoneHandle)
|
void CProfiler::EnterZone(ZoneHandle zoneHandle)
|
||||||
{
|
{
|
||||||
assert(std::this_thread::get_id() == m_workThreadId);
|
assert(std::this_thread::get_id() == m_workThreadId);
|
||||||
|
|
||||||
auto thisTime = std::chrono::high_resolution_clock::now();
|
auto thisTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
if(!m_zoneStack.empty())
|
if(!m_zoneStack.empty())
|
||||||
|
|
|
@ -15,45 +15,45 @@ public:
|
||||||
|
|
||||||
struct ZONE
|
struct ZONE
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
uint64 totalTime = 0;
|
uint64 totalTime = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ZONE> ZoneArray;
|
typedef std::vector<ZONE> ZoneArray;
|
||||||
typedef std::chrono::high_resolution_clock::time_point TimePoint;
|
typedef std::chrono::high_resolution_clock::time_point TimePoint;
|
||||||
|
|
||||||
CProfiler();
|
CProfiler();
|
||||||
virtual ~CProfiler();
|
virtual ~CProfiler();
|
||||||
|
|
||||||
ZoneHandle RegisterZone(const char*);
|
ZoneHandle RegisterZone(const char*);
|
||||||
|
|
||||||
void CountCurrentZone();
|
void CountCurrentZone();
|
||||||
|
|
||||||
void EnterZone(ZoneHandle);
|
void EnterZone(ZoneHandle);
|
||||||
void ExitZone();
|
void ExitZone();
|
||||||
|
|
||||||
ZoneArray GetStats() const;
|
ZoneArray GetStats() const;
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
void SetWorkThread();
|
||||||
|
|
||||||
void SetWorkThread();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::stack<ZoneHandle> ZoneStack;
|
typedef std::stack<ZoneHandle> ZoneStack;
|
||||||
|
|
||||||
void AddTimeToZone(ZoneHandle, uint64);
|
|
||||||
|
|
||||||
ZoneArray m_zones;
|
void AddTimeToZone(ZoneHandle, uint64);
|
||||||
ZoneStack m_zoneStack;
|
|
||||||
TimePoint m_currentTime;
|
ZoneArray m_zones;
|
||||||
|
ZoneStack m_zoneStack;
|
||||||
|
TimePoint m_currentTime;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
std::thread::id m_workThreadId;
|
std::thread::id m_workThreadId;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class CProfilerZone
|
class CProfilerZone
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CProfilerZone(CProfiler::ZoneHandle);
|
CProfilerZone(CProfiler::ZoneHandle);
|
||||||
~CProfilerZone();
|
~CProfilerZone();
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace PS2
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
IOP_CLOCK_BASE_FREQ = (44100 * 256 * 3),
|
IOP_CLOCK_BASE_FREQ = (44100 * 256 * 3),
|
||||||
IOP_CLOCK_OVER_FREQ = (48000 * 256 * 3)
|
IOP_CLOCK_OVER_FREQ = (48000 * 256 * 3)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -7,20 +7,18 @@
|
||||||
#include "lexical_cast_ex.h"
|
#include "lexical_cast_ex.h"
|
||||||
|
|
||||||
CRegisterStateFile::CRegisterStateFile(const char* name)
|
CRegisterStateFile::CRegisterStateFile(const char* name)
|
||||||
: CZipFile(name)
|
: CZipFile(name)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CRegisterStateFile::CRegisterStateFile(Framework::CStream& stream)
|
CRegisterStateFile::CRegisterStateFile(Framework::CStream& stream)
|
||||||
: CZipFile("")
|
: CZipFile("")
|
||||||
{
|
{
|
||||||
Read(stream);
|
Read(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRegisterStateFile::~CRegisterStateFile()
|
CRegisterStateFile::~CRegisterStateFile()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRegisterStateFile::Read(Framework::CStream& stream)
|
void CRegisterStateFile::Read(Framework::CStream& stream)
|
||||||
|
@ -29,7 +27,7 @@ void CRegisterStateFile::Read(Framework::CStream& stream)
|
||||||
auto rootNode = std::unique_ptr<Framework::Xml::CNode>(Framework::Xml::CParser::ParseDocument(stream));
|
auto rootNode = std::unique_ptr<Framework::Xml::CNode>(Framework::Xml::CParser::ParseDocument(stream));
|
||||||
auto registerList = rootNode->SelectNodes("RegisterFile/Register");
|
auto registerList = rootNode->SelectNodes("RegisterFile/Register");
|
||||||
for(Framework::Xml::CNode::NodeIterator nodeIterator(registerList.begin());
|
for(Framework::Xml::CNode::NodeIterator nodeIterator(registerList.begin());
|
||||||
nodeIterator != registerList.end(); nodeIterator++)
|
nodeIterator != registerList.end(); nodeIterator++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -52,7 +50,6 @@ void CRegisterStateFile::Read(Framework::CStream& stream)
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +58,7 @@ void CRegisterStateFile::Write(Framework::CStream& stream)
|
||||||
{
|
{
|
||||||
auto rootNode = new Framework::Xml::CNode("RegisterFile", true);
|
auto rootNode = new Framework::Xml::CNode("RegisterFile", true);
|
||||||
for(auto registerIterator(m_registers.begin());
|
for(auto registerIterator(m_registers.begin());
|
||||||
registerIterator != m_registers.end(); registerIterator++)
|
registerIterator != m_registers.end(); registerIterator++)
|
||||||
{
|
{
|
||||||
const Register& reg(registerIterator->second);
|
const Register& reg(registerIterator->second);
|
||||||
auto registerNode = new Framework::Xml::CNode("Register", true);
|
auto registerNode = new Framework::Xml::CNode("Register", true);
|
||||||
|
|
|
@ -7,24 +7,24 @@
|
||||||
class CRegisterStateFile : public Framework::CZipFile
|
class CRegisterStateFile : public Framework::CZipFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRegisterStateFile(const char*);
|
CRegisterStateFile(const char*);
|
||||||
CRegisterStateFile(Framework::CStream&);
|
CRegisterStateFile(Framework::CStream&);
|
||||||
virtual ~CRegisterStateFile();
|
virtual ~CRegisterStateFile();
|
||||||
|
|
||||||
void SetRegister32(const char*, uint32);
|
void SetRegister32(const char*, uint32);
|
||||||
void SetRegister64(const char*, uint64);
|
void SetRegister64(const char*, uint64);
|
||||||
void SetRegister128(const char*, uint128);
|
void SetRegister128(const char*, uint128);
|
||||||
|
|
||||||
uint32 GetRegister32(const char*) const;
|
uint32 GetRegister32(const char*) const;
|
||||||
uint64 GetRegister64(const char*) const;
|
uint64 GetRegister64(const char*) const;
|
||||||
uint128 GetRegister128(const char*) const;
|
uint128 GetRegister128(const char*) const;
|
||||||
|
|
||||||
void Read(Framework::CStream&);
|
void Read(Framework::CStream&);
|
||||||
void Write(Framework::CStream&) override;
|
void Write(Framework::CStream&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::pair<uint8, uint128> Register;
|
typedef std::pair<uint8, uint128> Register;
|
||||||
typedef std::map<std::string, Register> RegisterList;
|
typedef std::map<std::string, Register> RegisterList;
|
||||||
|
|
||||||
RegisterList m_registers;
|
RegisterList m_registers;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "VirtualMachine.h"
|
#include "VirtualMachine.h"
|
||||||
|
|
||||||
CScopedVmPauser::CScopedVmPauser(CVirtualMachine& virtualMachine)
|
CScopedVmPauser::CScopedVmPauser(CVirtualMachine& virtualMachine)
|
||||||
: m_virtualMachine(virtualMachine)
|
: m_virtualMachine(virtualMachine)
|
||||||
{
|
{
|
||||||
if(m_virtualMachine.GetStatus() == CVirtualMachine::RUNNING)
|
if(m_virtualMachine.GetStatus() == CVirtualMachine::RUNNING)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,10 +5,10 @@ class CVirtualMachine;
|
||||||
class CScopedVmPauser
|
class CScopedVmPauser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CScopedVmPauser(CVirtualMachine&);
|
CScopedVmPauser(CVirtualMachine&);
|
||||||
virtual ~CScopedVmPauser();
|
virtual ~CScopedVmPauser();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CVirtualMachine& m_virtualMachine;
|
CVirtualMachine& m_virtualMachine;
|
||||||
bool m_paused = false;
|
bool m_paused = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,25 +13,23 @@
|
||||||
void CScreenShotUtils::TriggerGetScreenshot(CPS2VM* virtualMachine, Callback completionCallback)
|
void CScreenShotUtils::TriggerGetScreenshot(CPS2VM* virtualMachine, Callback completionCallback)
|
||||||
{
|
{
|
||||||
virtualMachine->m_ee->m_gs->OnFlipComplete.connect_extended(
|
virtualMachine->m_ee->m_gs->OnFlipComplete.connect_extended(
|
||||||
[=](const boost::signals2::connection &c)->void
|
[=](const boost::signals2::connection& c) -> void {
|
||||||
{
|
c.disconnect();
|
||||||
c.disconnect();
|
try
|
||||||
try
|
{
|
||||||
{
|
auto buffer = virtualMachine->m_ee->m_gs->GetScreenshot();
|
||||||
auto buffer = virtualMachine->m_ee->m_gs->GetScreenshot();
|
auto name = GenerateScreenShotPath(virtualMachine->m_ee->m_os->GetExecutableName());
|
||||||
auto name = GenerateScreenShotPath(virtualMachine->m_ee->m_os->GetExecutableName());
|
Framework::CStdStream outputStream(name.string().c_str(), "wb");
|
||||||
Framework::CStdStream outputStream(name.string().c_str(), "wb");
|
Framework::CBMP::WriteBitmap(buffer, outputStream);
|
||||||
Framework::CBMP::WriteBitmap(buffer, outputStream);
|
|
||||||
|
|
||||||
auto msgstr = string_format("Screenshot saved as '%s'.", name.filename().string().c_str());
|
auto msgstr = string_format("Screenshot saved as '%s'.", name.filename().string().c_str());
|
||||||
completionCallback(0, msgstr.c_str());
|
completionCallback(0, msgstr.c_str());
|
||||||
}
|
}
|
||||||
catch(const std::exception&)
|
catch(const std::exception&)
|
||||||
{
|
{
|
||||||
completionCallback(-1, "Error occured while trying to save screenshot.");
|
completionCallback(-1, "Error occured while trying to save screenshot.");
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Framework::CConfig::PathType CScreenShotUtils::GetScreenShotDirectoryPath()
|
Framework::CConfig::PathType CScreenShotUtils::GetScreenShotDirectoryPath()
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
class CScreenShotUtils : public Framework::CConfig
|
class CScreenShotUtils : public Framework::CConfig
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(int, const char*)> Callback;
|
typedef std::function<void(int, const char*)> Callback;
|
||||||
|
|
||||||
static void TriggerGetScreenshot(CPS2VM*, Callback);
|
static void TriggerGetScreenshot(CPS2VM*, Callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static CConfig::PathType GetScreenShotDirectoryPath();
|
static CConfig::PathType GetScreenShotDirectoryPath();
|
||||||
static CConfig::PathType GenerateScreenShotPath(const char* gameID);
|
static CConfig::PathType GenerateScreenShotPath(const char* gameID);
|
||||||
};
|
};
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue