diff --git a/rpcs3/Gui/InstructionEditor.cpp b/rpcs3/Gui/InstructionEditor.cpp
new file mode 100644
index 0000000000..83011e37e7
--- /dev/null
+++ b/rpcs3/Gui/InstructionEditor.cpp
@@ -0,0 +1,88 @@
+#include "stdafx.h"
+#include "InstructionEditor.h"
+
+InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
+ : wxDialog(parent, wxID_ANY, "Edit instruction", 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, "Address: ");
+ wxStaticText* t1_addr = new wxStaticText(this, wxID_ANY, wxString::Format("%08x",pc));
+ wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Instruction:");
+ t2_instr = new wxTextCtrl(this, wxID_ANY);
+ wxStaticText* t3_text = new wxStaticText(this, wxID_ANY, "Preview: ");
+ t3_preview = new wxStaticText(this, wxID_ANY, "");
+
+ s_t1_panel->Add(t1_text);
+ s_t1_panel->AddSpacer(8);
+ s_t1_panel->Add(t1_addr);
+
+ s_t2_panel->Add(t2_text);
+ s_t2_panel->AddSpacer(8);
+ s_t2_panel->Add(t2_instr);
+
+ s_t3_panel->Add(t3_text);
+ s_t3_panel->AddSpacer(8);
+ s_t3_panel->Add(t3_preview);
+
+ 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), wxRIGHT, 0, 5);
+
+ s_panel->Add(s_t1_panel);
+ s_panel->AddSpacer(8);
+ s_panel->Add(s_t3_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_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
+ t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(pc)));
+
+ this->SetSizerAndFit(s_panel_margin_x);
+
+ if(this->ShowModal() == wxID_OK)
+ {
+ unsigned long opcode;
+ if (!t2_instr->GetValue().ToULong(&opcode, 16))
+ wxMessageBox("This instruction could not be parsed.\nNo changes were made.","Error");
+ else
+ Memory.Write32(CPU->GetOffset() + pc, (u32)opcode);
+ }
+}
+
+void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
+{
+ unsigned long opcode;
+ if (t2_instr->GetValue().ToULong(&opcode, 16))
+ {
+ decoder->Decode((u32)opcode);
+ wxString preview = disasm->last_opcode;
+ while (preview[0] != ':') preview.Remove(0,1);
+ preview.Remove(0,1);
+ t3_preview->SetLabel(preview);
+ }
+ else
+ {
+ t3_preview->SetLabel("Could not parse instruction.");
+ }
+}
\ No newline at end of file
diff --git a/rpcs3/Gui/InstructionEditor.h b/rpcs3/Gui/InstructionEditor.h
new file mode 100644
index 0000000000..7edb0ef1a8
--- /dev/null
+++ b/rpcs3/Gui/InstructionEditor.h
@@ -0,0 +1,24 @@
+#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 346a03810c..2475a7f24c 100644
--- a/rpcs3/Gui/InterpreterDisAsm.cpp
+++ b/rpcs3/Gui/InterpreterDisAsm.cpp
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "InterpreterDisAsm.h"
+#include "InstructionEditor.h"
//static const int show_lines = 30;
@@ -67,6 +68,7 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
Connect(m_btn_step->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoStep));
Connect(m_btn_run->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoRun));
Connect(m_btn_pause->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoPause));
+ Connect(m_list->GetId(), wxEVT_COMMAND_LIST_KEY_DOWN, wxListEventHandler(InterpreterDisAsmFrame::InstrKey));
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(InterpreterDisAsmFrame::DClick));
Connect(m_choice_units->GetId(),wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(InterpreterDisAsmFrame::OnSelectUnit));
Connect(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
@@ -442,6 +444,23 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
ThreadBase::Start();
}
+void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
+{
+ long i = m_list->GetFirstSelected();
+ if(i < 0) return;
+
+ const u64 start_pc = PC - m_item_count*4;
+ const u64 pc = start_pc + i*4;
+
+ switch(event.GetKeyCode())
+ {
+ case 'E':
+ InstructionEditorDialog(this, pc, CPU, decoder, disasm);
+ DoUpdate();
+ return;
+ }
+}
+
void InterpreterDisAsmFrame::DClick(wxListEvent& event)
{
long i = m_list->GetFirstSelected();
diff --git a/rpcs3/Gui/InterpreterDisAsm.h b/rpcs3/Gui/InterpreterDisAsm.h
index b86db3ab2a..f14068db35 100644
--- a/rpcs3/Gui/InterpreterDisAsm.h
+++ b/rpcs3/Gui/InterpreterDisAsm.h
@@ -46,6 +46,7 @@ public:
void DoRun(wxCommandEvent& event);
void DoPause(wxCommandEvent& event);
void DoStep(wxCommandEvent& event);
+ void InstrKey(wxListEvent& event);
void DClick(wxListEvent& event);
void MouseWheel(wxMouseEvent& event);
diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj
index 893c671409..0558b5154b 100644
--- a/rpcs3/rpcs3.vcxproj
+++ b/rpcs3/rpcs3.vcxproj
@@ -265,6 +265,7 @@
+
diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters
index 1606f87a8a..fd5bf44ddf 100644
--- a/rpcs3/rpcs3.vcxproj.filters
+++ b/rpcs3/rpcs3.vcxproj.filters
@@ -307,6 +307,9 @@
Emu\SysCalls\lv2
+
+ Gui
+