mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Debugger improved: Register editor added
How to use the register editor: 1. Load an .ELF file 2. Select any instruction from a thread. (This is a workaround to activate the appropriate event listener. This will be changed in the future). 3. Press 'R' key and modify any register you want. Note: The register editor only works with PPU and SPU threads. Additional changes: * Fixed the filesize problem caused by the instruction editor dialog. * Instruction Editor: Fixed small issue in SPU threads
This commit is contained in:
parent
bf293ebbfc
commit
9c6ae554fa
@ -159,6 +159,8 @@ public:
|
||||
void Stop();
|
||||
|
||||
virtual wxString RegsToString() { return wxEmptyString; }
|
||||
virtual wxString ReadRegString(wxString reg) { return wxEmptyString; }
|
||||
virtual bool WriteRegString(wxString reg, wxString value) { return false; }
|
||||
|
||||
virtual void Exec();
|
||||
void ExecOnce();
|
||||
|
@ -753,6 +753,69 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual wxString ReadRegString(wxString reg)
|
||||
{
|
||||
if (reg.Contains("["))
|
||||
{
|
||||
long reg_index;
|
||||
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||
if (reg.StartsWith("GPR")) return wxString::Format("%016x", GPR[reg_index]);
|
||||
if (reg.StartsWith("FPR")) return wxString::Format("%016x", FPR[reg_index]);
|
||||
if (reg.StartsWith("VPR")) return wxString::Format("%032x", VPR[reg_index]);
|
||||
}
|
||||
if (reg == "CR") return wxString::Format("%08x", CR);
|
||||
if (reg == "LR") return wxString::Format("%016x", LR);
|
||||
if (reg == "CTR") return wxString::Format("%016x", CTR);
|
||||
if (reg == "XER") return wxString::Format("%016x", XER);
|
||||
if (reg == "FPSCR") return wxString::Format("%08x", FPSCR);
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
bool WriteRegString(wxString reg, wxString value) {
|
||||
while (value.Len() < 32) value = "0"+value;
|
||||
if (reg.Contains("["))
|
||||
{
|
||||
long reg_index;
|
||||
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||
if (reg.StartsWith("GPR") || (reg.StartsWith("FPR")))
|
||||
{
|
||||
unsigned long long reg_value;
|
||||
if (!value.SubString(16,32).ToULongLong(®_value, 16)) return false;
|
||||
if (reg.StartsWith("GPR")) GPR[reg_index] = (u64)reg_value;
|
||||
if (reg.StartsWith("FPR")) FPR[reg_index] = (u64)reg_value;
|
||||
return true;
|
||||
}
|
||||
if (reg.StartsWith("VPR"))
|
||||
{
|
||||
unsigned long long reg_value0;
|
||||
unsigned long long reg_value1;
|
||||
if (!value.SubString(16,32).ToULongLong(®_value0, 16)) return false;
|
||||
if (!value.SubString(0,16).ToULongLong(®_value1, 16)) return false;
|
||||
VPR[reg_index]._u64[0] = (u64)reg_value0;
|
||||
VPR[reg_index]._u64[1] = (u64)reg_value1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (reg == "LR" || reg == "CTR" || reg == "XER")
|
||||
{
|
||||
unsigned long long reg_value;
|
||||
if (!value.SubString(16,32).ToULongLong(®_value, 16)) return false;
|
||||
if (reg == "LR") LR = (u64)reg_value;
|
||||
if (reg == "CTR") CTR = (u64)reg_value;
|
||||
if (reg == "XER") XER.XER = (u64)reg_value;
|
||||
return true;
|
||||
}
|
||||
if (reg == "CR" || reg == "FPSCR")
|
||||
{
|
||||
unsigned long reg_value;
|
||||
if (!value.SubString(24,32).ToULong(®_value, 16)) return false;
|
||||
if (reg == "CR") CR.CR = (u32)reg_value;
|
||||
if (reg == "FPSCR") FPSCR.FPSCR = (u32)reg_value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void AddArgv(const wxString& arg);
|
||||
|
||||
public:
|
||||
|
@ -249,6 +249,37 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual wxString ReadRegString(wxString reg)
|
||||
{
|
||||
if (reg.Contains("["))
|
||||
{
|
||||
long reg_index;
|
||||
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||
if (reg.StartsWith("GPR")) return wxString::Format("%032x", GPR[reg_index]);
|
||||
}
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
bool WriteRegString(wxString reg, wxString value) {
|
||||
while (value.Len() < 32) value = "0"+value;
|
||||
if (reg.Contains("["))
|
||||
{
|
||||
long reg_index;
|
||||
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||
if (reg.StartsWith("GPR"))
|
||||
{
|
||||
unsigned long long reg_value0;
|
||||
unsigned long long reg_value1;
|
||||
if (!value.SubString(16,32).ToULongLong(®_value0, 16)) return false;
|
||||
if (!value.SubString(0,16).ToULongLong(®_value1, 16)) return false;
|
||||
GPR[reg_index]._u64[0] = (u64)reg_value0;
|
||||
GPR[reg_index]._u64[1] = (u64)reg_value1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void InitRegs();
|
||||
virtual u64 GetFreeStackSize() const;
|
||||
|
@ -1,5 +1,20 @@
|
||||
#include "stdafx.h"
|
||||
#include "InstructionEditor.h"
|
||||
class InstructionEditorDialog
|
||||
: public wxDialog
|
||||
{
|
||||
u64 pc;
|
||||
PPC_DisAsm* disasm;
|
||||
PPC_Decoder* decoder;
|
||||
wxTextCtrl* t2_instr;
|
||||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
PPCThread* CPU;
|
||||
|
||||
public:
|
||||
InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||
|
||||
void updatePreview(wxCommandEvent& event);
|
||||
};
|
||||
|
||||
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
||||
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
|
||||
@ -56,7 +71,7 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCTh
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
|
||||
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
|
||||
t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(pc)));
|
||||
t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(CPU->GetOffset() + pc)));
|
||||
|
||||
this->SetSizerAndFit(s_panel_margin_x);
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include "Emu/Cell/PPCThread.h"
|
||||
#include "Emu/Cell/PPUDecoder.h"
|
||||
#include "Emu/Cell/PPUDisAsm.h"
|
||||
#include "Emu/Cell/SPUDecoder.h"
|
||||
#include "Emu/Cell/SPUDisAsm.h"
|
||||
|
||||
class InstructionEditorDialog
|
||||
: public wxDialog
|
||||
{
|
||||
u64 pc;
|
||||
PPC_DisAsm* disasm;
|
||||
PPC_Decoder* decoder;
|
||||
wxTextCtrl* t2_instr;
|
||||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
PPCThread* CPU;
|
||||
|
||||
public:
|
||||
InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||
|
||||
void updatePreview(wxCommandEvent& event);
|
||||
};
|
@ -1,6 +1,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "InterpreterDisAsm.h"
|
||||
#include "InstructionEditor.h"
|
||||
|
||||
#include "InstructionEditor.cpp"
|
||||
#include "RegisterEditor.cpp"
|
||||
|
||||
//static const int show_lines = 30;
|
||||
|
||||
@ -458,6 +460,10 @@ void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
|
||||
InstructionEditorDialog(this, pc, CPU, decoder, disasm);
|
||||
DoUpdate();
|
||||
return;
|
||||
case 'R':
|
||||
RegisterEditorDialog(this, pc, CPU, decoder, disasm);
|
||||
DoUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
105
rpcs3/Gui/RegisterEditor.cpp
Normal file
105
rpcs3/Gui/RegisterEditor.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
class RegisterEditorDialog
|
||||
: public wxDialog
|
||||
{
|
||||
u64 pc;
|
||||
PPC_DisAsm* disasm;
|
||||
PPC_Decoder* decoder;
|
||||
wxComboBox* t1_register;
|
||||
wxTextCtrl* t2_value;
|
||||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
PPCThread* CPU;
|
||||
|
||||
public:
|
||||
RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||
|
||||
void updateRegister(wxCommandEvent& event);
|
||||
void updatePreview(wxCommandEvent& event);
|
||||
};
|
||||
|
||||
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
||||
: wxDialog(parent, wxID_ANY, "Edit registers", wxDefaultPosition)
|
||||
, pc(_pc)
|
||||
, CPU(_CPU)
|
||||
, decoder(_decoder)
|
||||
, disasm(_disasm)
|
||||
{
|
||||
wxBoxSizer* s_panel_margin_x(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_panel_margin_y(new wxBoxSizer(wxVERTICAL));
|
||||
|
||||
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
|
||||
wxBoxSizer* s_t1_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_t2_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_t3_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
|
||||
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Register: ");
|
||||
t1_register = new wxComboBox(this, wxID_ANY, wxEmptyString);
|
||||
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Value (Hex):");
|
||||
t2_value = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1));
|
||||
|
||||
s_t1_panel->Add(t1_text);
|
||||
s_t1_panel->AddSpacer(8);
|
||||
s_t1_panel->Add(t1_register);
|
||||
|
||||
s_t2_panel->Add(t2_text);
|
||||
s_t2_panel->AddSpacer(8);
|
||||
s_t2_panel->Add(t2_value);
|
||||
|
||||
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
|
||||
s_b_panel->AddSpacer(5);
|
||||
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxLEFT, 0, 5);
|
||||
|
||||
s_panel->Add(s_t1_panel);
|
||||
s_panel->AddSpacer(8);
|
||||
s_panel->Add(s_t2_panel);
|
||||
s_panel->AddSpacer(16);
|
||||
s_panel->Add(s_b_panel);
|
||||
|
||||
s_panel_margin_y->AddSpacer(12);
|
||||
s_panel_margin_y->Add(s_panel);
|
||||
s_panel_margin_y->AddSpacer(12);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
s_panel_margin_x->Add(s_panel_margin_y);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
|
||||
this->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(RegisterEditorDialog::updateRegister));
|
||||
|
||||
if (CPU->GetType() == PPC_THREAD_PPU)
|
||||
{
|
||||
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("FPR[%d]",i));
|
||||
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("VPR[%d]",i));
|
||||
t1_register->Append("CR");
|
||||
t1_register->Append("LR");
|
||||
t1_register->Append("CTR");
|
||||
t1_register->Append("XER");
|
||||
t1_register->Append("FPSCR");
|
||||
}
|
||||
if (CPU->GetType() == PPC_THREAD_SPU)
|
||||
{
|
||||
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||
}
|
||||
if (CPU->GetType() == PPC_THREAD_RAW_SPU)
|
||||
{
|
||||
wxMessageBox("RawSPU threads not yet supported.","Error");
|
||||
return;
|
||||
}
|
||||
|
||||
this->SetSizerAndFit(s_panel_margin_x);
|
||||
|
||||
if(this->ShowModal() == wxID_OK)
|
||||
{
|
||||
wxString reg = t1_register->GetStringSelection();
|
||||
wxString value = t2_value->GetValue();
|
||||
if (!CPU->WriteRegString(reg,value))
|
||||
wxMessageBox("This value could not be converted.\nNo changes were made.","Error");
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
|
||||
{
|
||||
wxString reg = t1_register->GetStringSelection();
|
||||
t2_value->SetValue(CPU->ReadRegString(reg));
|
||||
}
|
@ -265,7 +265,6 @@
|
||||
<ClCompile Include="Gui\Debugger.cpp" />
|
||||
<ClCompile Include="Gui\DisAsmFrame.cpp" />
|
||||
<ClCompile Include="Gui\GameViewer.cpp" />
|
||||
<ClCompile Include="Gui\InstructionEditor.cpp" />
|
||||
<ClCompile Include="Gui\InterpreterDisAsm.cpp" />
|
||||
<ClCompile Include="Gui\MainFrame.cpp" />
|
||||
<ClCompile Include="Gui\MemoryViewer.cpp" />
|
||||
|
@ -307,9 +307,6 @@
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Mouse.cpp">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Gui\InstructionEditor.cpp">
|
||||
<Filter>Gui</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
|
Loading…
Reference in New Issue
Block a user