- removed wx debugger dialogs (enhanced gui debugger now almost stable with wx)
This commit is contained in:
parent
a6bce2031c
commit
058c0e05fb
@ -291,8 +291,5 @@ menu
|
||||
bochs
|
||||
(subtree containing Bochs state)
|
||||
|
||||
wxdebug
|
||||
(special subtree for wxBochs debugger)
|
||||
|
||||
user
|
||||
(subtree for user-defined options)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -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!
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user