2015-05-24 04:55:12 +00:00
|
|
|
// Copyright 2008 Dolphin Emulator Project
|
2015-05-17 23:08:10 +00:00
|
|
|
// Licensed under GPLv2+
|
2013-04-18 03:43:35 +00:00
|
|
|
// Refer to the license.txt file included.
|
2008-12-08 05:30:24 +00:00
|
|
|
|
2016-12-23 19:18:14 +00:00
|
|
|
#include "DolphinWX/Debugger/MemoryCheckDlg.h"
|
|
|
|
|
2014-02-22 22:36:30 +00:00
|
|
|
#include <string>
|
2016-09-16 22:08:16 +00:00
|
|
|
#include <wx/radiobut.h>
|
2014-02-22 22:36:30 +00:00
|
|
|
#include <wx/sizer.h>
|
|
|
|
#include <wx/stattext.h>
|
|
|
|
#include <wx/textctrl.h>
|
|
|
|
|
2014-09-08 01:06:58 +00:00
|
|
|
#include "Common/CommonTypes.h"
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "Common/StringUtil.h"
|
2016-12-23 19:18:14 +00:00
|
|
|
#include "Core/PowerPC/BreakPoints.h"
|
2014-02-17 10:18:15 +00:00
|
|
|
#include "Core/PowerPC/PowerPC.h"
|
|
|
|
#include "DolphinWX/Debugger/BreakpointWindow.h"
|
2016-06-24 08:43:46 +00:00
|
|
|
#include "DolphinWX/WxUtils.h"
|
2008-12-08 05:30:24 +00:00
|
|
|
|
2017-01-02 20:39:02 +00:00
|
|
|
MemoryCheckDlg::MemoryCheckDlg(wxWindow* parent)
|
|
|
|
: wxDialog(parent, wxID_ANY, _("Add a Memory Breakpoint"))
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2016-06-24 08:43:46 +00:00
|
|
|
Bind(wxEVT_BUTTON, &MemoryCheckDlg::OnOK, this, wxID_OK);
|
2016-09-16 22:08:16 +00:00
|
|
|
Bind(wxEVT_RADIOBUTTON, &MemoryCheckDlg::OnRadioButtonClick, this);
|
|
|
|
|
2016-10-03 07:29:50 +00:00
|
|
|
const int space5 = FromDIP(5);
|
|
|
|
|
2016-09-16 22:08:16 +00:00
|
|
|
m_textAddress = new wxStaticText(this, wxID_ANY, _("Address"));
|
|
|
|
m_textStartAddress = new wxStaticText(this, wxID_ANY, _("Start"));
|
|
|
|
m_textStartAddress->Disable();
|
|
|
|
m_textEndAddress = new wxStaticText(this, wxID_ANY, _("End"));
|
|
|
|
m_textEndAddress->Disable();
|
|
|
|
m_pEditAddress = new wxTextCtrl(this, wxID_ANY);
|
|
|
|
m_pEditStartAddress = new wxTextCtrl(this, wxID_ANY);
|
|
|
|
m_pEditStartAddress->Disable();
|
|
|
|
m_pEditEndAddress = new wxTextCtrl(this, wxID_ANY);
|
|
|
|
m_pEditEndAddress->Disable();
|
|
|
|
m_radioAddress = new wxRadioButton(this, wxID_ANY, _("With an address"), wxDefaultPosition,
|
|
|
|
wxDefaultSize, wxRB_GROUP);
|
|
|
|
m_radioRange = new wxRadioButton(this, wxID_ANY, _("Within a range"));
|
2017-05-06 13:38:53 +00:00
|
|
|
// i18n: This string is used for a radio button that represents the type of
|
|
|
|
// memory breakpoint that gets triggered when a read operation occurs.
|
|
|
|
// The string does not mean "read-only" in the sense that something cannot be written to.
|
|
|
|
m_radioRead = new wxRadioButton(this, wxID_ANY, _("Read only"), wxDefaultPosition, wxDefaultSize,
|
|
|
|
wxRB_GROUP);
|
|
|
|
// i18n: This string is used for a radio button that represents the type of
|
|
|
|
// memory breakpoint that gets triggered when a write operation occurs.
|
|
|
|
// The string does not mean "write-only" in the sense that something cannot be read from.
|
|
|
|
m_radioWrite = new wxRadioButton(this, wxID_ANY, _("Write only"));
|
|
|
|
// i18n: This string is used for a radio button that represents the type of
|
|
|
|
// memory breakpoint that gets triggered when a read operation or write operation occurs.
|
|
|
|
// The string is not a command to read and write something or to allow reading and writing.
|
2016-09-16 22:08:16 +00:00
|
|
|
m_radioReadWrite = new wxRadioButton(this, wxID_ANY, _("Read and write"));
|
|
|
|
m_radioLog =
|
|
|
|
new wxRadioButton(this, wxID_ANY, _("Log"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
|
|
|
|
m_radioBreak = new wxRadioButton(this, wxID_ANY, _("Break"));
|
|
|
|
m_radioBreakLog = new wxRadioButton(this, wxID_ANY, _("Break and log"));
|
|
|
|
m_radioBreakLog->SetValue(true);
|
|
|
|
|
|
|
|
auto* sAddressBox = new wxBoxSizer(wxHORIZONTAL);
|
2016-10-03 07:29:50 +00:00
|
|
|
sAddressBox->AddSpacer(space5);
|
|
|
|
sAddressBox->Add(m_textAddress, 0, wxALIGN_CENTER_VERTICAL);
|
|
|
|
sAddressBox->AddSpacer(space5);
|
|
|
|
sAddressBox->Add(m_pEditAddress, 1, wxALIGN_CENTER_VERTICAL);
|
|
|
|
sAddressBox->AddSpacer(space5);
|
2016-09-16 22:08:16 +00:00
|
|
|
|
|
|
|
auto* sAddressRangeBox = new wxBoxSizer(wxHORIZONTAL);
|
2016-10-03 07:29:50 +00:00
|
|
|
sAddressRangeBox->AddSpacer(space5);
|
|
|
|
sAddressRangeBox->Add(m_textStartAddress, 0, wxALIGN_CENTER_VERTICAL);
|
|
|
|
sAddressRangeBox->AddSpacer(space5);
|
|
|
|
sAddressRangeBox->Add(m_pEditStartAddress, 1, wxALIGN_CENTER_VERTICAL);
|
|
|
|
sAddressRangeBox->AddSpacer(space5);
|
|
|
|
sAddressRangeBox->Add(m_textEndAddress, 0, wxALIGN_CENTER_VERTICAL);
|
|
|
|
sAddressRangeBox->AddSpacer(space5);
|
|
|
|
sAddressRangeBox->Add(m_pEditEndAddress, 1, wxALIGN_CENTER_VERTICAL);
|
|
|
|
sAddressRangeBox->AddSpacer(space5);
|
2016-09-16 22:08:16 +00:00
|
|
|
|
|
|
|
auto* sActions = new wxStaticBoxSizer(wxVERTICAL, this, _("Action"));
|
|
|
|
sActions->Add(m_radioRead, 0, wxEXPAND);
|
|
|
|
sActions->Add(m_radioWrite, 0, wxEXPAND);
|
|
|
|
sActions->Add(m_radioReadWrite, 0, wxEXPAND);
|
|
|
|
m_radioWrite->SetValue(true);
|
|
|
|
|
|
|
|
auto* sFlags = new wxStaticBoxSizer(wxVERTICAL, this, _("Flags"));
|
|
|
|
sFlags->Add(m_radioLog);
|
|
|
|
sFlags->Add(m_radioBreak);
|
|
|
|
sFlags->Add(m_radioBreakLog);
|
|
|
|
|
|
|
|
auto* sOptionsBox = new wxBoxSizer(wxHORIZONTAL);
|
2016-10-03 07:29:50 +00:00
|
|
|
sOptionsBox->Add(sActions, 1, wxEXPAND, space5);
|
|
|
|
sOptionsBox->Add(sFlags, 1, wxEXPAND | wxLEFT, space5);
|
2016-09-16 22:08:16 +00:00
|
|
|
|
|
|
|
auto* sControls = new wxBoxSizer(wxVERTICAL);
|
|
|
|
sControls->Add(m_radioAddress, 0, wxEXPAND);
|
2016-10-03 07:29:50 +00:00
|
|
|
sControls->AddSpacer(5);
|
2016-09-16 22:08:16 +00:00
|
|
|
sControls->Add(sAddressBox, 0, wxEXPAND);
|
2016-10-03 07:29:50 +00:00
|
|
|
sControls->AddSpacer(5);
|
2016-09-16 22:08:16 +00:00
|
|
|
sControls->Add(m_radioRange, 0, wxEXPAND);
|
2016-10-03 07:29:50 +00:00
|
|
|
sControls->AddSpacer(5);
|
2016-06-24 08:43:46 +00:00
|
|
|
sControls->Add(sAddressRangeBox, 0, wxEXPAND);
|
2016-10-03 07:29:50 +00:00
|
|
|
sControls->AddSpacer(5);
|
2016-09-16 22:08:16 +00:00
|
|
|
sControls->Add(sOptionsBox, 0, wxEXPAND);
|
2016-06-24 08:43:46 +00:00
|
|
|
|
2016-09-16 22:08:16 +00:00
|
|
|
auto* sMainSizer = new wxBoxSizer(wxVERTICAL);
|
2016-10-03 07:29:50 +00:00
|
|
|
sMainSizer->AddSpacer(space5);
|
|
|
|
sMainSizer->Add(sControls, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
|
|
|
sMainSizer->AddSpacer(space5);
|
|
|
|
sMainSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
|
|
|
|
sMainSizer->AddSpacer(space5);
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
SetSizerAndFit(sMainSizer);
|
|
|
|
SetFocus();
|
2016-09-16 22:08:16 +00:00
|
|
|
m_pEditAddress->SetFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MemoryCheckDlg::OnRadioButtonClick(wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
if (m_radioAddress->GetValue())
|
|
|
|
{
|
|
|
|
m_pEditAddress->Enable();
|
|
|
|
m_textAddress->Enable();
|
|
|
|
m_pEditStartAddress->Disable();
|
|
|
|
m_pEditEndAddress->Disable();
|
|
|
|
m_textStartAddress->Disable();
|
|
|
|
m_textEndAddress->Disable();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_pEditStartAddress->Enable();
|
|
|
|
m_textStartAddress->Enable();
|
|
|
|
m_textEndAddress->Enable();
|
|
|
|
m_pEditEndAddress->Enable();
|
|
|
|
m_pEditAddress->Disable();
|
|
|
|
m_textAddress->Disable();
|
|
|
|
}
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|
|
|
|
|
2011-03-17 04:26:01 +00:00
|
|
|
void MemoryCheckDlg::OnOK(wxCommandEvent& event)
|
2008-12-08 05:30:24 +00:00
|
|
|
{
|
2016-09-16 22:08:16 +00:00
|
|
|
wxString StartAddressString;
|
|
|
|
wxString EndAddressString;
|
|
|
|
if (m_radioAddress->GetValue())
|
|
|
|
{
|
|
|
|
StartAddressString = m_pEditAddress->GetLineText(0);
|
|
|
|
EndAddressString = m_pEditAddress->GetLineText(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
StartAddressString = m_pEditStartAddress->GetLineText(0);
|
|
|
|
EndAddressString = m_pEditEndAddress->GetLineText(0);
|
|
|
|
}
|
|
|
|
bool OnRead = m_radioRead->GetValue() || m_radioReadWrite->GetValue();
|
|
|
|
bool OnWrite = m_radioWrite->GetValue() || m_radioReadWrite->GetValue();
|
|
|
|
bool Log = m_radioLog->GetValue() || m_radioBreakLog->GetValue();
|
|
|
|
bool Break = m_radioBreak->GetValue() || m_radioBreakLog->GetValue();
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
u32 StartAddress, EndAddress;
|
|
|
|
bool EndAddressOK =
|
|
|
|
EndAddressString.Len() && AsciiToHex(WxStrToStr(EndAddressString), EndAddress);
|
|
|
|
|
|
|
|
if (AsciiToHex(WxStrToStr(StartAddressString), StartAddress) && (OnRead || OnWrite) &&
|
|
|
|
(Log || Break))
|
|
|
|
{
|
|
|
|
TMemCheck MemCheck;
|
|
|
|
|
|
|
|
if (!EndAddressOK)
|
|
|
|
EndAddress = StartAddress;
|
|
|
|
|
2017-01-11 13:27:45 +00:00
|
|
|
MemCheck.start_address = StartAddress;
|
|
|
|
MemCheck.end_address = EndAddress;
|
|
|
|
MemCheck.is_ranged = StartAddress != EndAddress;
|
|
|
|
MemCheck.is_break_on_read = OnRead;
|
|
|
|
MemCheck.is_break_on_write = OnWrite;
|
|
|
|
MemCheck.log_on_hit = Log;
|
|
|
|
MemCheck.break_on_hit = Break;
|
2016-06-24 08:43:46 +00:00
|
|
|
|
|
|
|
PowerPC::memchecks.Add(MemCheck);
|
2017-01-02 20:39:02 +00:00
|
|
|
EndModal(wxID_OK);
|
2016-06-24 08:43:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
event.Skip();
|
2008-12-08 05:30:24 +00:00
|
|
|
}
|