debugger: Tweaks + add context menu to write different value types (#1950)

This commit is contained in:
Swift
2026-06-09 15:04:33 -05:00
committed by GitHub
parent bae38e56c2
commit 745d30bc08
3 changed files with 200 additions and 30 deletions
+177 -22
View File
@@ -12,6 +12,14 @@
#define OFFSET_ADDRESS_RELATIVE (90)
#define OFFSET_MEMORY (450)
enum {
ID_WRITE_U8 = wxID_HIGHEST + 1,
ID_WRITE_U16,
ID_WRITE_U32,
ID_WRITE_FLOAT,
ID_WRITE_STRING
};
DumpCtrl::DumpCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, const wxSize& size, long style)
: TextList(parent, id, pos, size, style)
{
@@ -28,6 +36,8 @@ DumpCtrl::DumpCtrl(wxWindow* parent, const wxWindowID& id, const wxPoint& pos, c
m_memoryRegion.size = 0x1000;
Init();
}
Bind(wxEVT_MENU, &DumpCtrl::OnMenuSelected, this);
}
void DumpCtrl::Init()
@@ -163,31 +173,36 @@ void DumpCtrl::OnMouseMove(const wxPoint& start_position, uint32 line)
position.x -= OFFSET_MEMORY;
}
uint32 DumpCtrl::PositionToAddress(const wxPoint& position, uint32 line)
{
wxPoint pos = position;
if (pos.x <= OFFSET_ADDRESS + OFFSET_ADDRESS_RELATIVE)
return MPTR_NULL;
pos.x -= OFFSET_ADDRESS + OFFSET_ADDRESS_RELATIVE;
if (pos.x > OFFSET_MEMORY)
return MPTR_NULL;
const uint32 byteIndex = (pos.x / m_char_width) / 3;
return LineToOffset(line) + byteIndex;
}
void DumpCtrl::OnMouseDClick(const wxPoint& position, uint32 line)
{
wxPoint pos = position;
if (pos.x <= OFFSET_ADDRESS + OFFSET_ADDRESS_RELATIVE)
uint32 address = PositionToAddress(position, line);
if (address == MPTR_NULL)
return;
pos.x -= OFFSET_ADDRESS + OFFSET_ADDRESS_RELATIVE;
if(pos.x <= OFFSET_MEMORY)
if (!memory_isAddressRangeAccessible(address, 1))
return;
if (WriteNumericDialog<uint8>(address))
{
const uint32 byte_index = (pos.x / m_char_width) / 3;
const uint32 offset = LineToOffset(line) + byte_index;
if (!memory_isAddressRangeAccessible(offset, 1))
return;
const uint8 value = memory_readU8(offset);
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set byte at address %08x"), offset), wxString::Format("%02x", value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const uint8 new_value = std::stoul(set_value_dialog.GetValue().ToStdString(), nullptr, 16);
memory_writeU8(offset, new_value);
wxRect update_rect(0, line * m_line_height, GetSize().x, m_line_height);
RefreshControl(&update_rect);
}
return;
wxRect updateRect(0, line * m_line_height, GetSize().x, m_line_height);
RefreshControl(&updateRect);
}
}
@@ -264,7 +279,6 @@ uint32 DumpCtrl::OffsetToLine(uint32 offset)
return (offset - m_memoryRegion.baseAddress) / 0x10;
}
void DumpCtrl::OnKeyPressed(sint32 key_code, const wxPoint& position)
{
switch (key_code)
@@ -284,3 +298,144 @@ wxSize DumpCtrl::DoGetBestSize() const
{
return TextList::DoGetBestSize();
}
void DumpCtrl::OnContextMenu(const wxPoint& position, uint32 line)
{
const uint32 address = PositionToAddress(position, line);
if (!memory_isAddressRangeAccessible(address, 1))
return;
m_writerContextAddress = address;
m_writerContextLine = line;
wxMenu menu;
menu.Append(ID_WRITE_U8, _("Write Byte"));
menu.Append(ID_WRITE_U16, _("Write Int16"));
menu.Append(ID_WRITE_U32, _("Write Int32"));
menu.Append(ID_WRITE_FLOAT, _("Write Float"));
menu.Append(ID_WRITE_STRING, _("Write String"));
PopupMenu(&menu);
}
void DumpCtrl::OnMenuSelected(wxCommandEvent& event)
{
bool update = false;
switch (event.GetId())
{
case ID_WRITE_U8:
update = WriteNumericDialog<uint8>(m_writerContextAddress);
break;
case ID_WRITE_U16:
update = WriteNumericDialog<uint16>(m_writerContextAddress);
break;
case ID_WRITE_U32:
update = WriteNumericDialog<uint32>(m_writerContextAddress);
break;
case ID_WRITE_FLOAT:
update = WriteNumericDialog<float>(m_writerContextAddress);
break;
case ID_WRITE_STRING:
update = WriteString(m_writerContextAddress);
break;
}
if (update)
{
wxRect updateRect(0, m_writerContextLine * m_line_height, GetSize().x, m_line_height);
RefreshControl(&updateRect);
}
}
template <typename T>
bool DumpCtrl::WriteNumericDialog(uint32 address)
{
static_assert(
std::is_same<T, uint8>::value ||
std::is_same<T, uint16>::value ||
std::is_same<T, uint32>::value ||
std::is_same<T, float>::value,
"Unsupported type"
);
T value;
const char* dataType;
wxString label;
if constexpr (std::is_same<T, uint8>::value)
{
value = memory_readU8(address);
dataType = "byte";
label = wxString::Format("0x%02x", value);
}
else if constexpr (std::is_same<T, uint16>::value)
{
value = memory_readU16(address);
dataType = "int16";
label = wxString::Format("0x%04x", value);
}
else if constexpr (std::is_same<T, uint32>::value)
{
value = memory_readU32(address);
dataType = "int32";
label = wxString::Format("0x%08x", value);
}
else if constexpr (std::is_same<T, float>::value)
{
value = memory_readFloat(address);
dataType = "float";
label = wxString::Format("%f", value);
}
wxTextEntryDialog dialog(
this,
_("Enter a new value."),
wxString::Format(_("Write %s at address 0x%08x"), dataType, address),
label
);
if (dialog.ShowModal() != wxID_OK)
return false;
const T newValue = ConvertString<T>(dialog.GetValue().ToStdString());
if constexpr (std::is_same<T, uint8>::value)
memory_writeU8(address, newValue);
else if constexpr (std::is_same<T, uint16>::value)
memory_writeU16(address, newValue);
else if constexpr (std::is_same<T, uint32>::value)
memory_writeU32(address, newValue);
else if constexpr (std::is_same<T, float>::value)
memory_writeFloat(address, newValue);
return true;
}
bool DumpCtrl::WriteString(uint32 address)
{
wxTextEntryDialog dialog(
this,
_("Enter string"),
wxString::Format(_("Write string at address 0x%08x"), address),
""
);
if (dialog.ShowModal() != wxID_OK)
return false;
std::string text = dialog.GetValue().ToStdString();
if (text.empty())
return false;
for (size_t i = 0; i < text.size(); i++)
memory_writeU8(address + i, static_cast<uint8>(text[i]));
// null-terminator
memory_writeU8(address + text.size(), 0);
return true;
}
+9 -1
View File
@@ -1,7 +1,6 @@
#pragma once
#include "wxgui/components/TextList.h"
class DumpCtrl : public TextList
{
public:
@@ -15,11 +14,18 @@ protected:
void CenterOffset(uint32 offset);
uint32 LineToOffset(uint32 line);
uint32 OffsetToLine(uint32 offset);
uint32 PositionToAddress(const wxPoint& position, uint32 line);
void OnDraw(wxDC& dc, sint32 start, sint32 count, const wxPoint& start_position) override;
void OnMouseMove(const wxPoint& position, uint32 line) override;
void OnMouseDClick(const wxPoint& position, uint32 line) override;
void OnKeyPressed(sint32 key_code, const wxPoint& position) override;
void OnContextMenu(const wxPoint& position, uint32 line) override;
void OnMenuSelected(wxCommandEvent& event);
template <typename T>
bool WriteNumericDialog(uint32 address);
bool WriteString(uint32 address);
private:
struct
{
@@ -27,4 +33,6 @@ private:
uint32 size;
}m_memoryRegion;
uint32 m_lastGotoOffset{0};
uint32 m_writerContextAddress {0};
uint32 m_writerContextLine {0};
};
+14 -7
View File
@@ -8,6 +8,7 @@
#include "Cafe/OS/RPL/rpl.h"
#include "Cafe/OS/RPL/rpl_structs.h"
#include "Cafe/HW/Espresso/EspressoISA.h"
#include "util/helpers/helpers.h"
enum
{
@@ -355,15 +356,17 @@ void RegisterWindow::OnMouseDClickEvent(wxMouseEvent& event)
{
const uint32 register_index = id - kRegisterValueR0;
const uint32 register_value = ppcSnapshot.gpr[register_index];
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set R%d value"), register_index), wxString::Format("%08x", register_value));
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set R%d value"), register_index), wxString::Format("0x%08x", register_value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const uint32 new_value = std::stoul(set_value_dialog.GetValue().ToStdString(), nullptr, 16);
const uint32 value = ConvertString<uint32>(set_value_dialog.GetValue().ToStdString());
if (debugSession = debugger_lockDebugSession(); debugSession)
{
debugSession->gpr[register_index] = new_value;
debugSession->gpr[register_index] = value;
debugger_unlockDebugSession(debugSession);
}
OnUpdateView();
}
return;
@@ -376,12 +379,14 @@ void RegisterWindow::OnMouseDClickEvent(wxMouseEvent& event)
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set FP0_%d value"), register_index), wxString::Format("%lf", register_value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const double new_value = std::stod(set_value_dialog.GetValue().ToStdString());
const double value = ConvertString<double>(set_value_dialog.GetValue().ToStdString());
if (debugSession = debugger_lockDebugSession(); debugSession)
{
debugSession->fpr[register_index].fp0 = new_value;
debugSession->fpr[register_index].fp0 = value;
debugger_unlockDebugSession(debugSession);
}
OnUpdateView();
}
@@ -395,12 +400,14 @@ void RegisterWindow::OnMouseDClickEvent(wxMouseEvent& event)
wxTextEntryDialog set_value_dialog(this, _("Enter a new value."), wxString::Format(_("Set FP1_%d value"), register_index), wxString::Format("%lf", register_value));
if (set_value_dialog.ShowModal() == wxID_OK)
{
const double new_value = std::stod(set_value_dialog.GetValue().ToStdString());
const double value = ConvertString<double>(set_value_dialog.GetValue().ToStdString());
if (debugSession = debugger_lockDebugSession(); debugSession)
{
debugSession->fpr[register_index].fp1 = new_value;
debugSession->fpr[register_index].fp1 = value;
debugger_unlockDebugSession(debugSession);
}
OnUpdateView();
}
return;