mirror of
https://github.com/libretro/Play-.git
synced 2025-03-04 17:28:29 +00:00
git-svn-id: http://svn.purei.org/purei/trunk@167 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
d3f2ebe262
commit
175f74312a
@ -168,7 +168,12 @@ void CCacheBlock::InsertEpilog(CMIPS* pCtx, bool nDelayJump)
|
||||
|
||||
#else
|
||||
|
||||
//push 1
|
||||
#pragma message("TODO : Need to fix that for x64.")
|
||||
|
||||
//push ebp
|
||||
StreamWrite(1, 0x55);
|
||||
|
||||
//push 1
|
||||
StreamWrite(2, 0x6A, 0x01);
|
||||
|
||||
#endif
|
||||
@ -184,8 +189,8 @@ void CCacheBlock::InsertEpilog(CMIPS* pCtx, bool nDelayJump)
|
||||
|
||||
#else
|
||||
|
||||
//add esp, 4
|
||||
StreamWrite(3, 0x83, 0xC4, 0x04);
|
||||
//add esp, 8
|
||||
StreamWrite(3, 0x83, 0xC4, 0x08);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -44,14 +44,14 @@ CMIPS::~CMIPS()
|
||||
DELETEPTR(m_pAnalysis);
|
||||
}
|
||||
|
||||
void CMIPS::ToggleBreakpoint(uint32 nAddress)
|
||||
void CMIPS::ToggleBreakpoint(uint32 address)
|
||||
{
|
||||
if(m_Breakpoint.DoesKeyExist(nAddress))
|
||||
if(m_breakpoints.find(address) != m_breakpoints.end())
|
||||
{
|
||||
m_Breakpoint.Remove(nAddress);
|
||||
m_breakpoints.erase(address);
|
||||
return;
|
||||
}
|
||||
m_Breakpoint.Insert(NULL, nAddress);
|
||||
m_breakpoints.insert(address);
|
||||
}
|
||||
|
||||
void CMIPS::Step()
|
||||
@ -151,5 +151,5 @@ void CMIPS::InvalidateCache()
|
||||
|
||||
bool CMIPS::MustBreak()
|
||||
{
|
||||
return m_Breakpoint.DoesKeyExist(m_State.nPC);
|
||||
return m_breakpoints.find(m_State.nPC) != m_breakpoints.end();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "MIPSAnalysis.h"
|
||||
#include "MIPSTags.h"
|
||||
#include "uint128.h"
|
||||
#include <set>
|
||||
|
||||
struct MIPSSTATE
|
||||
{
|
||||
@ -57,7 +58,7 @@ __declspec(align(16))
|
||||
|
||||
#define MIPS_INVALID_PC (0x00000001)
|
||||
|
||||
typedef unsigned int (*TickFunction)(unsigned int);
|
||||
typedef unsigned int (*TickFunctionType)(unsigned int);
|
||||
typedef void (*SysCallHandlerType)();
|
||||
typedef uint32 (*AddressTranslator)(CMIPS*, uint32, uint32);
|
||||
|
||||
@ -87,7 +88,7 @@ public:
|
||||
CMIPSCoprocessor* m_pCOP[4];
|
||||
CMemoryMap* m_pMemoryMap;
|
||||
CExecMap* m_pExecMap;
|
||||
Framework::CList<void> m_Breakpoint;
|
||||
std::set<uint32> m_breakpoints;
|
||||
|
||||
CMIPSAnalysis* m_pAnalysis;
|
||||
CMIPSTags m_Comments;
|
||||
@ -95,7 +96,7 @@ public:
|
||||
|
||||
AddressTranslator m_pAddrTranslator;
|
||||
SysCallHandlerType m_pSysCallHandler;
|
||||
TickFunction m_pTickFunction;
|
||||
TickFunctionType m_pTickFunction;
|
||||
void* m_handlerParam;
|
||||
|
||||
enum REGISTER
|
||||
|
@ -14,6 +14,8 @@ public:
|
||||
|
||||
virtual ~CVirtualMachine() {};
|
||||
virtual STATUS GetStatus() const = 0;
|
||||
virtual void Pause() = 0;
|
||||
virtual void Resume() = 0;
|
||||
|
||||
boost::signal<void ()> m_OnMachineStateChange;
|
||||
boost::signal<void ()> m_OnRunningStateChange;
|
||||
|
@ -738,7 +738,7 @@ void CDisAsm::Paint(HDC hDC)
|
||||
nAddress = m_nAddress + (i * 4);
|
||||
|
||||
//Not thread safe...?
|
||||
if(m_pCtx->m_Breakpoint.DoesKeyExist(nAddress))
|
||||
if(m_pCtx->m_breakpoints.find(nAddress) != m_pCtx->m_breakpoints.end())
|
||||
{
|
||||
SetTextColor(hDC, RGB(0x00, 0x00, 0x00));
|
||||
|
||||
|
@ -2,18 +2,19 @@
|
||||
#include <string.h>
|
||||
#include <boost/bind.hpp>
|
||||
#include "RegViewGeneral.h"
|
||||
#include "../PS2VM.h"
|
||||
|
||||
using namespace Framework;
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
CRegViewGeneral::CRegViewGeneral(HWND hParent, RECT* pR, CMIPS* pC) :
|
||||
CRegViewPage(hParent, pR)
|
||||
CRegViewGeneral::CRegViewGeneral(HWND hParent, RECT* pR, CVirtualMachine& virtualMachine, CMIPS* pC) :
|
||||
CRegViewPage(hParent, pR),
|
||||
m_virtualMachine(virtualMachine)
|
||||
{
|
||||
m_pCtx = pC;
|
||||
|
||||
CPS2VM::m_OnMachineStateChange.connect(bind(&CRegViewGeneral::Update, this));
|
||||
CPS2VM::m_OnRunningStateChange.connect(bind(&CRegViewGeneral::Update, this));
|
||||
m_virtualMachine.m_OnMachineStateChange.connect(bind(&CRegViewGeneral::Update, this));
|
||||
m_virtualMachine.m_OnRunningStateChange.connect(bind(&CRegViewGeneral::Update, this));
|
||||
}
|
||||
|
||||
CRegViewGeneral::~CRegViewGeneral()
|
||||
@ -23,38 +24,38 @@ CRegViewGeneral::~CRegViewGeneral()
|
||||
|
||||
void CRegViewGeneral::Update()
|
||||
{
|
||||
CStrA sText;
|
||||
GetDisplayText(&sText);
|
||||
SetDisplayText(sText);
|
||||
SetDisplayText(GetDisplayText().c_str());
|
||||
CRegViewPage::Update();
|
||||
}
|
||||
|
||||
void CRegViewGeneral::GetDisplayText(CStrA* pText)
|
||||
string CRegViewGeneral::GetDisplayText()
|
||||
{
|
||||
char sTemp[256];
|
||||
MIPSSTATE* s;
|
||||
unsigned int i;
|
||||
string displayText;
|
||||
|
||||
s = &m_pCtx->m_State;
|
||||
|
||||
for(i = 0; i < 32; i++)
|
||||
for(unsigned int i = 0; i < 32; i++)
|
||||
{
|
||||
sprintf(sTemp, "%s : 0x%0.8X%0.8X%0.8X%0.8X\r\n", CMIPS::m_sGPRName[i], s->nGPR[i].nV[3], s->nGPR[i].nV[2], s->nGPR[i].nV[1], s->nGPR[i].nV[0]);
|
||||
(*pText) += sTemp;
|
||||
displayText += sTemp;
|
||||
}
|
||||
|
||||
sprintf(sTemp, "LO : 0x%0.8X%0.8X\r\n", s->nLO[1], s->nLO[0]);
|
||||
(*pText) += sTemp;
|
||||
displayText += sTemp;
|
||||
|
||||
sprintf(sTemp, "HI : 0x%0.8X%0.8X\r\n", s->nHI[1], s->nHI[0]);
|
||||
(*pText) += sTemp;
|
||||
displayText += sTemp;
|
||||
|
||||
sprintf(sTemp, "LO1: 0x%0.8X%0.8X\r\n", s->nLO1[1], s->nLO1[0]);
|
||||
(*pText) += sTemp;
|
||||
displayText += sTemp;
|
||||
|
||||
sprintf(sTemp, "HI1: 0x%0.8X%0.8X\r\n", s->nHI1[1], s->nHI1[0]);
|
||||
(*pText) += sTemp;
|
||||
displayText += sTemp;
|
||||
|
||||
sprintf(sTemp, "SA : 0x%0.8X\r\n", s->nSA);
|
||||
(*pText) += sTemp;
|
||||
displayText += sTemp;
|
||||
|
||||
return displayText;
|
||||
}
|
||||
|
@ -4,18 +4,21 @@
|
||||
#include <boost/signal.hpp>
|
||||
#include "RegViewPage.h"
|
||||
#include "../MIPS.h"
|
||||
#include "../VirtualMachine.h"
|
||||
#include <string>
|
||||
|
||||
class CRegViewGeneral : public CRegViewPage, public boost::signals::trackable
|
||||
{
|
||||
public:
|
||||
CRegViewGeneral(HWND, RECT*, CMIPS*);
|
||||
CRegViewGeneral(HWND, RECT*, CVirtualMachine&, CMIPS*);
|
||||
virtual ~CRegViewGeneral();
|
||||
|
||||
private:
|
||||
void Update();
|
||||
void GetDisplayText(Framework::CStrA*);
|
||||
std::string GetDisplayText();
|
||||
|
||||
CMIPS* m_pCtx;
|
||||
CVirtualMachine& m_virtualMachine;
|
||||
CMIPS* m_pCtx;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -195,6 +195,14 @@
|
||||
RelativePath=".\Source\PsfVm.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Source\win32ui\RegViewGeneral.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Source\win32ui\RegViewPage.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\win32\WinMain.cpp"
|
||||
>
|
||||
@ -229,6 +237,14 @@
|
||||
RelativePath=".\Source\PsfVm.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Source\win32ui\RegViewGeneral.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Source\win32ui\RegViewPage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\Source\win32ui\WinUtils.h"
|
||||
>
|
||||
|
@ -2,13 +2,18 @@
|
||||
#include "MA_MIPSIV.h"
|
||||
#include "PtrStream.h"
|
||||
#include "ELF.h"
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace Framework;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
CPsfVm::CPsfVm(const char* psfPath) :
|
||||
m_fileSystem(psfPath),
|
||||
m_cpu(MEMORYMAP_ENDIAN_LSBF, 0x00000000, RAMSIZE)
|
||||
m_cpu(MEMORYMAP_ENDIAN_LSBF, 0x00000000, RAMSIZE),
|
||||
m_status(PAUSED),
|
||||
m_pauseAck(false),
|
||||
m_emuThread(NULL)
|
||||
{
|
||||
//Initialize block map
|
||||
m_blockMap[RAMSIZE] = 0;
|
||||
@ -20,7 +25,7 @@ m_cpu(MEMORYMAP_ENDIAN_LSBF, 0x00000000, RAMSIZE)
|
||||
|
||||
m_cpu.m_pArch = &g_MAMIPSIV;
|
||||
m_cpu.m_pAddrTranslator = m_cpu.TranslateAddress64;
|
||||
m_cpu.m_pTickFunction = TickFunction;
|
||||
m_cpu.m_pTickFunction = reinterpret_cast<TickFunctionType>(TickFunctionStub);
|
||||
m_cpu.m_pSysCallHandler = reinterpret_cast<SysCallHandlerType>(SysCallHandlerStub);
|
||||
m_cpu.m_handlerParam = this;
|
||||
|
||||
@ -38,6 +43,8 @@ m_cpu(MEMORYMAP_ENDIAN_LSBF, 0x00000000, RAMSIZE)
|
||||
reinterpret_cast<const uint8*>(&firstParam),
|
||||
4);
|
||||
m_cpu.m_State.nPC = entryPoint;
|
||||
|
||||
m_emuThread = new thread(bind(&CPsfVm::EmulationProc, this));
|
||||
}
|
||||
|
||||
CPsfVm::~CPsfVm()
|
||||
@ -45,6 +52,27 @@ CPsfVm::~CPsfVm()
|
||||
delete [] m_ram;
|
||||
}
|
||||
|
||||
void CPsfVm::Pause()
|
||||
{
|
||||
if(GetStatus() == PAUSED) return;
|
||||
m_pauseAck = false;
|
||||
m_status = PAUSED;
|
||||
while(!m_pauseAck)
|
||||
{
|
||||
xtime xt;
|
||||
xtime_get(&xt, boost::TIME_UTC);
|
||||
xt.nsec += 100000000;
|
||||
}
|
||||
m_OnRunningStateChange();
|
||||
}
|
||||
|
||||
void CPsfVm::Resume()
|
||||
{
|
||||
if(GetStatus() == RUNNING) return;
|
||||
m_status = RUNNING;
|
||||
m_OnRunningStateChange();
|
||||
}
|
||||
|
||||
CMIPS& CPsfVm::GetCpu()
|
||||
{
|
||||
return m_cpu;
|
||||
@ -52,7 +80,7 @@ CMIPS& CPsfVm::GetCpu()
|
||||
|
||||
CVirtualMachine::STATUS CPsfVm::GetStatus() const
|
||||
{
|
||||
return PAUSED;
|
||||
return m_status;
|
||||
}
|
||||
|
||||
uint32 CPsfVm::LoadIopModule(const char* modulePath, uint32 baseAddress)
|
||||
@ -145,9 +173,18 @@ uint32 CPsfVm::LoadIopModule(const char* modulePath, uint32 baseAddress)
|
||||
return baseAddress + elf.m_Header.nEntryPoint;
|
||||
}
|
||||
|
||||
unsigned int CPsfVm::TickFunction(unsigned int dummy)
|
||||
unsigned int CPsfVm::TickFunctionStub(unsigned int ticks, CMIPS* context)
|
||||
{
|
||||
return 1;
|
||||
return reinterpret_cast<CPsfVm*>(context->m_handlerParam)->TickFunction(ticks);
|
||||
}
|
||||
|
||||
unsigned int CPsfVm::TickFunction(unsigned int ticks)
|
||||
{
|
||||
if(m_cpu.MustBreak())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
string CPsfVm::ReadModuleName(uint32 address)
|
||||
@ -178,6 +215,11 @@ void CPsfVm::stdio_printf()
|
||||
const char* text = reinterpret_cast<const char*>(&m_ram[m_cpu.m_State.nGPR[param++].nV[0]]);
|
||||
printf("%s", text);
|
||||
}
|
||||
else if(type == 'd')
|
||||
{
|
||||
int number = m_cpu.m_State.nGPR[param++].nV[0];
|
||||
printf("%d", number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -262,3 +304,28 @@ uint32 CPsfVm::Push(uint32& address, const uint8* data, uint32 size)
|
||||
memcpy(&m_ram[address], data, size);
|
||||
return address;
|
||||
}
|
||||
|
||||
void CPsfVm::EmulationProc()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(m_status == RUNNING)
|
||||
{
|
||||
RET_CODE returnCode = m_cpu.Execute(1000);
|
||||
if(returnCode == RET_CODE_BREAKPOINT)
|
||||
{
|
||||
m_status = PAUSED;
|
||||
m_OnRunningStateChange();
|
||||
m_OnMachineStateChange();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pauseAck = true;
|
||||
xtime xt;
|
||||
xtime_get(&xt, boost::TIME_UTC);
|
||||
xt.nsec += 100000000;
|
||||
thread::sleep(xt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "PsfFs.h"
|
||||
#include "VirtualMachine.h"
|
||||
#include <string>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
class CPsfVm : public CVirtualMachine
|
||||
{
|
||||
@ -14,6 +15,8 @@ public:
|
||||
|
||||
CMIPS& GetCpu();
|
||||
STATUS GetStatus() const;
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
private:
|
||||
typedef std::map<uint32, uint32> BlockMapType;
|
||||
@ -32,17 +35,23 @@ private:
|
||||
uint32 AllocateMemory(uint32);
|
||||
void FreeMemory(uint32);
|
||||
uint32 Push(uint32&, const uint8*, uint32);
|
||||
static unsigned int TickFunction(unsigned int);
|
||||
static unsigned int TickFunctionStub(unsigned int, CMIPS*);
|
||||
static void SysCallHandlerStub(CMIPS*);
|
||||
unsigned int TickFunction(unsigned int);
|
||||
void SysCallHandler();
|
||||
|
||||
std::string ReadModuleName(uint32);
|
||||
void stdio_printf();
|
||||
|
||||
void EmulationProc();
|
||||
|
||||
CMIPS m_cpu;
|
||||
CPsfFs m_fileSystem;
|
||||
uint8* m_ram;
|
||||
BlockMapType m_blockMap;
|
||||
STATUS m_status;
|
||||
bool m_pauseAck;
|
||||
boost::thread* m_emuThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,11 @@ m_virtualMachine(virtualMachine)
|
||||
|
||||
m_splitter = new Win32::CHorizontalSplitter(m_hWnd, GetClientRect());
|
||||
m_disAsmView = new CDisAsm(m_splitter->m_hWnd, Win32::CRect(0, 0, 1, 1), m_virtualMachine, &m_virtualMachine.GetCpu());
|
||||
m_registerView = new CRegViewGeneral(m_splitter->m_hWnd, Win32::CRect(0, 0, 1, 1), m_virtualMachine, &m_virtualMachine.GetCpu());
|
||||
m_registerView->Show(SW_SHOW);
|
||||
|
||||
m_splitter->SetChild(0, *m_disAsmView);
|
||||
m_splitter->SetChild(1, *m_registerView);
|
||||
m_disAsmView->SetAddress(m_virtualMachine.GetCpu().m_State.nPC);
|
||||
}
|
||||
|
||||
@ -62,6 +66,9 @@ long CMiniDebugger::OnCommand(unsigned short command, unsigned short id, HWND hw
|
||||
case ID_VM_STEP1:
|
||||
StepCPU();
|
||||
break;
|
||||
case ID_VM_RESUME:
|
||||
m_virtualMachine.Resume();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "win32/Window.h"
|
||||
#include "win32/HorizontalSplitter.h"
|
||||
#include "win32ui/DisAsm.h"
|
||||
#include "win32ui/RegViewGeneral.h"
|
||||
#include "../PsfVm.h"
|
||||
|
||||
class CMiniDebugger : public Framework::Win32::CWindow
|
||||
@ -23,6 +24,7 @@ private:
|
||||
CPsfVm& m_virtualMachine;
|
||||
Framework::Win32::CHorizontalSplitter* m_splitter;
|
||||
CDisAsm* m_disAsmView;
|
||||
CRegViewGeneral* m_registerView;
|
||||
HACCEL m_acceleratorTable;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user