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

This commit is contained in:
jpd002 2007-10-31 22:09:21 +00:00
parent d557e266d7
commit 406d153cf8
15 changed files with 213 additions and 34 deletions

View File

@ -2496,14 +2496,15 @@ void CCodeGen::Cmp64Lt(bool nSigned, bool nOrEqual)
{
struct EmitComparaison
{
void operator ()(uint32 nValueType, uint32 nValue, unsigned int nRegister)
void operator ()(uint32 nValueType, uint32 nValue, unsigned int nRegister, CX86Assembler& assembler)
{
switch(nValueType)
{
case CONSTANT:
assert(GetMinimumConstantSize(nValue) == 1);
//cmp reg, Immediate
m_pBlock->StreamWrite(3, 0x83, 0xC0 | (0x07 << 3) | (m_nRegisterLookup[nRegister]), static_cast<uint8>(nValue));
assembler.CmpId(
CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[nRegister]),
nValue);
break;
case RELATIVE:
//cmp reg, dword ptr[rel]
@ -2612,7 +2613,7 @@ void CCodeGen::Cmp64Lt(bool nSigned, bool nOrEqual)
//mov reg, dword ptr[base + rel2]
LoadRelativeInRegister(nRegister, nValue[1]);
EmitComparaison()(nValueType[3], nValue[3], nRegister);
EmitComparaison()(nValueType[3], nValue[3], nRegister, m_Assembler);
//je +0x08
m_pBlock->StreamWrite(2, 0x74, 0x08);
@ -2636,7 +2637,7 @@ void CCodeGen::Cmp64Lt(bool nSigned, bool nOrEqual)
//mov reg, dword ptr[base + rel1]
LoadRelativeInRegister(nRegister, nValue[0]);
EmitComparaison()(nValueType[2], nValue[2], nRegister);
EmitComparaison()(nValueType[2], nValue[2], nRegister, m_Assembler);
//setb/be reg[l]
m_pBlock->StreamWrite(3, 0x0F, nOrEqual ? 0x96 : 0x92, 0xC0 | (0x00 << 3) | (m_nRegisterLookup[nRegister]));

View File

@ -65,6 +65,18 @@ struct ELFPROGRAMHEADER
class CELF
{
public:
enum SECTION_HEADER_TYPE
{
SHT_REL = 9,
};
enum MIPS_RELOCATION_TYPE
{
R_MIPS_26 = 4,
R_MIPS_HI16 = 5,
R_MIPS_LO16 = 6,
};
CELF(Framework::CStream*);
~CELF();
ELFSECTIONHEADER* GetSection(unsigned int);

View File

@ -65,6 +65,11 @@ void CX86Assembler::CmpEq(REGISTER nRegister, const CAddress& Address)
WriteEvGvOp(0x3B, true, Address, nRegister);
}
void CX86Assembler::CmpId(const CAddress& address, uint32 constant)
{
WriteEvId(0x07, address, constant);
}
void CX86Assembler::CmpIq(const CAddress& Address, uint64 nConstant)
{
WriteEvIq(0x07, Address, nConstant);

View File

@ -61,6 +61,7 @@ public:
void AddId(const CAddress&, uint32);
void CmpEq(REGISTER, const CAddress&);
void CmpId(const CAddress&, uint32);
void CmpIq(const CAddress&, uint64);
void Nop();
void MovEd(REGISTER, const CAddress&);

View File

@ -122,6 +122,9 @@ void CELFSectionView::FillInformation()
case 0x08:
_tcscpy(sTemp, _T("SHT_NOBITS"));
break;
case 0x09:
_tcscpy(sTemp, _T("SHT_REL"));
break;
default:
_sntprintf(sTemp, countof(sTemp), _T("Unknown (0x%0.8X)"), pH->nType);
break;

View File

@ -200,6 +200,10 @@
RelativePath=".\Source\PsfVm.cpp"
>
</File>
<File
RelativePath=".\Source\RegisterView.cpp"
>
</File>
<File
RelativePath=".\Source\TextDebugger.cpp"
>
@ -242,6 +246,10 @@
RelativePath=".\Source\PsfVm.h"
>
</File>
<File
RelativePath=".\Source\RegisterView.h"
>
</File>
<File
RelativePath=".\Source\TextDebugger.h"
>

View File

@ -21,6 +21,7 @@ void CDisAsmView::SetViewAddress(uint32 viewAddress)
void CDisAsmView::Update(WINDOW* window, int width, int height)
{
uint32 address = m_viewAddress;
getmaxyx(window, height, width);
for(int i = 0; i < height; i++)
{
@ -56,4 +57,6 @@ void CDisAsmView::Update(WINDOW* window, int width, int height)
address += 4;
}
wrefresh(window);
}

View File

@ -16,6 +16,7 @@ CMemoryView::~CMemoryView()
void CMemoryView::Update(WINDOW* window, int width, int height)
{
const int bytesPerLine = 16;
getmaxyx(window, height, width);
uint32 address = m_viewAddress;
//Draw the ruler
@ -62,7 +63,9 @@ void CMemoryView::Update(WINDOW* window, int width, int height)
}
address += bytesPerLine;
}
}
wrefresh(window);
}
void CMemoryView::SetViewAddress(uint32 viewAddress)

View File

@ -4,6 +4,7 @@
#include "ELF.h"
using namespace Framework;
using namespace std;
CPsfVm::CPsfVm(const char* psfPath) :
m_fileSystem(psfPath),
@ -13,6 +14,7 @@ m_cpu(MEMORYMAP_ENDIAN_LSBF, 0x00000000, RAMSIZE)
m_cpu.m_pMemoryMap->InsertReadMap(0x00000000, RAMSIZE - 1, m_ram, MEMORYMAP_TYPE_MEMORY, 0x00);
m_cpu.m_pArch = &g_MAMIPSIV;
m_cpu.m_pAddrTranslator = m_cpu.TranslateAddress64;
m_cpu.m_pTickFunction = TickFunction;
uint32 entryPoint = LoadIopModule("psf2.irx", 0x000100000);
m_cpu.m_State.nPC = entryPoint;
@ -34,6 +36,58 @@ uint32 CPsfVm::LoadIopModule(const char* modulePath, uint32 baseAddress)
CPtrStream stream(file->data, file->size);
CELF elf(&stream);
//Process relocation
for(unsigned int i = 0; i < elf.m_Header.nSectHeaderCount; i++)
{
ELFSECTIONHEADER* sectionHeader = elf.GetSection(i);
if(sectionHeader != NULL && sectionHeader->nType == CELF::SHT_REL)
{
unsigned int linkedSection = sectionHeader->nInfo;
unsigned int recordCount = sectionHeader->nSize / 8;
ELFSECTIONHEADER* relocatedSection = elf.GetSection(linkedSection);
const uint32* relocationRecord = reinterpret_cast<const uint32*>(elf.GetSectionData(i));
uint8* relocatedSectionData = reinterpret_cast<uint8*>(const_cast<void*>(elf.GetSectionData(linkedSection)));
if(relocatedSection == NULL || relocationRecord == NULL || relocatedSection == NULL) continue;
for(unsigned int record = 0; record < recordCount; record++)
{
uint32 relocationAddress = relocationRecord[0];
uint32 relocationType = relocationRecord[1];
if(relocationAddress < relocatedSection->nSize)
{
uint32& instruction = *reinterpret_cast<uint32*>(&relocatedSectionData[relocationAddress]);
switch(relocationType)
{
case CELF::R_MIPS_26:
{
uint32 offset = (instruction & 0x03FFFFFF) + (baseAddress >> 2);
instruction &= ~0x03FFFFFF;
instruction |= offset;
}
break;
case CELF::R_MIPS_HI16:
{
uint32 offset = (instruction & 0xFFFF) + (baseAddress >> 16);
instruction &= ~0xFFFF;
instruction |= offset;
}
break;
case CELF::R_MIPS_LO16:
{
uint32 offset = (instruction & 0xFFFF) + (baseAddress & 0xFFFF);
instruction &= ~0xFFFF;
instruction |= offset;
}
break;
default:
throw exception();
break;
}
}
relocationRecord += 2;
}
}
}
for(unsigned int i = 0; i < elf.m_Header.nProgHeaderCount; i++)
{
ELFPROGRAMHEADER* programHeader = elf.GetProgram(i);
@ -48,3 +102,8 @@ uint32 CPsfVm::LoadIopModule(const char* modulePath, uint32 baseAddress)
return baseAddress + elf.m_Header.nEntryPoint;
}
unsigned int CPsfVm::TickFunction(unsigned int dummy)
{
return 1;
}

View File

@ -7,10 +7,10 @@
class CPsfVm
{
public:
CPsfVm(const char*);
virtual ~CPsfVm();
CPsfVm(const char*);
virtual ~CPsfVm();
CMIPS& GetCpu();
CMIPS& GetCpu();
private:
enum RAMSIZE
@ -18,11 +18,12 @@ private:
RAMSIZE = 0x00400000,
};
uint32 LoadIopModule(const char*, uint32);
uint32 LoadIopModule(const char*, uint32);
static unsigned int TickFunction(unsigned int);
CMIPS m_cpu;
CPsfFs m_fileSystem;
uint8* m_ram;
CMIPS m_cpu;
CPsfFs m_fileSystem;
uint8* m_ram;
};
#endif

View File

@ -0,0 +1,41 @@
#include "RegisterView.h"
#include "CursesUtils.h"
CRegisterView::CRegisterView(CMIPS& cpu) :
m_cpu(cpu)
{
}
CRegisterView::~CRegisterView()
{
}
void CRegisterView::Update(WINDOW* window, int width, int height)
{
getmaxyx(window, width, height);
const unsigned int registerCount = 32;
const unsigned int columnCount = 5;
const unsigned int lineCount = (registerCount + (columnCount - 1)) / (columnCount);
int reg = 0;
for(unsigned int i = 0; i < lineCount && reg < registerCount; i++)
{
wmove(window, i, 0);
CursesUtils::ClearLine(window, width);
wmove(window, i, 0);
for(unsigned int j = 0; j < columnCount && reg < registerCount; j++)
{
const char* regName = CMIPS::m_sGPRName[reg];
uint32 regValue = m_cpu.m_State.nGPR[reg].nV0;
wprintw(window, "%s: 0x%0.8X ", regName, regValue);
reg++;
}
}
wrefresh(window);
}

View File

@ -0,0 +1,19 @@
#ifndef _REGISTERVIEW_H_
#define _REGISTERVIEW_H_
#include "DebugView.h"
#include "MIPS.h"
class CRegisterView : public CDebugView
{
public:
CRegisterView(CMIPS&);
virtual ~CRegisterView();
void Update(WINDOW*, int, int);
private:
CMIPS& m_cpu;
};
#endif

View File

@ -8,11 +8,14 @@ using namespace boost;
CTextDebugger::CTextDebugger(CMIPS& cpu) :
m_cpu(cpu),
m_window(NULL),
//m_window(NULL),
m_commandWindow(NULL),
m_primaryWindow(NULL),
m_height(0),
m_width(0),
m_disAsmView(cpu),
m_memoryView(cpu),
m_registerView(cpu),
m_currentView(&m_disAsmView)
{
@ -25,26 +28,36 @@ CTextDebugger::~CTextDebugger()
void CTextDebugger::Run()
{
initscr();
WINDOW* _stdscr = initscr();
cbreak();
noecho();
start_color();
init_pair(1, COLOR_YELLOW, COLOR_BLUE);
init_pair(2, COLOR_BLUE, COLOR_YELLOW);
init_pair(2, COLOR_WHITE, COLOR_BLUE);
init_pair(3, COLOR_BLACK, COLOR_WHITE);
m_window = newwin(0, 0, 0, 0);
getmaxyx(m_window, m_height, m_width);
keypad(m_window, true);
getmaxyx(_stdscr, m_height, m_width);
// m_window = newwin(0, 0, 0, 0);
// getmaxyx(m_window, m_height, m_width);
const int regViewHeight = 7;
const int commandViewHeight = 1;
const int primaryViewHeight = m_height - regViewHeight - commandViewHeight;
m_commandWindow = newwin(commandViewHeight, m_width, m_height - commandViewHeight, 0);
m_primaryWindow = newwin(primaryViewHeight, m_width, 0, 0);
m_secondaryWindow = newwin(regViewHeight, m_width, primaryViewHeight, 0);
keypad(m_commandWindow, true);
wbkgd(m_commandWindow, COLOR_PAIR(2));
// uint32 address = cpu.m_State.nPC;
// address = 0x1005E0;
// UpdateDisassembly(vin, cpu, address, w, h - 1);
// UpdateMemory(vin, cpu, address, w, h - 1);
// wbkgd(vin, COLOR_PAIR(3));
m_disAsmView.SetViewAddress(m_cpu.m_State.nPC);
string command;
@ -52,15 +65,16 @@ void CTextDebugger::Run()
{
if(m_currentView != NULL)
{
m_currentView->Update(m_window, m_width, m_height);
m_currentView->Update(m_primaryWindow, m_width, m_height - 1);
}
m_registerView.Update(m_secondaryWindow, m_width, m_height);
wmove(m_window, m_height - 1, 0);
CursesUtils::ClearLine(m_window, m_width);
wmove(m_window, m_height - 1, 0);
wprintw(m_window, command.c_str());
wrefresh(m_window);
int ch = wgetch(m_window);
wmove(m_commandWindow, 0, 0);
CursesUtils::ClearLine(m_commandWindow, m_width);
wmove(m_commandWindow, 0, 0);
wprintw(m_commandWindow, command.c_str());
wrefresh(m_commandWindow);
int ch = wgetch(m_commandWindow);
if(ch == KEY_F(10))
{
@ -84,10 +98,14 @@ void CTextDebugger::Run()
}
}
delwin(m_window);
delwin(m_commandWindow);
delwin(m_primaryWindow);
// delwin(m_window);
endwin();
m_window = NULL;
m_commandWindow = NULL;
m_primaryWindow = NULL;
// m_window = NULL;
}
void CTextDebugger::ExecuteCommand(const string& command)

View File

@ -6,6 +6,7 @@
#include "MIPS.h"
#include "DisAsmView.h"
#include "MemoryView.h"
#include "RegisterView.h"
class CTextDebugger
{
@ -18,13 +19,17 @@ public:
private:
void ExecuteCommand(const std::string&);
WINDOW* m_window;
// WINDOW* m_window;
WINDOW* m_primaryWindow;
WINDOW* m_secondaryWindow;
WINDOW* m_commandWindow;
int m_width;
int m_height;
CMIPS& m_cpu;
CDebugView* m_currentView;
CDisAsmView m_disAsmView;
CMemoryView m_memoryView;
CRegisterView m_registerView;
};
#endif

View File

@ -4,15 +4,15 @@
using namespace std;
int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, char* params, int showCmd)
//int main(int argc, char** argv)
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, char*, int)
{
AllocConsole();
string filename = "C:\\nsf\\kh\\Kingdom Hearts (Sequences Only)\\101 - Dearly Beloved.psf2";
// string filename = "C:\\nsf\\FF10\\111 Game Over.minipsf2";
CPsfVm virtualMachine(filename.c_str());
AllocConsole();
CTextDebugger debugger(virtualMachine.GetCpu());
debugger.Run();
return 1;
}