- removed wx debugger dialogs (enhanced gui debugger now almost stable with wx)

This commit is contained in:
Volker Ruppert 2013-02-16 12:22:13 +00:00
parent a6bce2031c
commit 058c0e05fb
8 changed files with 1 additions and 996 deletions

View File

@ -291,8 +291,5 @@ menu
bochs
(subtree containing Bochs state)
wxdebug
(special subtree for wxBochs debugger)
user
(subtree for user-defined options)

View File

@ -1423,9 +1423,6 @@ public: // for now...
void initialize(void);
void after_restore_state(void);
void register_state(void);
#if BX_WITH_WX && !BX_DEBUGGER_GUI
void register_wx_state(void);
#endif
static Bit64s param_save_handler(void *devptr, bx_param_c *param);
static void param_restore_handler(void *devptr, bx_param_c *param, Bit64s val);
#if !BX_USE_CPU_SMF

View File

@ -57,108 +57,6 @@ BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id)
srand(time(NULL)); // initialize random generator for RDRAND/RDSEED
}
#if BX_WITH_WX && !BX_DEBUGGER_GUI
#define IF_SEG_REG_GET(x) \
if (!strcmp(param->get_name(), #x)) { \
return BX_CPU(cpu)->sregs[BX_SEG_REG_##x].selector.value; \
}
#define IF_SEG_REG_SET(reg, val) \
if (!strcmp(param->get_name(), #reg)) { \
BX_CPU(cpu)->load_seg_reg(&BX_CPU(cpu)->sregs[BX_SEG_REG_##reg],val); \
}
#define IF_LAZY_EFLAG_GET(flag) \
if (!strcmp(param->get_name(), #flag)) { \
return BX_CPU(cpu)->get_##flag(); \
}
#define IF_LAZY_EFLAG_SET(flag, val) \
if (!strcmp(param->get_name(), #flag)) { \
BX_CPU(cpu)->set_##flag(val); \
}
#define IF_EFLAG_GET(flag) \
if (!strcmp(param->get_name(), #flag)) { \
return BX_CPU(cpu)->get_##flag(); \
}
#define IF_EFLAG_SET(flag, val) \
if (!strcmp(param->get_name(), #flag)) { \
BX_CPU(cpu)->set_##flag(val); \
}
// implement get/set handler for parameters that need unusual set/get
static Bit64s cpu_param_handler(bx_param_c *param, int set, Bit64s val)
{
#if BX_SUPPORT_SMP
int cpu = atoi(param->get_parent()->get_name());
#endif
if (set) {
if (!strcmp(param->get_name(), "LDTR")) {
BX_CPU(cpu)->panic("setting LDTR not implemented");
}
if (!strcmp(param->get_name(), "TR")) {
BX_CPU(cpu)->panic("setting LDTR not implemented");
}
IF_SEG_REG_SET(CS, val);
IF_SEG_REG_SET(DS, val);
IF_SEG_REG_SET(SS, val);
IF_SEG_REG_SET(ES, val);
IF_SEG_REG_SET(FS, val);
IF_SEG_REG_SET(GS, val);
IF_LAZY_EFLAG_SET(OF, val);
IF_LAZY_EFLAG_SET(SF, val);
IF_LAZY_EFLAG_SET(ZF, val);
IF_LAZY_EFLAG_SET(AF, val);
IF_LAZY_EFLAG_SET(PF, val);
IF_LAZY_EFLAG_SET(CF, val);
IF_EFLAG_SET(ID, val);
IF_EFLAG_SET(VIP, val);
IF_EFLAG_SET(VIF, val);
IF_EFLAG_SET(AC, val);
IF_EFLAG_SET(VM, val);
IF_EFLAG_SET(RF, val);
IF_EFLAG_SET(NT, val);
IF_EFLAG_SET(IOPL, val);
IF_EFLAG_SET(DF, val);
IF_EFLAG_SET(IF, val);
IF_EFLAG_SET(TF, val);
} else {
if (!strcmp(param->get_name(), "LDTR")) {
return BX_CPU(cpu)->ldtr.selector.value;
}
if (!strcmp(param->get_name(), "TR")) {
return BX_CPU(cpu)->tr.selector.value;
}
IF_SEG_REG_GET (CS);
IF_SEG_REG_GET (DS);
IF_SEG_REG_GET (SS);
IF_SEG_REG_GET (ES);
IF_SEG_REG_GET (FS);
IF_SEG_REG_GET (GS);
IF_LAZY_EFLAG_GET(OF);
IF_LAZY_EFLAG_GET(SF);
IF_LAZY_EFLAG_GET(ZF);
IF_LAZY_EFLAG_GET(AF);
IF_LAZY_EFLAG_GET(PF);
IF_LAZY_EFLAG_GET(CF);
IF_EFLAG_GET(ID);
IF_EFLAG_GET(VIP);
IF_EFLAG_GET(VIF);
IF_EFLAG_GET(AC);
IF_EFLAG_GET(VM);
IF_EFLAG_GET(RF);
IF_EFLAG_GET(NT);
IF_EFLAG_GET(IOPL);
IF_EFLAG_GET(DF);
IF_EFLAG_GET(IF);
IF_EFLAG_GET(TF);
}
return val;
}
#undef IF_SEG_REG_GET
#undef IF_SEG_REG_SET
#endif
#if BX_CPU_LEVEL >= 4
#include "generic_cpuid.h"
@ -226,137 +124,8 @@ void BX_CPU_C::initialize(void)
#if BX_SUPPORT_VMX
init_VMCS();
#endif
#if BX_WITH_WX && !BX_DEBUGGER_GUI
register_wx_state();
#endif
}
#if BX_WITH_WX && !BX_DEBUGGER_GUI
void BX_CPU_C::register_wx_state(void)
{
if (SIM->get_param(BXPN_WX_CPU_STATE) != NULL) {
// Register some of the CPUs variables as shadow parameters so that
// they can be visible in the config interface.
// (Experimental, obviously not a complete list)
bx_param_num_c *param;
char cpu_name[10], cpu_title[10], cpu_pname[16];
const char *fmt16 = "%04X";
const char *fmt32 = "%08X";
Bit32u oldbase = bx_param_num_c::set_default_base(16);
const char *oldfmt = bx_param_num_c::set_default_format(fmt32);
sprintf(cpu_name, "%d", BX_CPU_ID);
sprintf(cpu_title, "CPU %d", BX_CPU_ID);
sprintf(cpu_pname, "%s.%d", BXPN_WX_CPU_STATE, BX_CPU_ID);
if (SIM->get_param(cpu_pname) == NULL) {
bx_list_c *list = new bx_list_c(SIM->get_param(BXPN_WX_CPU_STATE),
cpu_name, cpu_title);
#define DEFPARAM_NORMAL(name,field) \
new bx_shadow_num_c(list, #name, &(field))
DEFPARAM_NORMAL(EAX, EAX);
DEFPARAM_NORMAL(EBX, EBX);
DEFPARAM_NORMAL(ECX, ECX);
DEFPARAM_NORMAL(EDX, EDX);
DEFPARAM_NORMAL(ESP, ESP);
DEFPARAM_NORMAL(EBP, EBP);
DEFPARAM_NORMAL(ESI, ESI);
DEFPARAM_NORMAL(EDI, EDI);
DEFPARAM_NORMAL(EIP, EIP);
DEFPARAM_NORMAL(DR0, dr[0]);
DEFPARAM_NORMAL(DR1, dr[1]);
DEFPARAM_NORMAL(DR2, dr[2]);
DEFPARAM_NORMAL(DR3, dr[3]);
DEFPARAM_NORMAL(DR6, dr6.val32);
DEFPARAM_NORMAL(DR7, dr7.val32);
DEFPARAM_NORMAL(CR0, cr0.val32);
DEFPARAM_NORMAL(CR2, cr2);
DEFPARAM_NORMAL(CR3, cr3);
#if BX_CPU_LEVEL >= 5
DEFPARAM_NORMAL(CR4, cr4.val32);
#endif
// segment registers require a handler function because they have
// special get/set requirements.
#define DEFPARAM_SEG_REG(x) \
param = new bx_param_num_c(list, \
#x, #x, "", 0, 0xffff, 0); \
param->set_handler(cpu_param_handler); \
param->set_format(fmt16);
#define DEFPARAM_GLOBAL_SEG_REG(name,field) \
param = new bx_shadow_num_c(list, \
#name"_base", &(field.base)); \
param = new bx_shadow_num_c(list, \
#name"_limit", &(field.limit));
DEFPARAM_SEG_REG(CS);
DEFPARAM_SEG_REG(DS);
DEFPARAM_SEG_REG(SS);
DEFPARAM_SEG_REG(ES);
DEFPARAM_SEG_REG(FS);
DEFPARAM_SEG_REG(GS);
DEFPARAM_SEG_REG(LDTR);
DEFPARAM_SEG_REG(TR);
DEFPARAM_GLOBAL_SEG_REG(GDTR, BX_CPU_THIS_PTR gdtr);
DEFPARAM_GLOBAL_SEG_REG(IDTR, BX_CPU_THIS_PTR idtr);
#undef DEFPARAM_NORMAL
#undef DEFPARAM_SEG_REG
#undef DEFPARAM_GLOBAL_SEG_REG
param = new bx_shadow_num_c(list, "EFLAGS",
&BX_CPU_THIS_PTR eflags);
// flags implemented in lazy_flags.cc must be done with a handler
// that calls their get function, to force them to be computed.
#define DEFPARAM_EFLAG(name) \
param = new bx_param_bool_c(list, \
#name, #name, "", get_##name()); \
param->set_handler(cpu_param_handler);
#define DEFPARAM_LAZY_EFLAG(name) \
param = new bx_param_bool_c(list, \
#name, #name, "", get_##name()); \
param->set_handler(cpu_param_handler);
#if BX_CPU_LEVEL >= 4
DEFPARAM_EFLAG(ID);
DEFPARAM_EFLAG(VIP);
DEFPARAM_EFLAG(VIF);
DEFPARAM_EFLAG(AC);
#endif
#if BX_CPU_LEVEL >= 3
DEFPARAM_EFLAG(VM);
DEFPARAM_EFLAG(RF);
#endif
#if BX_CPU_LEVEL >= 2
DEFPARAM_EFLAG(NT);
// IOPL is a special case because it is 2 bits wide.
param = new bx_shadow_num_c(
list,
"IOPL",
&BX_CPU_THIS_PTR eflags, 10,
12, 13);
param->set_range(0, 3);
param->set_format("%d");
#endif
DEFPARAM_LAZY_EFLAG(OF);
DEFPARAM_EFLAG(DF);
DEFPARAM_EFLAG(IF);
DEFPARAM_EFLAG(TF);
DEFPARAM_LAZY_EFLAG(SF);
DEFPARAM_LAZY_EFLAG(ZF);
DEFPARAM_LAZY_EFLAG(AF);
DEFPARAM_LAZY_EFLAG(PF);
DEFPARAM_LAZY_EFLAG(CF);
// restore defaults
bx_param_num_c::set_default_base(oldbase);
bx_param_num_c::set_default_format(oldfmt);
}
}
}
#endif
// save/restore functionality
void BX_CPU_C::register_state(void)
{

View File

@ -400,158 +400,6 @@ void AdvancedLogOptionsDialog::ShowHelp()
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this);
}
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
//////////////////////////////////////////////////////////////////////
// DebugLogDialog implementation
//////////////////////////////////////////////////////////////////////
// Structure:
// mainSizer:
// wxTextCtrl log (multiline with vert scrollbar)
// "Type a debugger command"
// commandSizer:
// wxTextCtrl command
// Execute button
// buttonSizer:
// help
// cancel
// ok
//
// all events go to OnEvent method
BEGIN_EVENT_TABLE(DebugLogDialog, wxDialog)
EVT_BUTTON(-1, DebugLogDialog::OnEvent)
EVT_CHECKBOX(-1, DebugLogDialog::OnEvent)
EVT_KEY_DOWN(DebugLogDialog::OnKeyEvent)
EVT_KEY_UP(DebugLogDialog::OnKeyEvent)
EVT_CHAR(DebugLogDialog::OnKeyEvent)
EVT_TEXT(-1, DebugLogDialog::OnEvent)
EVT_TEXT_ENTER(-1, DebugLogDialog::OnEnterEvent)
END_EVENT_TABLE()
DebugLogDialog::DebugLogDialog(
wxWindow* parent,
wxWindowID id)
: wxDialog (parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
lengthMax = DEBUG_LOG_DEFAULT_LENGTH_MAX;
lengthTolerance = DEBUG_LOG_DEFAULT_TOLERANCE;
SetTitle (DEBUG_LOG_TITLE);
mainSizer = new wxBoxSizer (wxVERTICAL);
log = new wxTextCtrl (this, -1, wxT(""),
wxDefaultPosition, wxSize(400, 300),
wxTE_MULTILINE | wxTE_RICH | wxTE_READONLY);
mainSizer->Add (log, 1, wxALL|wxGROW, 10);
wxStaticText *text = new wxStaticText (this, -1, DEBUG_CMD_PROMPT);
mainSizer->Add (text, 0, wxTOP|wxLEFT, 10);
commandSizer = new wxBoxSizer (wxHORIZONTAL);
mainSizer->Add (commandSizer, 0, wxALL|wxGROW, 5);
buttonSizer = new wxBoxSizer (wxHORIZONTAL);
mainSizer->Add (buttonSizer, 0, wxALIGN_RIGHT);
// commandSizer contents
command = new wxTextCtrl (this, ID_DebugCommand, wxT(""),
wxDefaultPosition, wxDefaultSize,
wxTE_PROCESS_ENTER);
commandSizer->Add (command, 1, wxGROW);
wxButton *btn;
btn = new wxButton (this, ID_Execute, BTNLABEL_EXECUTE);
commandSizer->Add (btn, 0, wxALL, 5);
// buttonSizer contents
btn = new wxButton (this, wxID_OK, BTNLABEL_CLOSE);
buttonSizer->Add (btn, 0, wxALL, 5);
}
void DebugLogDialog::Init()
{
// lay it out!
SetAutoLayout(TRUE);
SetSizer(mainSizer);
mainSizer->Fit(this);
wxSize size = mainSizer->GetMinSize();
int margin = 5;
SetSizeHints(size.GetWidth() + margin, size.GetHeight() + margin);
Center();
}
void DebugLogDialog::Execute(bool clear)
{
// send to debugger
theFrame->DebugCommand (command->GetValue ());
// display what they typed on the log screen
if (clear) command->Clear ();
}
void DebugLogDialog::CheckLogLength ()
{
// truncate the text control periodically to avoid a
// serious memory leak.
wxString str = log->GetValue ();
Bit32u len = str.Length ();
if (len > lengthMax + lengthTolerance) {
// Truncate the string. Start from length - lengthMax, search
// forward until we find the first \n.
for (int i = len - lengthMax; i<(int)(len-1); i++) {
if (str.GetChar (i) == '\n') {
// remove the \n and everything before it. Done.
//printf ("truncating from 0 to %d\n", i+1);
//printf ("\n");
log->Remove (0, i+1);
return;
}
}
// no newline found?!
//printf ("no newline found! truncating from 0 to %d", len - lengthMax);
//printf ("\n");
log->Remove (0, len - lengthMax);
} else {
//printf ("log length is %d, no truncation yet", len);
//printf ("\n");
}
}
void DebugLogDialog::AppendCommand (const char *cmd)
{
log->AppendText(wxT(">>> "));
log->AppendText(wxString(cmd, wxConvUTF8));
log->AppendText(wxT("\n"));
int n = log->GetLastPosition();
if (n>0) n--;
log->ShowPosition(n);
CheckLogLength();
}
void DebugLogDialog::AppendText (wxString text) {
log->AppendText (text);
int n = log->GetLastPosition ();
if (n>0) n--;
log->ShowPosition (n);
CheckLogLength ();
}
void DebugLogDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId();
switch (id) {
case wxID_OK:
Show(FALSE);
break;
case ID_Execute: // pressed execute button
Execute(false);
break;
default:
event.Skip();
}
}
void DebugLogDialog::OnKeyEvent(wxKeyEvent& event)
{
wxLogDebug(wxT("key event"));
}
#endif
//////////////////////////////////////////////////////////////////////
// PluginControlDialog implementation
//////////////////////////////////////////////////////////////////////
@ -1289,232 +1137,6 @@ void ParamDialog::ShowHelp()
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this);
}
/////////////////////////////////////////////////////////////////
// CpuRegistersDialog
/////////////////////////////////////////////////////////////////
// Structure:
// - mainSizer
// - mainRegsSizer (grid or flexgrid)
// - col0: flexgrid
// - params from EAX to ESP
// - col1: flexgrid
// - params from EIP to EFLAGS
// - col2: flexgrid
// - params from LDTR to IDTR limit
// - flagsSizer
// - extRegsSizer
// - col0: flexgrid
// - DR* params
// - col1: flexgrid
// - TR* params
// - col2: flexgrid
// - CR* params
#if !BX_DEBUGGER_GUI
// all events go to OnEvent method
BEGIN_EVENT_TABLE(CpuRegistersDialog, wxDialog)
EVT_BUTTON(-1, CpuRegistersDialog::OnEvent)
EVT_CHECKBOX(-1, CpuRegistersDialog::OnEvent)
EVT_TEXT(-1, CpuRegistersDialog::OnEvent)
END_EVENT_TABLE()
CpuRegistersDialog::CpuRegistersDialog(
wxWindow* parent,
wxWindowID id)
: ParamDialog(parent, id)
{
wxFlexGridSizer *column;
nflags = 0;
const char *mainRegList1[] = CPU_REGS_MAIN_REGS1;
const char *mainRegList2[] = CPU_REGS_MAIN_REGS2;
const char *mainRegList3[] = CPU_REGS_MAIN_REGS3;
const char *flagList[] = CPU_REGS_FLAGS;
const char *controlList[] = CPU_REGS_CONTROL_REGS;
const char *debugList[] = CPU_REGS_DEBUG_REGS;
const char *testList[] = CPU_REGS_TEST_REGS;
bx_list_c *base = (bx_list_c*)SIM->get_param(BXPN_WX_CPU0_STATE);
// top level objects
wxStaticBox *mainRegsBox = new wxStaticBox(this, -1, wxT("Basic Registers"));
wxStaticBoxSizer *mainRegsBoxSizer =
new wxStaticBoxSizer(mainRegsBox, wxVERTICAL);
mainSizer->Add(mainRegsBoxSizer, 0, wxALL|wxGROW, 10);
wxStaticBox *flagsBox = new wxStaticBox(this, -1, wxT("EFLAGS Bits"));
wxStaticBoxSizer *flagsBoxSizer =
new wxStaticBoxSizer(flagsBox, wxVERTICAL);
mainSizer->Add(flagsBoxSizer, 0, wxALL|wxGROW, 10);
wxStaticBox *otherBox = new wxStaticBox(this, -1, wxT("Other Registers"));
wxStaticBoxSizer *otherBoxSizer =
new wxStaticBoxSizer(otherBox, wxVERTICAL);
mainSizer->Add(otherBoxSizer, 0, wxALL|wxGROW, 10);
// mainRegsSizer contents
mainRegsSizer = new wxFlexGridSizer(3);
mainRegsBoxSizer->Add(mainRegsSizer, 0, wxALL, 3);
column = new wxFlexGridSizer(3);
mainRegsSizer->Add(column, 0, wxALL, 10);
AddParamList(mainRegList1, base, column);
column = new wxFlexGridSizer(3);
mainRegsSizer->Add(column, 0, wxALL, 10);
AddParamList(mainRegList2, base, column);
column = new wxFlexGridSizer(3);
mainRegsSizer->Add(column, 0, wxALL, 10);
AddParamList(mainRegList3, base, column);
// add flag parameters
flagsSizer = new wxFlexGridSizer(CPU_REGS_MAX_FLAGS);
flagsBoxSizer->Add(flagsSizer, 0, wxALL | wxALIGN_CENTER, 3);
int i = 0;
while (flagList[i] != NULL) {
bx_param_c *param = SIM->get_param(flagList[i], base);
if (param != NULL) {
AddFlag(param);
}
i++;
}
// extRegsSizer contents
extRegsSizer = new wxFlexGridSizer(3);
otherBoxSizer->Add(extRegsSizer, 0, wxALL, 3);
column = new wxFlexGridSizer(3);
extRegsSizer->Add(column, 0, wxALL, 10);
AddParamList(controlList, base, column);
column = new wxFlexGridSizer(3);
extRegsSizer->Add(column, 0, wxALL, 10);
AddParamList(debugList, base, column);
column = new wxFlexGridSizer(3);
extRegsSizer->Add(column, 0, wxALL, 10);
AddParamList(testList, base, column);
// add buttons
#if BX_DEBUGGER
// only show these if debugger is enabled
contButton = AddButton(ID_Debug_Continue, BTNLABEL_DEBUG_CONTINUE);
stopButton = AddButton(ID_Debug_Stop, BTNLABEL_DEBUG_STOP);
stepButton = AddButton(ID_Debug_Step, BTNLABEL_DEBUG_STEP);
//commitButton = AddButton(ID_Debug_Commit, BTNLABEL_DEBUG_COMMIT);
#endif
AddButton(ID_Close, BTNLABEL_CLOSE);
}
void CpuRegistersDialog::AddFlag(bx_param_c *param)
{
if (param == NULL) {
wxLogDebug(wxT("AddFlag on undefined param"));
return;
}
wxASSERT(nflags < CPU_REGS_MAX_FLAGS);
flagptr[nflags++] = param;
}
void CpuRegistersDialog::Init()
{
int i;
for (i=0; i<CPU_REGS_MAX_FLAGS; i++) {
if (i<nflags) {
bx_param_c *param = flagptr[i];
flagsSizer->Add(new wxStaticText(this, -1, wxString(param->get_label(), wxConvUTF8)), 0, wxALL|wxALIGN_LEFT, 4);
} else {
flagsSizer->Add(0, 0); // spacer
}
}
for (i=0; i<nflags; i++) {
bx_param_c *param = flagptr[i];
AddParam(param, flagsSizer, true);
}
// special case: make IOPL text field small
ParamStruct *pstr = (ParamStruct*)paramHash->Get(SIM->get_param(BXPN_WX_CPU0_EFLAGS_IOPL)->get_id());
if (pstr != NULL) {
wxSize size = pstr->u.text->GetSize();
size.SetWidth (size.GetWidth() / 2);
pstr->u.text->SetSize(size);
flagsSizer->SetItemMinSize(pstr->u.text, size.GetWidth(), size.GetHeight());
}
ParamDialog::Init();
stateChanged(false);
}
void CpuRegistersDialog::stateChanged (bool simRunning)
{
#if BX_DEBUGGER
contButton->Enable (!simRunning);
stepButton->Enable (!simRunning);
stopButton->Enable (simRunning);
#endif
}
void CpuRegistersDialog::CopyParamToGui ()
{
ParamDialog::CopyParamToGui ();
#if BX_DEBUGGER
stateChanged (SIM->get_param_bool(BXPN_DEBUG_RUNNING)->get());
#endif
}
// How am I going to communicate with the debugger?
//
// The current model is that the debugger asks you for a command, and
// blocks forever until you press return. Then it interprets the command,
// however long it takes, and returns to the input loop when the command
// is done. A control-C can stop a command prematurely.
//
// To extend this into wxWidgets multithreaded space, I will create a
// synchronous event called BX_SYNC_GET_DBG_COMMAND which is sent from
// the simulation thread to wxWidgets. When the user chooses a debugger
// action (step, continue, breakpoint, etc.) the simulation awakens and
// interprets the event by calling a function in bx_debug/dbg_main.cc.
//
// The equivalent of a control-C is pressing the "Stop" button during
// a long step or continue command. This can be implemented by setting
// bx_guard.interrupt_requested = 1, just like the SIGINT handler in
// bx_debug/dbg_main.cc does.
//
// input loop model is good. Create a debugger input loop, possibly in
// siminterface.
// in the simulation thread. This loop waits for a command from the
// wxWidgets debugger
//
// For example, if you press the "Step" button 5
// times, with each click it should call bx_dbg_stepN_command(1) in the
// simulator thread. When it returns, it goes back to
//
void CpuRegistersDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId ();
switch (id) {
case ID_Close:
Show(FALSE);
break;
#if BX_DEBUGGER
case ID_Debug_Stop:
wxLogDebug(wxT("wxWidgets triggered a break"));
theFrame->DebugBreak();
break;
case ID_Debug_Continue:
wxLogDebug(wxT("before calling DebugCommand"));
theFrame->DebugCommand("continue");
wxLogDebug(wxT("after calling DebugCommand"));
break;
case ID_Debug_Step:
theFrame->DebugCommand("step 1");
break;
case ID_Debug_Commit:
CopyGuiToParam();
break;
#endif
default:
ParamDialog::OnEvent(event);
}
}
#endif
//////////////////////////////////////////////////////////////////////
// FloppyConfigDialog implementation
//////////////////////////////////////////////////////////////////////

View File

@ -167,58 +167,6 @@ public:
DECLARE_EVENT_TABLE()
};
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
////////////////////////////////////////////////////////////////////////////
// DebugLogDialog
////////////////////////////////////////////////////////////////////////////
// DebugLogDialog allows the user to decide how Bochs will
// behave for each type of log event.
//
// +---- Debugger log ---------------------------------------+
// | |
// | +--------------------------------------------------+ |
// | |(0) f000:fff0: ea5be000f0: jmp f000:e05b | |
// | |(0) 0010:00001868: 83fb10: cmp EBX, #10 | |
// | | | |
// | | | |
// | | | |
// | | | |
// | +--------------------------------------------------+ |
// | Type a debugger command: |
// | +----------------------------------------+ +-------+ |
// | | step 1000 | |Execute| |
// | +----------------------------------------+ +-------+ |
// | |
// | [ Close ] |
// +---------------------------------------------------------+
class DebugLogDialog: public wxDialog
{
private:
#define DEBUG_LOG_TITLE wxT("Debugger log")
#define DEBUG_CMD_PROMPT wxT("Type a debugger command:")
wxBoxSizer *mainSizer, *commandSizer, *buttonSizer;
wxTextCtrl *log, *command;
Bit32u lengthMax;
Bit32u lengthTolerance;
#define DEBUG_LOG_DEFAULT_LENGTH_MAX (400*80)
#define DEBUG_LOG_DEFAULT_TOLERANCE (200*80)
public:
DebugLogDialog(wxWindow* parent, wxWindowID id);
void Init(); // called automatically by ShowModal()
void OnEvent(wxCommandEvent& event);
void OnEnterEvent(wxCommandEvent& event) { Execute(true); }
void OnKeyEvent(wxKeyEvent& event);
int ShowModal() { Init(); return wxDialog::ShowModal(); }
void Execute(bool clearCommand);
void CheckLogLength();
void AppendCommand(const char *);
void AppendText(wxString text);
void CopyParamToGui() { /* empty for now */ }
DECLARE_EVENT_TABLE()
};
#endif
////////////////////////////////////////////////////////////////////////////
// PluginControlDialog
////////////////////////////////////////////////////////////////////////////
@ -388,103 +336,6 @@ public:
DECLARE_EVENT_TABLE()
};
////////////////////////////////////////////////////////////////////////////
// CpuRegistersDialog
////////////////////////////////////////////////////////////////////////////
//
// this would display the current values of all CPU registers, possibly you can
// enable different groups like debug, FPU, MMX registers. Certainly if you
// interrupt the simulation, these would be updated. we could update
// periodically during simulation if it was useful. If we get the debugger
// integrated with wxwidgets, you could single step and update the cpu
// registers, with regs that change marked in a different color. Modeless
// dialog.
//
// +--- CPU Registers ---------------------------------------+
// | |
// | EAX 0x00000000 EIP 0xffff LDTR 0x00000000 |
// | EBX 0x00000000 CS 0x0018 TR 0x00000000 |
// | ECX 0x00000000 SS 0x0018 GDTR 0x00000000 |
// | EDX 0x00000000 DS 0x0018 lim 0x00000000 |
// | EBP 0x00000000 ES 0x0018 IDTR 0x00000000 |
// | ESI 0x00000000 FS 0x0018 lim 0x00000000 |
// | EDI 0x00000000 GS 0x0018 |
// | ESP 0x00000000 EFLAGS 0x0012 |
// | |
// | ID AC VM RF NT IOPL CF PF AF ZF SF TF IF DF OF |
// | [] [] [] [] [] [0] [] [] [] [] [] [] [] [] [] |
// | |
// | DR0 0x00000000 TR3 0x00000000 CR0 0x00000000 |
// | DR1 0x00000000 TR4 0x00000000 CR1 0x00000000 |
// | DR2 0x00000000 TR5 0x00000000 CR2 0x00000000 |
// | DR3 0x00000000 TR6 0x00000000 CR3 0x00000000 |
// | DR6 0x00000000 TR7 0x00000000 CR4 0x00000000 |
// | DR7 0x00000000 |
// | |
// | [Go] [Stop] [Step] [Step N] N=[____] |
// +---------------------------------------------------------+
//
// +--- CPU Extended Registers ------------------------------+
// | |
// | |
// | [Go] [Stop] [Step] [Step N] N=[____] |
// +---------------------------------------------------------+
//
#if !BX_DEBUGGER_GUI
class CpuRegistersDialog : public ParamDialog
{
#define CPU_REGS_MAIN_REGS1 \
{ "EAX", "EBX", "ECX", "EDX", \
"EBP", "ESI", "EDI", "ESP", \
NULL }
#define CPU_REGS_MAIN_REGS2 \
{ "EIP", "CS", "SS", "DS", \
"ES", "FS", "GS", "EFLAGS", \
NULL }
#define CPU_REGS_MAIN_REGS3 \
{ "LDTR", "TR", \
"GDTR_base", "IDTR_limit", \
"IDTR_base", "GDTR_limit", \
NULL }
#define CPU_REGS_FLAGS \
{ "ID", "VIP", "VIF", \
"AC", "VM", "RF", \
"NT", "IOPL", "OF", \
"DF", "IF", "TF", \
"SF", "ZF", "AF", \
"PF", "CF", \
NULL }
#define CPU_REGS_DEBUG_REGS \
{ "DR0", "DR1", "DR2", \
"DR3", "DR6", "DR7", \
NULL }
#define CPU_REGS_TEST_REGS \
{ "TR3", "TR4", "TR5", "TR6", "TR7", \
NULL }
#define CPU_REGS_CONTROL_REGS \
{ "CR0", "CR2", "CR3", "CR4", \
NULL }
void Init(); // called automatically by ShowModal()
wxFlexGridSizer *mainRegsSizer, *flagsSizer, *extRegsSizer;
#define CPU_REGS_MAX_FLAGS 17
bx_param_c *flagptr[CPU_REGS_MAX_FLAGS];
int nflags;
#if BX_DEBUGGER
wxButton *contButton, *stopButton, *stepButton, *commitButton;
#endif
void stateChanged(bool simRunning);
public:
CpuRegistersDialog(wxWindow* parent, wxWindowID id);
int ShowModal() { Init(); return wxDialog::ShowModal(); }
void AddFlag(bx_param_c *param);
void OnEvent(wxCommandEvent& event);
virtual void CopyParamToGui();
DECLARE_EVENT_TABLE()
};
#endif
/**************************************************************************
Everything else in here is a comment!

View File

@ -202,17 +202,6 @@ extern "C" int libwx_LTX_plugin_init(plugin_t *plugin, plugintype_t type,
wxLogDebug(wxT("installing %s as the Bochs GUI"), wxT("wxWidgets"));
SIM->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY)->set_enabled(0);
MyPanel::OnPluginInit();
#if !BX_DEBUGGER_GUI
bx_list_c *list = new bx_list_c(SIM->get_param("."),
"wxdebug",
"subtree for the wx debugger"
);
bx_list_c *cpu = new bx_list_c(list,
"cpu",
"CPU State"
);
cpu->set_options(bx_list_c::USE_TAB_WINDOW);
#endif
return 0; // success
}
@ -346,12 +335,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Edit_Other, MyFrame::OnEditOther)
EVT_MENU(ID_Log_Prefs, MyFrame::OnLogPrefs)
EVT_MENU(ID_Log_PrefsDevice, MyFrame::OnLogPrefsDevice)
#if !BX_DEBUGGER_GUI
EVT_MENU(ID_Debug_ShowCpu, MyFrame::OnShowCpu)
#if BX_DEBUGGER
EVT_MENU(ID_Debug_Console, MyFrame::OnDebugLog)
#endif
#endif
// toolbar events
EVT_TOOL(ID_Edit_FD_0, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Edit_FD_1, MyFrame::OnToolbarClick)
@ -427,11 +410,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
// init variables
sim_thread = NULL;
start_bochs_times = 0;
#if !BX_DEBUGGER_GUI
showCpu = NULL;
debugCommand = NULL;
debugCommandEvent = NULL;
#endif
// set up the gui
menuConfiguration = new wxMenu;
@ -472,14 +450,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuSimulate->Enable(ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable(ID_Simulate_Stop, FALSE);
#if !BX_DEBUGGER_GUI
menuDebug = new wxMenu;
menuDebug->Append(ID_Debug_ShowCpu, wxT("Show &CPU"));
#if BX_DEBUGGER
menuDebug->Append(ID_Debug_Console, wxT("Debug Console"));
#endif
#endif
menuLog = new wxMenu;
menuLog->Append(ID_Log_View, wxT("&View"));
menuLog->Append(ID_Log_Prefs, wxT("&Preferences..."));
@ -492,9 +462,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuBar->Append(menuConfiguration, wxT("&File"));
menuBar->Append(menuEdit, wxT("&Edit"));
menuBar->Append(menuSimulate, wxT("&Simulate"));
#if !BX_DEBUGGER_GUI
menuBar->Append(menuDebug, wxT("&Debug"));
#endif
menuBar->Append(menuLog, wxT("&Log"));
menuBar->Append(menuHelp, wxT("&Help"));
SetMenuBar(menuBar);
@ -548,13 +515,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
sz->Add(panel, 0, wxGROW);
SetAutoLayout(TRUE);
SetSizer(sz);
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
// create the debug log dialog box immediately so that we can write output
// to it.
showDebugLog = new DebugLogDialog(this, -1);
showDebugLog->Init();
#endif
}
MyFrame::~MyFrame()
@ -806,101 +766,6 @@ void MyFrame::OnLogPrefsDevice(wxCommandEvent& WXUNUSED(event))
dlg.ShowModal();
}
// How is this going to work?
// The dialog box shows the value of CPU registers, which will be changing
// all the time. What causes the dialog to reread the register value and
// display it? Brainstorm:
// 1) The update could be controlled by a real-time timer.
// 2) It could be triggered by periodic BX_SYNC_EVT_TICK events.
// 3) It could be triggered by changes in the actual value. This is
// good for values that rarely change, but horrible for values like
// EIP that change constantly.
// 4) An update can be forced by explictly calling an update function. For
// example after a single-step you would want to force an update. If you
// interrupt the simulation, you want to force an update. If you manually
// change a parameter, you would force an update.
// When simulation is free running, #1 or #2 might make sense. Try #2.
#if !BX_DEBUGGER_GUI
void MyFrame::OnShowCpu(wxCommandEvent& WXUNUSED(event))
{
if (SIM->get_param(BXPN_WX_CPU0_STATE) == NULL) {
// if params not initialized yet, then give up
wxMessageBox(wxT("Cannot show the debugger window until the simulation has begun."),
wxT("Sim not started"), wxOK | wxICON_ERROR, this);
return;
}
if (showCpu == NULL) {
showCpu = new CpuRegistersDialog(this, -1);
#if BX_DEBUGGER
showCpu->SetTitle(wxT("Bochs Debugger"));
#else
showCpu->SetTitle(wxT("CPU Registers"));
#endif
showCpu->Init();
} else {
showCpu->CopyParamToGui();
}
showCpu->Show(TRUE);
}
#if BX_DEBUGGER
void MyFrame::OnDebugLog(wxCommandEvent& WXUNUSED(event))
{
wxASSERT(showDebugLog != NULL);
showDebugLog->CopyParamToGui();
showDebugLog->Show(TRUE);
}
void MyFrame::DebugBreak()
{
if (debugCommand) {
delete [] debugCommand;
debugCommand = NULL;
}
wxASSERT(showDebugLog != NULL);
showDebugLog->AppendCommand("*** break ***");
SIM->debug_break();
}
void MyFrame::DebugCommand(wxString cmd)
{
char buf[1024];
safeWxStrcpy(buf, cmd, sizeof(buf));
DebugCommand(buf);
}
void MyFrame::DebugCommand(const char *cmd)
{
wxLogDebug(wxT("debugger command: %s"), cmd);
wxASSERT(showDebugLog != NULL);
showDebugLog->AppendCommand(cmd);
if (debugCommand != NULL) {
// one is already waiting
wxLogDebug(wxT("multiple debugger commands, discarding the earlier one"));
delete [] debugCommand;
debugCommand = NULL;
}
int len = strlen(cmd);
char *tmp = new char[len+1];
strncpy(tmp, cmd, len+1);
// if an event is waiting for us, fill it an send back to sim_thread.
if (debugCommandEvent != NULL) {
wxLogDebug(wxT("sim_thread was waiting for this command '%s'"), tmp);
wxASSERT(debugCommandEvent->type == BX_SYNC_EVT_GET_DBG_COMMAND);
debugCommandEvent->u.debugcmd.command = tmp;
debugCommandEvent->retcode = 1;
sim_thread->SendSyncResponse(debugCommandEvent);
wxASSERT(debugCommand == NULL);
debugCommandEvent = NULL;
} else {
// store this command in debugCommand for the future
wxLogDebug(wxT("storing debugger command '%s'"), tmp);
debugCommand = tmp;
}
}
#endif
#endif
void MyFrame::OnQuit(wxCommandEvent& event)
{
wxBochsClosing = true;
@ -943,9 +808,6 @@ void MyFrame::simStatusChanged(StatusChange change, bx_bool popupNotify) {
menuSimulate->Enable(ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable(ID_Simulate_Stop, FALSE);
menuSimulate->SetLabel(ID_Simulate_PauseResume, wxT("&Pause"));
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
showDebugLog->Show(FALSE);
#endif
// This should only be used if the simulation stops due to error.
// Obviously if the user asked it to stop, they don't need to be told.
if (popupNotify)
@ -1067,15 +929,8 @@ void MyFrame::OnKillSim(wxCommandEvent& WXUNUSED(event))
// OnSimThreadExit, which also tries to lock sim_thread_lock.
// If we grab the lock at this level, deadlock results.
wxLogDebug(wxT("OnKillSim()"));
#if BX_DEBUGGER
#if BX_DEBUGGER_GUI
#if BX_DEBUGGER && BX_DEBUGGER_GUI
bx_user_quit = 1;
#else
// the sim_thread may be waiting for a debugger command. If so, send
// it a "quit"
DebugCommand("quit");
debugCommand = NULL;
#endif
#endif
if (sim_thread) {
wxBochsStopSim = true;
@ -1196,11 +1051,6 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
// all cases should return. sync event handlers MUST send back a
// response. async event handlers MUST delete the event.
switch (be->type) {
#if !BX_DEBUGGER_GUI
case BX_ASYNC_EVT_REFRESH:
RefreshDialogs();
break;
#endif
case BX_SYNC_EVT_ASK_PARAM:
wxLogDebug(wxT("before HandleAskParam"));
be->retcode = HandleAskParam(be);
@ -1209,40 +1059,10 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
sim_thread->SendSyncResponse(be);
wxLogDebug(wxT("after SendSyncResponse"));
break;
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
case BX_ASYNC_EVT_DBG_MSG:
showDebugLog->AppendText(wxString(be->u.logmsg.msg, wxConvUTF8));
break;
#endif
case BX_SYNC_EVT_LOG_ASK:
case BX_ASYNC_EVT_LOG_MSG:
OnLogMsg(be);
break;
#if !BX_DEBUGGER_GUI
case BX_SYNC_EVT_GET_DBG_COMMAND:
wxLogDebug(wxT("BX_SYNC_EVT_GET_DBG_COMMAND received"));
if (debugCommand == NULL) {
// no debugger command is ready to send, so don't send a response yet.
// When a command is issued, MyFrame::DebugCommand will fill in the
// event and call SendSyncResponse() so that the simulation thread can
// continue.
debugCommandEvent = be;
//
if (showCpu == NULL || !showCpu->IsShowing()) {
wxCommandEvent unused;
OnShowCpu(unused);
}
} else {
// a debugger command is waiting for us!
wxLogDebug(wxT("sending debugger command '%s' that was waiting"), debugCommand);
be->u.debugcmd.command = debugCommand;
debugCommand = NULL; // ready for the next one
debugCommandEvent = NULL;
be->retcode = 1;
sim_thread->SendSyncResponse(be);
}
break;
#endif
case BX_ASYNC_EVT_QUIT_SIM:
wxMessageBox(wxT("Bochs simulation has stopped."), wxT("Bochs Stopped"),
wxOK | wxICON_INFORMATION, this);
@ -1371,21 +1191,6 @@ void MyFrame::OnToolbarClick(wxCommandEvent& event)
}
}
// warning: This can be called from the simulator thread!!!
#if !BX_DEBUGGER_GUI
bool MyFrame::WantRefresh()
{
bool anyShowing = false;
if (showCpu!=NULL && showCpu->IsShowing()) anyShowing = true;
return anyShowing;
}
void MyFrame::RefreshDialogs()
{
if (showCpu!=NULL && showCpu->IsShowing()) showCpu->CopyParamToGui();
}
#endif
//////////////////////////////////////////////////////////////////////
// Simulation Thread
//////////////////////////////////////////////////////////////////////
@ -1488,14 +1293,6 @@ BxEvent *SimThread::SiminterfaceCallback2(BxEvent *event)
return event;
}
#if !BX_DEBUGGER_GUI
// prune refresh events if the frame is going to ignore them anyway
if (event->type == BX_ASYNC_EVT_REFRESH && !theFrame->WantRefresh()) {
delete event;
return NULL;
}
#endif
//encapsulate the bxevent in a wxwidgets event
wxCommandEvent wxevent(wxEVT_COMMAND_MENU_SELECTED, ID_Sim2CI_Event);
wxevent.SetEventObject((wxEvent *)event);

View File

@ -58,10 +58,6 @@ enum
ID_Simulate_Start,
ID_Simulate_PauseResume,
ID_Simulate_Stop,
#if !BX_DEBUGGER_GUI
ID_Debug_ShowCpu,
ID_Debug_Console,
#endif
ID_Log_View,
ID_Log_Prefs,
ID_Log_PrefsDevice,
@ -191,15 +187,6 @@ public:
void OnLogPrefs(wxCommandEvent& event);
void OnLogPrefsDevice(wxCommandEvent& event);
void OnEditATA(wxCommandEvent& event);
#if !BX_DEBUGGER_GUI
void OnShowCpu(wxCommandEvent& event);
#if BX_DEBUGGER
void OnDebugLog(wxCommandEvent& event);
void DebugBreak();
void DebugCommand(wxString string);
void DebugCommand(const char *cmd);
#endif
#endif
void editFloppyConfig(int drive);
void editFirstCdrom();
void OnToolbarClick(wxCommandEvent& event);
@ -221,19 +208,7 @@ private:
wxMenu *menuLog;
wxMenu *menuHelp;
wxToolBar *bxToolBar;
#if !BX_DEBUGGER_GUI
ParamDialog *showCpu;
#if BX_DEBUGGER
DebugLogDialog *showDebugLog;
#endif
void RefreshDialogs();
char *debugCommand; // maybe need lock on this
BxEvent *debugCommandEvent; // maybe need lock on this
#endif
public:
#if !BX_DEBUGGER_GUI
bool WantRefresh();
#endif
DECLARE_EVENT_TABLE()
};

View File

@ -186,8 +186,5 @@
#define BXPN_MENU_RUNTIME_CDROM "menu.runtime.cdrom"
#define BXPN_MENU_RUNTIME_USB "menu.runtime.usb"
#define BXPN_MENU_RUNTIME_MISC "menu.runtime.misc"
#define BXPN_WX_CPU_STATE "wxdebug.cpu"
#define BXPN_WX_CPU0_STATE "wxdebug.cpu.0"
#define BXPN_WX_CPU0_EFLAGS_IOPL "wxdebug.cpu.0.IOPL"
#endif