mirror of
https://github.com/libretro/Play-.git
synced 2024-12-13 03:27:09 +00:00
git-svn-id: http://svn.purei.org/purei/trunk@158 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
d557e266d7
commit
406d153cf8
@ -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]));
|
||||
|
12
Source/ELF.h
12
Source/ELF.h
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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&);
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
@ -63,6 +64,8 @@ void CMemoryView::Update(WINDOW* window, int width, int height)
|
||||
|
||||
address += bytesPerLine;
|
||||
}
|
||||
|
||||
wrefresh(window);
|
||||
}
|
||||
|
||||
void CMemoryView::SetViewAddress(uint32 viewAddress)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
41
tools/PsfPlayer/Source/RegisterView.cpp
Normal file
41
tools/PsfPlayer/Source/RegisterView.cpp
Normal 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);
|
||||
}
|
||||
|
19
tools/PsfPlayer/Source/RegisterView.h
Normal file
19
tools/PsfPlayer/Source/RegisterView.h
Normal 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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user