diff --git a/rpcs3/Emu/Cell/PPCThread.h b/rpcs3/Emu/Cell/PPCThread.h index a4f2f5ae33..63ba891b28 100644 --- a/rpcs3/Emu/Cell/PPCThread.h +++ b/rpcs3/Emu/Cell/PPCThread.h @@ -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(); diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 6954c31412..b6740d663f 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -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: diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 26775a6ec9..b99ae24cbd 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -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; diff --git a/rpcs3/Gui/InstructionEditor.cpp b/rpcs3/Gui/InstructionEditor.cpp index 83011e37e7..cb5491e368 100644 --- a/rpcs3/Gui/InstructionEditor.cpp +++ b/rpcs3/Gui/InstructionEditor.cpp @@ -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); diff --git a/rpcs3/Gui/InstructionEditor.h b/rpcs3/Gui/InstructionEditor.h deleted file mode 100644 index 7edb0ef1a8..0000000000 --- a/rpcs3/Gui/InstructionEditor.h +++ /dev/null @@ -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); -}; \ No newline at end of file diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index 2475a7f24c..cc671c6e9d 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -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; } } diff --git a/rpcs3/Gui/RegisterEditor.cpp b/rpcs3/Gui/RegisterEditor.cpp new file mode 100644 index 0000000000..da190f2e11 --- /dev/null +++ b/rpcs3/Gui/RegisterEditor.cpp @@ -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)); +} \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 0558b5154b..893c671409 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -265,7 +265,6 @@ - diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index fd5bf44ddf..1606f87a8a 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -307,9 +307,6 @@ Emu\SysCalls\lv2 - - Gui -