git-svn-id: http://svn.purei.org/purei/trunk@167 b36208d7-6611-0410-8bec-b1987f11c4a2

This commit is contained in:
jpd002 2007-11-06 02:08:51 +00:00
parent d3f2ebe262
commit 175f74312a
12 changed files with 151 additions and 38 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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"
>

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;
};