- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
/////////////////////////////////////////////////////////////////
|
2003-08-23 13:52:26 +04:00
|
|
|
// $Id: wxmain.cc,v 1.92 2003-08-23 09:52:26 vruppert Exp $
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
/////////////////////////////////////////////////////////////////
|
2002-04-18 04:22:20 +04:00
|
|
|
//
|
|
|
|
// wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs.
|
|
|
|
// When the application starts, the user is given a chance to choose/edit/save
|
|
|
|
// a configuration. When they decide to start the simulation, functions in
|
|
|
|
// main.cc are called in a separate thread to initialize and run the Bochs
|
|
|
|
// simulator.
|
|
|
|
//
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// Most ports to different platforms implement only the VGA window and
|
|
|
|
// toolbar buttons. The wxWindows port is the first to implement both
|
|
|
|
// the VGA display and the configuration interface, so the boundaries
|
|
|
|
// between them are somewhat blurry. See the extensive comments at
|
|
|
|
// the top of siminterface for the rationale behind this separation.
|
|
|
|
//
|
|
|
|
// The separation between wxmain.cc and wx.cc is as follows:
|
2002-08-29 18:59:37 +04:00
|
|
|
// - wxmain.cc implements a Bochs configuration interface (CI),
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// which is the wxWindows equivalent of control.cc. wxmain creates
|
|
|
|
// a frame with several menus and a toolbar, and allows the user to
|
|
|
|
// choose the machine configuration and start the simulation. Note
|
|
|
|
// that wxmain.cc does NOT include bochs.h. All interactions
|
2002-08-29 18:59:37 +04:00
|
|
|
// between the CI and the simulator are through the siminterface
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// object.
|
2002-04-18 04:22:20 +04:00
|
|
|
// - wx.cc implements a VGA display screen using wxWindows. It is
|
|
|
|
// is the wxWindows equivalent of x.cc, win32.cc, macos.cc, etc.
|
|
|
|
// wx.cc includes bochs.h and has access to all Bochs devices.
|
|
|
|
// The VGA panel accepts only paint, key, and mouse events. As it
|
|
|
|
// receives events, it builds BxEvents and places them into a
|
|
|
|
// thread-safe BxEvent queue. The simulation thread periodically
|
|
|
|
// processes events from the BxEvent queue (bx_gui_c::handle_events)
|
|
|
|
// and notifies the appropriate emulated I/O device.
|
|
|
|
//
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// includes
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
|
|
|
|
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
|
|
|
// is used to know when we are exporting symbols and when we are importing.
|
|
|
|
#define BX_PLUGGABLE
|
|
|
|
|
2002-11-19 08:47:45 +03:00
|
|
|
#include "config.h" // definitions based on configure script
|
|
|
|
#if BX_WITH_WX
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
2002-08-30 11:03:50 +04:00
|
|
|
#include <wx/wxprec.h>
|
2002-04-18 04:22:20 +04:00
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
2002-08-30 11:03:50 +04:00
|
|
|
#include <wx/wx.h>
|
2002-04-18 04:22:20 +04:00
|
|
|
#endif
|
2002-08-30 11:03:50 +04:00
|
|
|
#include <wx/image.h>
|
2002-09-05 17:38:44 +04:00
|
|
|
#include <wx/clipbrd.h>
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
#include "osdep.h" // workarounds for missing stuff
|
|
|
|
#include "gui/siminterface.h" // interface to the simulator
|
|
|
|
#include "bxversion.h" // get version string
|
2002-08-28 07:20:23 +04:00
|
|
|
#include "wxdialog.h" // custom dialog boxes
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
#include "wxmain.h" // wxwindows shared stuff
|
2002-10-25 01:07:56 +04:00
|
|
|
#include "extplugin.h"
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
// include XPM icons
|
|
|
|
#include "bitmaps/cdromd.xpm"
|
|
|
|
#include "bitmaps/copy.xpm"
|
|
|
|
#include "bitmaps/floppya.xpm"
|
|
|
|
#include "bitmaps/floppyb.xpm"
|
|
|
|
#include "bitmaps/paste.xpm"
|
|
|
|
#include "bitmaps/power.xpm"
|
|
|
|
#include "bitmaps/reset.xpm"
|
|
|
|
#include "bitmaps/snapshot.xpm"
|
|
|
|
#include "bitmaps/mouse.xpm"
|
2002-09-06 19:00:54 +04:00
|
|
|
//#include "bitmaps/configbutton.xpm"
|
2002-08-09 10:16:43 +04:00
|
|
|
#include "bitmaps/userbutton.xpm"
|
2002-12-25 20:13:45 +03:00
|
|
|
#ifdef __WXGTK__
|
|
|
|
#include "icon_bochs.xpm"
|
|
|
|
#endif
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
// FIXME: ugly global variables that the bx_gui_c object in wx.cc can use
|
|
|
|
// to access the MyFrame and the MyPanel.
|
|
|
|
MyFrame *theFrame = NULL;
|
|
|
|
MyPanel *thePanel = NULL;
|
|
|
|
|
2002-10-07 08:01:00 +04:00
|
|
|
// The wxBochsClosing flag is used to keep track of when the wxWindows GUI is
|
|
|
|
// shutting down. Shutting down can be somewhat complicated because the
|
|
|
|
// simulation may be running for a while in another thread before it realizes
|
|
|
|
// that it should shut down. The wxBochsClosing flag is a global variable, as
|
|
|
|
// opposed to a field of some C++ object, so that it will be valid at any stage
|
|
|
|
// of the program. wxBochsClosing starts out false (not wxBochsClosing). When
|
|
|
|
// the GUI decides to shut down, it sets wxBochsClosing=true. If there
|
|
|
|
// is not a simulation running, everything is quite simple and it can just
|
|
|
|
// call Close(TRUE). If a simulation is running, it calls OnKillSim to
|
|
|
|
// ask the simulation to stop. When the simulation thread stops, it calls
|
|
|
|
// Close(TRUE) on the frame. During the time that the simulation is
|
|
|
|
// still running and afterward, the wxBochsClosing flag is used to suppress
|
|
|
|
// any events that might reference parts of the GUI or create new dialogs.
|
|
|
|
bool wxBochsClosing = false;
|
|
|
|
|
2002-09-05 11:48:39 +04:00
|
|
|
bool isSimThread () {
|
2002-12-12 01:55:18 +03:00
|
|
|
if (wxThread::IsMain()) return false;
|
2002-09-05 11:48:39 +04:00
|
|
|
wxThread *current = wxThread::This ();
|
|
|
|
if (current == (wxThread*) theFrame->GetSimThread ()) {
|
2002-09-11 07:52:27 +04:00
|
|
|
//wxLogDebug ("isSimThread? yes");
|
2002-09-05 11:48:39 +04:00
|
|
|
return true;
|
|
|
|
}
|
2002-09-11 07:52:27 +04:00
|
|
|
//wxLogDebug ("isSimThread? no");
|
2002-09-05 11:48:39 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// class declarations
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class MyApp: public wxApp
|
|
|
|
{
|
|
|
|
virtual bool OnInit();
|
2002-09-21 01:25:09 +04:00
|
|
|
virtual int OnExit();
|
2002-09-25 22:40:15 +04:00
|
|
|
public:
|
|
|
|
// This default callback is installed when the simthread is NOT running,
|
|
|
|
// so that events coming from the simulator code can be handled.
|
|
|
|
// The primary culprit is panics which cause an BX_SYNC_EVT_LOG_ASK.
|
|
|
|
static BxEvent *DefaultCallback (void *thisptr, BxEvent *event);
|
2002-04-18 04:22:20 +04:00
|
|
|
};
|
|
|
|
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// SimThread is the thread in which the Bochs simulator runs. It is created
|
|
|
|
// by MyFrame::OnStartSim(). The SimThread::Entry() function calls a
|
|
|
|
// function in main.cc called bx_continue_after_config_interface() which
|
|
|
|
// initializes the devices and starts up the simulation. All events from
|
|
|
|
// the simulator
|
2002-04-18 04:22:20 +04:00
|
|
|
class SimThread: public wxThread
|
|
|
|
{
|
|
|
|
MyFrame *frame;
|
|
|
|
|
|
|
|
// when the sim thread sends a synchronous event to the GUI thread, the
|
|
|
|
// response is stored in sim2gui_mailbox.
|
|
|
|
// FIXME: this would be cleaner and more reusable if I made a general
|
|
|
|
// thread-safe mailbox class.
|
|
|
|
BxEvent *sim2gui_mailbox;
|
|
|
|
wxCriticalSection sim2gui_mailbox_lock;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SimThread (MyFrame *_frame) { frame = _frame; sim2gui_mailbox = NULL; }
|
|
|
|
virtual ExitCode Entry ();
|
|
|
|
void OnExit ();
|
|
|
|
// called by the siminterface code, with the pointer to the sim thread
|
|
|
|
// in the thisptr arg.
|
|
|
|
static BxEvent *SiminterfaceCallback (void *thisptr, BxEvent *event);
|
|
|
|
BxEvent *SiminterfaceCallback2 (BxEvent *event);
|
|
|
|
// methods to coordinate synchronous response mailbox
|
|
|
|
void ClearSyncResponse ();
|
|
|
|
void SendSyncResponse (BxEvent *);
|
|
|
|
BxEvent *GetSyncResponse ();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2002-10-25 01:07:56 +04:00
|
|
|
// wxWindows startup
|
2002-04-18 04:22:20 +04:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
static int ci_callback (void *userdata, ci_command_t command)
|
|
|
|
{
|
|
|
|
switch (command)
|
|
|
|
{
|
2002-11-01 18:19:48 +03:00
|
|
|
case CI_START:
|
2002-10-25 01:07:56 +04:00
|
|
|
//fprintf (stderr, "wxmain.cc: start\n");
|
2002-11-01 18:19:48 +03:00
|
|
|
#ifdef __WXMSW__
|
2002-11-01 18:28:41 +03:00
|
|
|
// on Windows only, wxEntry needs some data that is passed into WinMain.
|
|
|
|
// So, in main.cc we define WinMain and fill in the bx_startup_flags
|
|
|
|
// structure with the data, so that when we're ready to call wxEntry
|
|
|
|
// it has access to the data.
|
|
|
|
wxEntry (
|
|
|
|
bx_startup_flags.hInstance,
|
|
|
|
bx_startup_flags.hPrevInstance,
|
|
|
|
bx_startup_flags.m_lpCmdLine,
|
|
|
|
bx_startup_flags.nCmdShow);
|
2002-11-01 18:19:48 +03:00
|
|
|
#else
|
|
|
|
wxEntry (bx_startup_flags.argc, bx_startup_flags.argv);
|
|
|
|
#endif
|
2002-10-25 01:07:56 +04:00
|
|
|
break;
|
|
|
|
case CI_RUNTIME_CONFIG:
|
|
|
|
fprintf (stderr, "wxmain.cc: runtime config not implemented\n");
|
|
|
|
break;
|
|
|
|
case CI_SHUTDOWN:
|
|
|
|
fprintf (stderr, "wxmain.cc: shutdown not implemented\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int libwx_LTX_plugin_init (plugin_t *plugin, plugintype_t type,
|
|
|
|
int argc, char *argv[])
|
|
|
|
{
|
|
|
|
wxLogDebug ("plugin_init for wxmain.cc");
|
|
|
|
wxLogDebug ("installing wxWindows as the configuration interface");
|
|
|
|
SIM->register_configuration_interface ("wx", ci_callback, NULL);
|
|
|
|
wxLogDebug ("installing %s as the Bochs GUI", "wxWindows");
|
|
|
|
MyPanel::OnPluginInit ();
|
|
|
|
return 0; // success
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void libwx_LTX_plugin_fini ()
|
|
|
|
{
|
|
|
|
//fprintf (stderr, "plugin_fini for wxmain.cc\n");
|
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// MyApp: the wxWindows application
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
IMPLEMENT_APP_NO_MAIN(MyApp)
|
|
|
|
|
|
|
|
// this is the entry point of the wxWindows code. It is called as follows:
|
|
|
|
// 1. main() loads the wxWindows plugin (if necessary) and calls
|
|
|
|
// libwx_LTX_plugin_init, which installs a function pointer to the
|
|
|
|
// ci_callback() function.
|
|
|
|
// 2. main() calls SIM->configuration_interface.
|
|
|
|
// 3. bx_real_sim_c::configuration_interface calls the function pointer that
|
|
|
|
// points to ci_callback() in this file, with command=CI_START.
|
|
|
|
// 4. ci_callback() calls wxEntry() in the wxWindows library
|
|
|
|
// 5. wxWindows library creates the app and calls OnInit().
|
|
|
|
//
|
|
|
|
// Before this code is called, the command line has already been parsed, and a
|
|
|
|
// .bochsrc has been loaded if it could be found. See main() for details.
|
2002-04-18 04:22:20 +04:00
|
|
|
bool MyApp::OnInit()
|
|
|
|
{
|
|
|
|
//wxLog::AddTraceMask (_T("mime"));
|
2002-09-05 20:41:54 +04:00
|
|
|
wxLog::SetActiveTarget (new wxLogStderr ());
|
2002-04-18 04:22:20 +04:00
|
|
|
bx_init_siminterface ();
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
// Install callback function to handle anything that occurs before the
|
|
|
|
// simulation begins. This is responsible for displaying any error
|
|
|
|
// dialogs during bochsrc and command line processing.
|
2002-09-25 22:40:15 +04:00
|
|
|
SIM->set_notify_callback (&MyApp::DefaultCallback, this);
|
2002-04-18 04:22:20 +04:00
|
|
|
MyFrame *frame = new MyFrame( "Bochs x86 Emulator", wxPoint(50,50), wxSize(450,340), wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION );
|
|
|
|
theFrame = frame; // hack alert
|
|
|
|
frame->Show( TRUE );
|
|
|
|
SetTopWindow( frame );
|
2002-09-05 17:38:44 +04:00
|
|
|
wxTheClipboard->UsePrimarySelection (true);
|
2002-09-05 11:01:30 +04:00
|
|
|
// if quickstart is enabled, kick off the simulation
|
2002-11-09 17:12:10 +03:00
|
|
|
if (SIM->get_param_enum(BXP_BOCHS_START)->get () == BX_QUICK_START) {
|
2002-09-05 11:01:30 +04:00
|
|
|
wxCommandEvent unusedEvent;
|
|
|
|
frame->OnStartSim (unusedEvent);
|
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2002-09-21 01:25:09 +04:00
|
|
|
int MyApp::OnExit ()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-09-25 22:40:15 +04:00
|
|
|
// these are only called when the simthread is not running.
|
|
|
|
BxEvent *
|
|
|
|
MyApp::DefaultCallback (void *thisptr, BxEvent *event)
|
|
|
|
{
|
2002-10-07 08:01:00 +04:00
|
|
|
wxLogDebug ("DefaultCallback: event type %d", event->type);
|
2002-09-25 22:40:15 +04:00
|
|
|
event->retcode = -1; // default return code
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case BX_ASYNC_EVT_LOG_MSG:
|
|
|
|
case BX_SYNC_EVT_LOG_ASK: {
|
2002-10-07 08:01:00 +04:00
|
|
|
wxLogDebug ("DefaultCallback: log ask event");
|
2002-09-25 22:40:15 +04:00
|
|
|
wxString text;
|
|
|
|
text.Printf ("Error: %s", event->u.logmsg.msg);
|
2002-10-07 08:01:00 +04:00
|
|
|
if (wxBochsClosing) {
|
2002-11-01 18:28:41 +03:00
|
|
|
// gui closing down, do something simple and nongraphical.
|
|
|
|
fprintf (stderr, "%s\n", text.c_str ());
|
2002-10-07 08:01:00 +04:00
|
|
|
} else {
|
2002-11-01 18:28:41 +03:00
|
|
|
wxMessageBox (text, "Error", wxOK | wxICON_ERROR );
|
|
|
|
// maybe I can make OnLogMsg display something that looks appropriate.
|
|
|
|
// theFrame->OnLogMsg (event);
|
2002-10-07 08:01:00 +04:00
|
|
|
}
|
|
|
|
event->retcode = BX_LOG_ASK_CHOICE_DIE;
|
2002-09-25 22:40:15 +04:00
|
|
|
// There is only one thread at this point. if I choose DIE here, it will
|
|
|
|
// call fatal() and kill the whole app.
|
|
|
|
break;
|
|
|
|
}
|
2002-10-07 08:01:00 +04:00
|
|
|
case BX_SYNC_EVT_TICK:
|
|
|
|
if (wxBochsClosing)
|
2002-11-01 18:28:41 +03:00
|
|
|
event->retcode = -1;
|
2002-10-07 08:01:00 +04:00
|
|
|
break;
|
2002-09-25 22:40:15 +04:00
|
|
|
case BX_ASYNC_EVT_REFRESH:
|
|
|
|
case BX_ASYNC_EVT_DBG_MSG:
|
2002-09-26 02:54:23 +04:00
|
|
|
break; // ignore
|
|
|
|
case BX_SYNC_EVT_ASK_PARAM:
|
2002-09-25 22:40:15 +04:00
|
|
|
case BX_SYNC_EVT_GET_DBG_COMMAND:
|
2002-09-26 02:54:23 +04:00
|
|
|
break; // ignore
|
2002-09-25 22:40:15 +04:00
|
|
|
default:
|
2002-10-07 08:01:00 +04:00
|
|
|
wxLogDebug ("DefaultCallback: unknown event type %d", event->type);
|
2002-09-25 22:40:15 +04:00
|
|
|
}
|
2002-09-26 07:01:13 +04:00
|
|
|
if (BX_EVT_IS_ASYNC(event->type)) {
|
2002-09-26 02:54:23 +04:00
|
|
|
delete event;
|
|
|
|
event = NULL;
|
|
|
|
}
|
2002-09-25 22:40:15 +04:00
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// MyFrame: the top level frame for the Bochs application
|
2002-04-18 04:22:20 +04:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
2002-08-30 20:23:36 +04:00
|
|
|
EVT_MENU(ID_Config_New, MyFrame::OnConfigNew)
|
2002-08-25 19:51:46 +04:00
|
|
|
EVT_MENU(ID_Config_Read, MyFrame::OnConfigRead)
|
|
|
|
EVT_MENU(ID_Config_Save, MyFrame::OnConfigSave)
|
2002-04-18 04:22:20 +04:00
|
|
|
EVT_MENU(ID_Quit, MyFrame::OnQuit)
|
|
|
|
EVT_MENU(ID_Help_About, MyFrame::OnAbout)
|
|
|
|
EVT_MENU(ID_Simulate_Start, MyFrame::OnStartSim)
|
|
|
|
EVT_MENU(ID_Simulate_PauseResume, MyFrame::OnPauseResumeSim)
|
|
|
|
EVT_MENU(ID_Simulate_Stop, MyFrame::OnKillSim)
|
2002-08-29 18:59:37 +04:00
|
|
|
EVT_MENU(ID_Sim2CI_Event, MyFrame::OnSim2CIEvent)
|
2002-12-12 19:31:41 +03:00
|
|
|
EVT_MENU(ID_Edit_ATA0, MyFrame::OnEditATA)
|
|
|
|
EVT_MENU(ID_Edit_ATA1, MyFrame::OnEditATA)
|
|
|
|
EVT_MENU(ID_Edit_ATA2, MyFrame::OnEditATA)
|
|
|
|
EVT_MENU(ID_Edit_ATA3, MyFrame::OnEditATA)
|
2002-08-31 08:58:24 +04:00
|
|
|
EVT_MENU(ID_Edit_Boot, MyFrame::OnEditBoot)
|
2002-09-03 00:13:52 +04:00
|
|
|
EVT_MENU(ID_Edit_Memory, MyFrame::OnEditMemory)
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
EVT_MENU(ID_Edit_Sound, MyFrame::OnEditSound)
|
|
|
|
EVT_MENU(ID_Edit_Cmos, MyFrame::OnEditCmos)
|
2003-08-22 20:52:38 +04:00
|
|
|
EVT_MENU(ID_Edit_Timing, MyFrame::OnEditTiming)
|
2002-09-01 23:38:08 +04:00
|
|
|
EVT_MENU(ID_Edit_Network, MyFrame::OnEditNet)
|
2002-09-03 02:53:39 +04:00
|
|
|
EVT_MENU(ID_Edit_Keyboard, MyFrame::OnEditKeyboard)
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
EVT_MENU(ID_Edit_Serial_Parallel, MyFrame::OnEditSerialParallel)
|
|
|
|
EVT_MENU(ID_Edit_LoadHack, MyFrame::OnEditLoadHack)
|
|
|
|
EVT_MENU(ID_Edit_Other, MyFrame::OnEditOther)
|
2002-09-02 21:03:14 +04:00
|
|
|
EVT_MENU(ID_Log_Prefs, MyFrame::OnLogPrefs)
|
2002-09-19 08:52:03 +04:00
|
|
|
EVT_MENU(ID_Log_PrefsDevice, MyFrame::OnLogPrefsDevice)
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
EVT_MENU(ID_Debug_ShowCpu, MyFrame::OnShowCpu)
|
|
|
|
EVT_MENU(ID_Debug_ShowKeyboard, MyFrame::OnShowKeyboard)
|
2002-09-19 00:59:05 +04:00
|
|
|
#if BX_DEBUGGER
|
2002-10-10 19:44:34 +04:00
|
|
|
EVT_MENU(ID_Debug_Console, MyFrame::OnDebugLog)
|
2002-09-16 19:28:19 +04:00
|
|
|
#endif
|
2002-04-18 04:22:20 +04:00
|
|
|
// toolbar events
|
2002-08-30 03:18:10 +04:00
|
|
|
EVT_TOOL(ID_Edit_FD_0, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Edit_FD_1, MyFrame::OnToolbarClick)
|
2002-08-30 10:06:36 +04:00
|
|
|
EVT_TOOL(ID_Edit_Cdrom, MyFrame::OnToolbarClick)
|
2002-04-18 04:22:20 +04:00
|
|
|
EVT_TOOL(ID_Toolbar_Reset, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Toolbar_Power, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Toolbar_Copy, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Toolbar_Paste, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Toolbar_Snapshot, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Toolbar_Config, MyFrame::OnToolbarClick)
|
|
|
|
EVT_TOOL(ID_Toolbar_Mouse_en, MyFrame::OnToolbarClick)
|
2002-08-09 10:16:43 +04:00
|
|
|
EVT_TOOL(ID_Toolbar_User, MyFrame::OnToolbarClick)
|
2002-04-18 04:22:20 +04:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
2002-08-30 10:46:38 +04:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// Menu layout (approximate)
|
|
|
|
//
|
|
|
|
// The actual menus will be changing so this probably isn't up
|
|
|
|
// to date, but having it in text form was useful in planning.
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// - File
|
|
|
|
// +----------------------+
|
|
|
|
// | New Configuration |
|
|
|
|
// | Read Configuration |
|
|
|
|
// | Save Configuration |
|
|
|
|
// +----------------------+
|
|
|
|
// | Quit |
|
|
|
|
// +----------------------+
|
|
|
|
// - Edit
|
|
|
|
// +----------------------+
|
|
|
|
// | Floppy Disk 0... |
|
|
|
|
// | Floppy Disk 1... |
|
|
|
|
// | Hard Disk 0... |
|
|
|
|
// | Hard Disk 1... |
|
|
|
|
// | Cdrom... |
|
|
|
|
// | Boot... |
|
|
|
|
// | VGA... |
|
|
|
|
// | Memory... |
|
|
|
|
// | Sound... |
|
|
|
|
// | Networking... |
|
|
|
|
// | Keyboard... |
|
|
|
|
// | Other... |
|
|
|
|
// +----------------------+
|
|
|
|
// - Simulate
|
|
|
|
// +----------------------+
|
|
|
|
// | Start |
|
|
|
|
// | Pause/Resume |
|
|
|
|
// | Stop |
|
|
|
|
// +----------------------|
|
|
|
|
// - Debug
|
|
|
|
// +----------------------|
|
|
|
|
// | Show CPU |
|
|
|
|
// | Show Memory |
|
|
|
|
// | ? what else ? |
|
|
|
|
// +----------------------|
|
|
|
|
// - Event Log
|
|
|
|
// +----------------------+
|
|
|
|
// | View |
|
|
|
|
// | Preferences... |
|
|
|
|
// | By Device... |
|
|
|
|
// +----------------------+
|
|
|
|
// - Help
|
|
|
|
// +----------------------+
|
|
|
|
// | About Bochs... |
|
|
|
|
// +----------------------+
|
|
|
|
//////////////////////////////////////////////////////////////////
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
|
|
|
|
: wxFrame((wxFrame *)NULL, -1, title, pos, size, style)
|
|
|
|
{
|
2002-12-25 20:13:45 +03:00
|
|
|
SetIcon(wxICON(icon_bochs));
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
// init variables
|
|
|
|
sim_thread = NULL;
|
|
|
|
start_bochs_times = 0;
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
showCpu = NULL;
|
|
|
|
showKbd = NULL;
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
debugCommand = NULL;
|
|
|
|
debugCommandEvent = NULL;
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
// set up the gui
|
|
|
|
menuConfiguration = new wxMenu;
|
|
|
|
menuConfiguration->Append( ID_Config_New, "&New Configuration" );
|
|
|
|
menuConfiguration->Append( ID_Config_Read, "&Read Configuration" );
|
|
|
|
menuConfiguration->Append( ID_Config_Save, "&Save Configuration" );
|
|
|
|
menuConfiguration->AppendSeparator ();
|
|
|
|
menuConfiguration->Append (ID_Quit, "&Quit");
|
|
|
|
|
|
|
|
menuEdit = new wxMenu;
|
2002-08-30 03:18:10 +04:00
|
|
|
menuEdit->Append( ID_Edit_FD_0, "Floppy Disk &0..." );
|
|
|
|
menuEdit->Append( ID_Edit_FD_1, "Floppy Disk &1..." );
|
- fixed up ParamDialog to correctly handle "trees" of parameters. A
bx_list_c can now be displayed as either a wxStaticBox with the
child parameters inside, or as a wxNotebook with each child
parameter in a separate tab. (The children can also be lists of
course.) The default display is the wxStaticBox type, but if you
set the option bit bx_list_c::USE_TAB_WINDOW in the list,
ParamDialog will use the wxNotebook display instead.
- to get the param trees working, I created a new struct
AddParamContext, which is passed to AddParam(). This struct is
critical when AddParam calls itself recursively to display lists
within lists.
- use the wxNotebook display feature for the ATA0,1,2,3 controller
dialog box. Now instead of being hundreds of pixels tall, it is
reasonable height with three different tabs. This fixed bug
#619074: "wx: ATA interface editor too tall" and was the whole
reason I started messing with this at all.
plus some minor cleanups
- when I added the enum constant bx_list_c::USE_TAB_WINDOW, I also
removed the BX_ prefix from all the other enum constants that are
used in parameter options in siminterface.cc. Since these constants
are enums within a class, there is no possibility of namespace
conflicts so the prefix is not needed.
- added wxADJUST_MINSIZE to all wxChoice controls, since that tells
wxWindows to adjust its size to the length of the longest string.
- instead of calling SetSize or SetSizeHints on every textcontrol with
a hardcoded width, I am using just two wxSize specifications for
everything: either normalTextSize or longTextSize.
- edit names of a few menus and params. For example now instead of
the tab saying "Master ATA device on channel 0" it will say
"First HD/CD on channel 0".
Modified Files:
main.cc gui/control.cc gui/gui.cc gui/siminterface.cc gui/siminterface.h
gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
2002-10-06 06:37:28 +04:00
|
|
|
menuEdit->Append( ID_Edit_ATA0, "ATA Channel 0..." );
|
|
|
|
menuEdit->Append( ID_Edit_ATA1, "ATA Channel 1..." );
|
|
|
|
menuEdit->Append( ID_Edit_ATA2, "ATA Channel 2..." );
|
|
|
|
menuEdit->Append( ID_Edit_ATA3, "ATA Channel 3..." );
|
2002-04-18 04:22:20 +04:00
|
|
|
menuEdit->Append( ID_Edit_Boot, "&Boot..." );
|
|
|
|
menuEdit->Append( ID_Edit_Memory, "&Memory..." );
|
2003-08-22 20:52:38 +04:00
|
|
|
menuEdit->Append( ID_Edit_Sound, "S&ound..." );
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
menuEdit->Append( ID_Edit_Cmos, "&CMOS..." );
|
2003-08-22 20:52:38 +04:00
|
|
|
menuEdit->Append( ID_Edit_Timing, "&Timing..." );
|
2002-04-18 04:22:20 +04:00
|
|
|
menuEdit->Append( ID_Edit_Network, "&Network..." );
|
|
|
|
menuEdit->Append( ID_Edit_Keyboard, "&Keyboard..." );
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
menuEdit->Append( ID_Edit_Serial_Parallel, "&Serial/Parallel..." );
|
|
|
|
menuEdit->Append( ID_Edit_LoadHack, "&Loader Hack..." );
|
2002-04-18 04:22:20 +04:00
|
|
|
menuEdit->Append( ID_Edit_Other, "&Other..." );
|
|
|
|
|
|
|
|
menuSimulate = new wxMenu;
|
|
|
|
menuSimulate->Append( ID_Simulate_Start, "&Start...");
|
|
|
|
menuSimulate->Append( ID_Simulate_PauseResume, "&Pause...");
|
|
|
|
menuSimulate->Append( ID_Simulate_Stop, "S&top...");
|
|
|
|
menuSimulate->AppendSeparator ();
|
|
|
|
menuSimulate->Enable (ID_Simulate_PauseResume, FALSE);
|
|
|
|
menuSimulate->Enable (ID_Simulate_Stop, FALSE);
|
|
|
|
|
|
|
|
menuDebug = new wxMenu;
|
|
|
|
menuDebug->Append (ID_Debug_ShowCpu, "Show &CPU");
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
menuDebug->Append (ID_Debug_ShowKeyboard, "Show &Keyboard");
|
2002-10-10 19:44:34 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
menuDebug->Append (ID_Debug_Console, "Debug Console");
|
|
|
|
#endif
|
2002-04-18 04:22:20 +04:00
|
|
|
menuDebug->Append (ID_Debug_ShowMemory, "Show &memory");
|
|
|
|
|
|
|
|
menuLog = new wxMenu;
|
|
|
|
menuLog->Append (ID_Log_View, "&View");
|
|
|
|
menuLog->Append (ID_Log_Prefs, "&Preferences...");
|
|
|
|
menuLog->Append (ID_Log_PrefsDevice, "By &Device...");
|
|
|
|
|
|
|
|
menuHelp = new wxMenu;
|
|
|
|
menuHelp->Append( ID_Help_About, "&About..." );
|
|
|
|
|
|
|
|
wxMenuBar *menuBar = new wxMenuBar;
|
|
|
|
menuBar->Append( menuConfiguration, "&File" );
|
|
|
|
menuBar->Append( menuEdit, "&Edit" );
|
|
|
|
menuBar->Append( menuSimulate, "&Simulate" );
|
|
|
|
menuBar->Append( menuDebug, "&Debug" );
|
|
|
|
menuBar->Append( menuLog, "&Log" );
|
|
|
|
menuBar->Append( menuHelp, "&Help" );
|
|
|
|
SetMenuBar( menuBar );
|
2002-09-03 12:55:35 +04:00
|
|
|
|
|
|
|
// disable things that don't work yet
|
|
|
|
menuDebug->Enable (ID_Debug_ShowMemory, FALSE); // not implemented
|
|
|
|
menuLog->Enable (ID_Log_View, FALSE); // not implemented
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
CreateStatusBar();
|
|
|
|
|
2002-09-03 23:04:17 +04:00
|
|
|
CreateToolBar(wxNO_BORDER|wxHORIZONTAL|wxTB_FLAT);
|
2002-04-18 04:22:20 +04:00
|
|
|
wxToolBar *tb = GetToolBar();
|
2002-09-03 21:50:12 +04:00
|
|
|
tb->SetToolBitmapSize(wxSize(32, 32));
|
2002-04-18 04:22:20 +04:00
|
|
|
|
2002-09-03 21:50:12 +04:00
|
|
|
#define BX_ADD_TOOL(id, xpm_name, tooltip) do { \
|
2002-09-03 23:04:17 +04:00
|
|
|
tb->AddTool(id, wxBitmap(xpm_name), tooltip); \
|
2002-09-03 21:50:12 +04:00
|
|
|
} while (0)
|
2002-04-18 04:22:20 +04:00
|
|
|
|
2002-08-30 03:18:10 +04:00
|
|
|
BX_ADD_TOOL(ID_Edit_FD_0, floppya_xpm, "Change Floppy A");
|
|
|
|
BX_ADD_TOOL(ID_Edit_FD_1, floppyb_xpm, "Change Floppy B");
|
2002-08-30 10:06:36 +04:00
|
|
|
BX_ADD_TOOL(ID_Edit_Cdrom, cdromd_xpm, "Change CDROM");
|
2002-04-18 04:22:20 +04:00
|
|
|
BX_ADD_TOOL(ID_Toolbar_Reset, reset_xpm, "Reset the system");
|
|
|
|
BX_ADD_TOOL(ID_Toolbar_Power, power_xpm, "Turn power on/off");
|
|
|
|
|
|
|
|
BX_ADD_TOOL(ID_Toolbar_Copy, copy_xpm, "Copy to clipboard");
|
|
|
|
BX_ADD_TOOL(ID_Toolbar_Paste, paste_xpm, "Paste from clipboard");
|
|
|
|
BX_ADD_TOOL(ID_Toolbar_Snapshot, snapshot_xpm, "Save screen snapshot");
|
2002-09-05 21:27:50 +04:00
|
|
|
// Omit config button because the whole wxWindows interface is like
|
|
|
|
// one really big config button.
|
|
|
|
//BX_ADD_TOOL(ID_Toolbar_Config, configbutton_xpm, "Runtime Configuration");
|
2002-10-07 08:49:50 +04:00
|
|
|
BX_ADD_TOOL(ID_Toolbar_Mouse_en, mouse_xpm, "Enable/disable mouse capture\nThere are also two shortcuts for this: F12 and the middle mouse button.");
|
2002-08-09 10:16:43 +04:00
|
|
|
BX_ADD_TOOL(ID_Toolbar_User, userbutton_xpm, "Keyboard shortcut");
|
2002-04-18 04:22:20 +04:00
|
|
|
|
|
|
|
tb->Realize();
|
|
|
|
|
|
|
|
// create a MyPanel that covers the whole frame
|
|
|
|
panel = new MyPanel (this, -1);
|
|
|
|
panel->SetBackgroundColour (wxColour (0,0,0));
|
2002-09-22 06:43:37 +04:00
|
|
|
panel->SetFocus ();
|
2002-04-18 04:22:20 +04:00
|
|
|
wxGridSizer *sz = new wxGridSizer (1, 1);
|
|
|
|
sz->Add (panel, 0, wxGROW);
|
|
|
|
SetAutoLayout (TRUE);
|
|
|
|
SetSizer (sz);
|
|
|
|
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
// create the debug log dialog box immediately so that we can write output
|
|
|
|
// to it.
|
|
|
|
showDebugLog = new DebugLogDialog (this, -1);
|
|
|
|
showDebugLog->Init ();
|
|
|
|
#endif
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
2002-09-05 20:01:34 +04:00
|
|
|
MyFrame::~MyFrame ()
|
|
|
|
{
|
2002-09-21 01:25:09 +04:00
|
|
|
delete panel;
|
2002-09-05 20:01:34 +04:00
|
|
|
wxLogDebug ("MyFrame destructor");
|
|
|
|
theFrame = NULL;
|
|
|
|
}
|
|
|
|
|
2002-08-30 20:23:36 +04:00
|
|
|
void MyFrame::OnConfigNew(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
int answer = wxMessageBox ("This will reset all settings back to their default values.\nAre you sure you want to do this?",
|
2003-08-23 09:34:40 +04:00
|
|
|
"Are you sure?", wxYES_NO | wxCENTER, this);
|
2002-08-30 20:23:36 +04:00
|
|
|
if (answer == wxYES) SIM->reset_all_param ();
|
|
|
|
}
|
|
|
|
|
2002-08-25 19:51:46 +04:00
|
|
|
void MyFrame::OnConfigRead(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
2002-09-25 22:40:15 +04:00
|
|
|
char *bochsrc;
|
|
|
|
long style = wxOPEN;
|
|
|
|
wxFileDialog *fdialog = new wxFileDialog (this, "Read configuration", "", "", "*.*", style);
|
|
|
|
if (fdialog->ShowModal() == wxID_OK) {
|
|
|
|
bochsrc = (char *)fdialog->GetPath().c_str ();
|
|
|
|
SIM->reset_all_param ();
|
|
|
|
SIM->read_rc (bochsrc);
|
|
|
|
}
|
|
|
|
delete fdialog;
|
2002-08-25 19:51:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnConfigSave(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
2002-09-25 22:40:15 +04:00
|
|
|
char *bochsrc;
|
|
|
|
long style = wxSAVE | wxOVERWRITE_PROMPT;
|
|
|
|
wxFileDialog *fdialog = new wxFileDialog (this, "Save configuration", "", "", "*.*", style);
|
|
|
|
if (fdialog->ShowModal() == wxID_OK) {
|
|
|
|
bochsrc = (char *)fdialog->GetPath().c_str ();
|
|
|
|
SIM->write_rc (bochsrc, 1);
|
|
|
|
}
|
|
|
|
delete fdialog;
|
2002-08-25 19:51:46 +04:00
|
|
|
}
|
|
|
|
|
2002-08-31 08:58:24 +04:00
|
|
|
void MyFrame::OnEditBoot(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
2002-09-03 20:03:50 +04:00
|
|
|
#define MAX_BOOT_DEVICES 3
|
2002-08-31 08:58:24 +04:00
|
|
|
int bootDevices = 0;
|
2002-09-03 20:03:50 +04:00
|
|
|
wxString devices[MAX_BOOT_DEVICES];
|
|
|
|
int dev_id[MAX_BOOT_DEVICES];
|
2002-09-23 00:56:12 +04:00
|
|
|
bx_param_enum_c *floppy = SIM->get_param_enum (BXP_FLOPPYA_DEVTYPE);
|
2002-08-31 08:58:24 +04:00
|
|
|
if (floppy->get () != BX_FLOPPY_NONE) {
|
|
|
|
devices[bootDevices] = wxT("First floppy drive");
|
|
|
|
dev_id[bootDevices++] = BX_BOOT_FLOPPYA;
|
|
|
|
}
|
2002-12-07 22:43:53 +03:00
|
|
|
bx_param_c *firsthd = SIM->get_first_hd ();
|
|
|
|
if (firsthd != NULL) {
|
2002-08-31 08:58:24 +04:00
|
|
|
devices[bootDevices] = wxT("First hard drive");
|
|
|
|
dev_id[bootDevices++] = BX_BOOT_DISKC;
|
|
|
|
}
|
2002-12-07 22:43:53 +03:00
|
|
|
bx_param_c *firstcd = SIM->get_first_cdrom ();
|
|
|
|
if (firstcd != NULL) {
|
2002-08-31 08:58:24 +04:00
|
|
|
devices[bootDevices] = wxT("CD-ROM drive");
|
|
|
|
dev_id[bootDevices++] = BX_BOOT_CDROM;
|
|
|
|
}
|
|
|
|
if (bootDevices == 0) {
|
2003-08-23 09:34:40 +04:00
|
|
|
wxMessageBox( "All the possible boot devices are disabled right now!\nYou must enable the first floppy drive, a hard drive, or a CD-ROM.",
|
|
|
|
"None enabled", wxOK | wxICON_ERROR, this );
|
2002-08-31 08:58:24 +04:00
|
|
|
return;
|
|
|
|
}
|
2003-08-23 09:34:40 +04:00
|
|
|
int which = wxGetSingleChoiceIndex ("Select the device to boot from", "Boot Device", bootDevices, devices, this);
|
2002-08-31 08:58:24 +04:00
|
|
|
if (which<0) return; // cancelled
|
|
|
|
bx_param_enum_c *bootdevice = (bx_param_enum_c *)
|
|
|
|
SIM->get_param(BXP_BOOTDRIVE);
|
|
|
|
bootdevice->set (which);
|
|
|
|
}
|
|
|
|
|
2002-09-03 00:13:52 +04:00
|
|
|
void MyFrame::OnEditMemory(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
ConfigMemoryDialog dlg (this, -1);
|
|
|
|
bx_param_num_c *megs = (bx_param_num_c*) SIM->get_param(BXP_MEM_SIZE);
|
|
|
|
bx_param_string_c *bios = (bx_param_string_c *) SIM->get_param (BXP_ROM_PATH);
|
|
|
|
bx_param_num_c *biosaddr = (bx_param_num_c*) SIM->get_param(BXP_ROM_ADDRESS);
|
|
|
|
bx_param_string_c *vgabios = (bx_param_string_c *) SIM->get_param (BXP_VGA_ROM_PATH);
|
|
|
|
static bx_id optRomPathParams[] = {
|
|
|
|
BXP_OPTROM1_PATH, BXP_OPTROM2_PATH, BXP_OPTROM3_PATH, BXP_OPTROM4_PATH
|
|
|
|
};
|
|
|
|
static bx_id optRomAddrParams[] = {
|
|
|
|
BXP_OPTROM1_ADDRESS, BXP_OPTROM2_ADDRESS, BXP_OPTROM3_ADDRESS, BXP_OPTROM4_ADDRESS
|
|
|
|
};
|
|
|
|
bx_param_string_c *optromPath[CONFIG_MEMORY_N_ROMS];
|
|
|
|
bx_param_num_c *optromAddr[CONFIG_MEMORY_N_ROMS];
|
|
|
|
int rom;
|
|
|
|
for (rom=0; rom<CONFIG_MEMORY_N_ROMS; rom++) {
|
|
|
|
optromPath[rom] = (bx_param_string_c *)
|
|
|
|
SIM->get_param (optRomPathParams[rom]);
|
|
|
|
optromAddr[rom] = (bx_param_num_c *)
|
|
|
|
SIM->get_param (optRomAddrParams[rom]);
|
|
|
|
}
|
|
|
|
dlg.SetSize (megs->get ());
|
|
|
|
dlg.SetBios (wxString (bios->getptr ()));
|
|
|
|
dlg.SetBiosAddr (biosaddr->get ());
|
|
|
|
dlg.SetVgaBios (wxString (vgabios->getptr ()));
|
|
|
|
for (rom=0; rom<CONFIG_MEMORY_N_ROMS; rom++) {
|
|
|
|
dlg.SetRom (rom, wxString (optromPath[rom]->getptr ()));
|
|
|
|
dlg.SetRomAddr (rom, optromAddr[rom]->get ());
|
|
|
|
}
|
|
|
|
int n = dlg.ShowModal ();
|
2002-09-04 16:29:04 +04:00
|
|
|
if (n == wxID_OK) {
|
2002-09-03 00:13:52 +04:00
|
|
|
char buf[1024];
|
|
|
|
megs->set (dlg.GetSize ());
|
|
|
|
safeWxStrcpy (buf, dlg.GetBios (), sizeof (buf));
|
|
|
|
bios->set (buf);
|
|
|
|
biosaddr->set (dlg.GetBiosAddr ());
|
|
|
|
safeWxStrcpy (buf, dlg.GetVgaBios (), sizeof (buf));
|
|
|
|
vgabios->set (buf);
|
|
|
|
for (rom=0; rom<CONFIG_MEMORY_N_ROMS; rom++) {
|
|
|
|
safeWxStrcpy (buf, dlg.GetRom (rom), sizeof (buf));
|
|
|
|
optromPath[rom]->set (buf);
|
|
|
|
optromAddr[rom]->set (dlg.GetRomAddr (rom));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
void MyFrame::OnEditSound(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
ParamDialog dlg (this, -1);
|
|
|
|
bx_list_c *list = (bx_list_c*) SIM->get_param (BXP_SB16);
|
|
|
|
dlg.SetTitle (list->get_name ());
|
|
|
|
for (int i=0; i<list->get_size (); i++)
|
|
|
|
dlg.AddParam (list->get (i));
|
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnEditCmos(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
ParamDialog dlg (this, -1);
|
2003-08-23 13:52:26 +04:00
|
|
|
dlg.SetTitle ("Configure CMOS");
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
dlg.AddParam (SIM->get_param (BXP_CMOS_IMAGE));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_CMOS_PATH));
|
2003-08-22 05:00:58 +04:00
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
2003-08-22 20:52:38 +04:00
|
|
|
void MyFrame::OnEditTiming(wxCommandEvent& WXUNUSED(event))
|
2003-08-22 05:00:58 +04:00
|
|
|
{
|
|
|
|
ParamDialog dlg (this, -1);
|
2003-08-22 20:52:38 +04:00
|
|
|
dlg.AddParam (SIM->get_param (BXP_IPS));
|
2003-08-22 05:00:58 +04:00
|
|
|
bx_list_c *list = (bx_list_c*) SIM->get_param (BXP_CLOCK);
|
|
|
|
dlg.SetTitle (list->get_name ());
|
|
|
|
for (int i=0; i<list->get_size (); i++)
|
|
|
|
dlg.AddParam (list->get (i));
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
2002-09-01 23:38:08 +04:00
|
|
|
void MyFrame::OnEditNet(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
NetConfigDialog dlg (this, -1);
|
2002-11-18 20:16:07 +03:00
|
|
|
bx_param_bool_c *present = (bx_param_bool_c*)SIM->get_param (BXP_NE2K_PRESENT);
|
2002-09-02 01:24:14 +04:00
|
|
|
bx_param_num_c *io = (bx_param_num_c*)SIM->get_param (BXP_NE2K_IOADDR);
|
|
|
|
bx_param_num_c *irq = (bx_param_num_c*)SIM->get_param (BXP_NE2K_IRQ);
|
|
|
|
bx_param_string_c *mac = (bx_param_string_c*)
|
|
|
|
SIM->get_param (BXP_NE2K_MACADDR);
|
|
|
|
bx_param_string_c *module = (bx_param_string_c*)
|
|
|
|
SIM->get_param (BXP_NE2K_ETHMOD);
|
|
|
|
bx_param_string_c *device = (bx_param_string_c*)
|
|
|
|
SIM->get_param (BXP_NE2K_ETHDEV);
|
|
|
|
bx_param_string_c *script = (bx_param_string_c*)
|
|
|
|
SIM->get_param (BXP_NE2K_SCRIPT);
|
|
|
|
dlg.SetEnable (present->get ());
|
|
|
|
dlg.SetIO (io->get ());
|
|
|
|
dlg.SetIrq (irq->get ());
|
|
|
|
dlg.SetMac ((unsigned char *) mac->getptr ());
|
|
|
|
dlg.AddConn ("Null Packet Mover", "null");
|
|
|
|
#if defined(ETH_LINUX)
|
|
|
|
dlg.AddConn ("Linux Socket Filter", "linux");
|
|
|
|
#endif
|
|
|
|
#if HAVE_ETHERTAP
|
|
|
|
dlg.AddConn ("Ethertap", "tap");
|
|
|
|
#endif
|
|
|
|
#if HAVE_TUNTAP
|
|
|
|
dlg.AddConn ("TUN/TAP", "tuntap");
|
|
|
|
#endif
|
|
|
|
#if defined(ETH_WIN32)
|
|
|
|
dlg.AddConn ("Win32 packet mover", "win32");
|
|
|
|
#endif
|
|
|
|
#if defined(ETH_FBSD)
|
|
|
|
dlg.AddConn ("Berkeley Packet Filter (FreeBSD, OpenBSD)", "fbsd");
|
|
|
|
#endif
|
|
|
|
#ifdef ETH_ARPBACK
|
|
|
|
dlg.AddConn ("ARPback packet mover", "arpback");
|
|
|
|
#endif
|
|
|
|
dlg.SetConn (module->getptr ());
|
|
|
|
dlg.SetPhys (device->getptr ());
|
|
|
|
dlg.SetScript (script->getptr ());
|
2002-09-01 23:38:08 +04:00
|
|
|
int n = dlg.ShowModal ();
|
2002-09-04 16:29:04 +04:00
|
|
|
if (n==wxID_OK) {
|
2002-09-02 01:24:14 +04:00
|
|
|
present->set (dlg.GetEnable ());
|
|
|
|
io->set (dlg.GetIO ());
|
|
|
|
irq->set (dlg.GetIrq ());
|
|
|
|
unsigned char tmp[6];
|
|
|
|
dlg.GetMac (tmp);
|
|
|
|
mac->set ((char *)tmp);
|
|
|
|
module->set ((char *)dlg.GetConnData ());
|
|
|
|
char buf[1024];
|
|
|
|
wxString deviceString (dlg.GetPhys ());
|
|
|
|
strncpy (buf, deviceString.c_str (), sizeof(buf));
|
|
|
|
device->set (buf);
|
|
|
|
wxString scriptString (dlg.GetScript ());
|
|
|
|
strncpy (buf, scriptString.c_str (), sizeof(buf));
|
|
|
|
script->set (buf);
|
2002-09-01 23:38:08 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-03 02:53:39 +04:00
|
|
|
void MyFrame::OnEditKeyboard(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
2002-09-03 12:55:35 +04:00
|
|
|
ParamDialog dlg(this, -1);
|
|
|
|
dlg.SetTitle ("Configure Keyboard");
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_KBD_TYPE));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_KBD_SERIAL_DELAY));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_KBD_PASTE_DELAY));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_KEYBOARD_USEMAPPING));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_KEYBOARD_MAP));
|
|
|
|
dlg.ShowModal ();
|
2002-09-03 02:53:39 +04:00
|
|
|
}
|
|
|
|
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
void MyFrame::OnEditSerialParallel(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
ParamDialog dlg(this, -1);
|
|
|
|
bx_list_c *list = (bx_list_c*) SIM->get_param (BXP_MENU_SERIAL_PARALLEL);
|
|
|
|
dlg.SetTitle (list->get_name ());
|
|
|
|
for (int i=0; i<list->get_size (); i++)
|
|
|
|
dlg.AddParam (list->get (i));
|
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnEditLoadHack(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
ParamDialog dlg(this, -1);
|
2002-09-03 12:55:35 +04:00
|
|
|
bx_list_c *list = (bx_list_c*) SIM->get_param (BXP_LOAD32BITOS);
|
|
|
|
dlg.SetTitle (list->get_name ());
|
|
|
|
for (int i=0; i<list->get_size (); i++)
|
|
|
|
dlg.AddParam (list->get (i));
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnEditOther(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
ParamDialog dlg(this, -1);
|
|
|
|
dlg.SetTitle ("Other Options");
|
2002-10-25 01:07:56 +04:00
|
|
|
dlg.AddParam (SIM->get_param (BXP_SEL_DISPLAY_LIBRARY));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_SEL_CONFIG_INTERFACE));
|
2002-09-03 12:55:35 +04:00
|
|
|
dlg.AddParam (SIM->get_param (BXP_VGA_UPDATE_INTERVAL));
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
dlg.AddParam (SIM->get_param (BXP_LOG_PREFIX));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_MOUSE_ENABLED));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_USER_SHORTCUT));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_FLOPPYSIGCHECK));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_FLOPPY_CMD_DELAY));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_NEWHARDDRIVESUPPORT));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_PRIVATE_COLORMAP));
|
|
|
|
#if BX_WITH_AMIGAOS
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_FULLSCREEN));
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_SCREENMODE));
|
|
|
|
#endif
|
|
|
|
dlg.AddParam (SIM->get_param (BXP_I440FX_SUPPORT));
|
2002-09-05 21:27:50 +04:00
|
|
|
dlg.ShowModal ();
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
}
|
|
|
|
|
2002-09-02 21:03:14 +04:00
|
|
|
void MyFrame::OnLogPrefs(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
// Ideally I would use the siminterface methods to fill in the fields
|
|
|
|
// of the LogOptionsDialog, but in fact several things are hardcoded.
|
|
|
|
// At least I can verify that the expected numbers are the same.
|
|
|
|
wxASSERT (SIM->get_max_log_level() == LOG_OPTS_N_TYPES);
|
|
|
|
LogOptionsDialog dlg (this, -1);
|
2002-09-05 21:27:50 +04:00
|
|
|
bx_param_string_c *logfile = SIM->get_param_string (BXP_LOG_FILENAME);
|
|
|
|
dlg.SetLogfile (wxString (logfile->getptr ()));
|
2002-12-07 19:52:09 +03:00
|
|
|
bx_param_string_c *debuggerlogfile = SIM->get_param_string (BXP_DEBUGGER_LOG_FILENAME);
|
|
|
|
dlg.SetDebuggerlogfile (wxString (debuggerlogfile->getptr ()));
|
2002-09-02 21:03:14 +04:00
|
|
|
|
|
|
|
// The inital values of the dialog are complicated. If the panic action
|
|
|
|
// for all modules is "ask", then clearly the inital value in the dialog
|
|
|
|
// for panic action should be "ask". This informs the user what the
|
|
|
|
// previous value was, and if they click Ok it won't do any harm. But if
|
|
|
|
// some devices are set to "ask" and others are set to "report", then the
|
|
|
|
// initial value should be "no change". With "no change", clicking on Ok
|
|
|
|
// will not destroy the settings for individual devices. You would only
|
|
|
|
// start to see "no change" if you've been messing around in the advanced
|
|
|
|
// menu already.
|
2002-09-20 21:53:14 +04:00
|
|
|
int level, nlevel = SIM->get_max_log_level();
|
|
|
|
for (level=0; level<nlevel; level++) {
|
2002-09-02 21:03:14 +04:00
|
|
|
int mod = 0;
|
|
|
|
int first = SIM->get_log_action (mod, level);
|
|
|
|
bool consensus = true;
|
|
|
|
// now compare all others to first. If all match, then use "first" as
|
|
|
|
// the initial value.
|
|
|
|
for (mod=1; mod<SIM->get_n_log_modules (); mod++) {
|
|
|
|
if (first != SIM->get_log_action (mod, level)) {
|
2002-11-01 18:28:41 +03:00
|
|
|
consensus = false;
|
|
|
|
break;
|
2002-09-02 21:03:14 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (consensus)
|
|
|
|
dlg.SetAction (level, first);
|
|
|
|
else
|
|
|
|
dlg.SetAction (level, LOG_OPTS_NO_CHANGE);
|
|
|
|
}
|
|
|
|
int n = dlg.ShowModal (); // show the dialog!
|
2002-09-04 16:29:04 +04:00
|
|
|
if (n == wxID_OK) {
|
2002-09-05 21:27:50 +04:00
|
|
|
char buf[1024];
|
|
|
|
safeWxStrcpy (buf, dlg.GetLogfile (), sizeof (buf));
|
|
|
|
logfile->set (buf);
|
2002-12-07 19:52:09 +03:00
|
|
|
safeWxStrcpy (buf, dlg.GetDebuggerlogfile (), sizeof (buf));
|
|
|
|
debuggerlogfile->set (buf);
|
2002-09-20 21:53:14 +04:00
|
|
|
for (level=0; level<nlevel; level++) {
|
2002-09-02 21:03:14 +04:00
|
|
|
// ask the dialog what action the user chose for this type of event
|
|
|
|
int action = dlg.GetAction (level);
|
|
|
|
if (action != LOG_OPTS_NO_CHANGE) {
|
2002-11-01 18:28:41 +03:00
|
|
|
// set new default
|
2002-09-20 21:53:14 +04:00
|
|
|
SIM->set_default_log_action (level, action);
|
2002-11-01 18:28:41 +03:00
|
|
|
// apply that action to all modules (devices)
|
|
|
|
SIM->set_log_action (-1, level, action);
|
2002-09-02 21:03:14 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-19 08:52:03 +04:00
|
|
|
void MyFrame::OnLogPrefsDevice(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
wxASSERT (SIM->get_max_log_level() == ADVLOG_OPTS_N_TYPES);
|
|
|
|
AdvancedLogOptionsDialog dlg (this, -1);
|
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
// 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.
|
|
|
|
void MyFrame::OnShowCpu(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
if (SIM->get_param (BXP_CPU_EAX) == NULL) {
|
|
|
|
// if params not initialized yet, then give up
|
2003-08-23 09:34:40 +04:00
|
|
|
wxMessageBox ("Cannot show the debugger window until the simulation has begun.",
|
|
|
|
"Sim not started", wxOK | wxICON_ERROR, this );
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
return;
|
|
|
|
}
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
if (showCpu == NULL) {
|
2002-09-19 00:59:05 +04:00
|
|
|
showCpu = new CpuRegistersDialog (this, -1);
|
2002-09-16 19:28:19 +04:00
|
|
|
#if BX_DEBUGGER
|
2002-09-19 00:59:05 +04:00
|
|
|
showCpu->SetTitle ("Bochs Debugger");
|
|
|
|
#else
|
|
|
|
showCpu->SetTitle ("CPU Registers");
|
2002-09-16 19:28:19 +04:00
|
|
|
#endif
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
showCpu->Init ();
|
|
|
|
} else {
|
2002-09-22 08:36:09 +04:00
|
|
|
showCpu->CopyParamToGui ();
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
}
|
|
|
|
showCpu->Show (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnShowKeyboard(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
if (showKbd == NULL) {
|
|
|
|
showKbd = new ParamDialog (this, -1);
|
|
|
|
showKbd->SetTitle ("Keyboard State (incomplete, this is a demo)");
|
|
|
|
showKbd->AddParam (SIM->get_param (BXP_KBD_PARAMETERS));
|
|
|
|
showKbd->Init ();
|
|
|
|
} else {
|
2002-09-22 08:36:09 +04:00
|
|
|
showKbd->CopyParamToGui ();
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
}
|
|
|
|
showKbd->Show (TRUE);
|
|
|
|
}
|
|
|
|
|
2002-09-19 00:59:05 +04:00
|
|
|
#if BX_DEBUGGER
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
void MyFrame::OnDebugLog(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
2002-11-01 18:28:41 +03:00
|
|
|
wxASSERT (showDebugLog != NULL);
|
2002-09-22 08:36:09 +04:00
|
|
|
showDebugLog->CopyParamToGui ();
|
2002-09-19 00:59:05 +04:00
|
|
|
showDebugLog->Show (TRUE);
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
}
|
|
|
|
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
void
|
|
|
|
MyFrame::DebugBreak ()
|
|
|
|
{
|
|
|
|
if (debugCommand) {
|
|
|
|
delete debugCommand;
|
|
|
|
debugCommand = NULL;
|
|
|
|
}
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
wxASSERT (showDebugLog != NULL);
|
|
|
|
showDebugLog->AppendCommand ("*** break ***");
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
SIM->debug_break ();
|
|
|
|
}
|
2002-09-19 00:59:05 +04:00
|
|
|
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
void
|
|
|
|
MyFrame::DebugCommand (wxString cmd)
|
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
safeWxStrcpy (buf, cmd, sizeof(buf));
|
|
|
|
DebugCommand (buf);
|
|
|
|
}
|
|
|
|
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
void
|
|
|
|
MyFrame::DebugCommand (const char *cmd)
|
|
|
|
{
|
|
|
|
wxLogDebug ("debugger command: %s", cmd);
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
wxASSERT (showDebugLog != NULL);
|
|
|
|
showDebugLog->AppendCommand (cmd);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
if (debugCommand != NULL) {
|
|
|
|
// one is already waiting
|
|
|
|
wxLogDebug ("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 ("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 ("storing debugger command '%s'", tmp);
|
|
|
|
debugCommand = tmp;
|
|
|
|
}
|
2002-09-19 00:59:05 +04:00
|
|
|
}
|
2002-09-16 19:28:19 +04:00
|
|
|
#endif
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
void MyFrame::OnQuit(wxCommandEvent& event)
|
|
|
|
{
|
2002-10-07 08:01:00 +04:00
|
|
|
wxBochsClosing = true;
|
|
|
|
if (!sim_thread) {
|
|
|
|
// no simulation thread is running. Just close the window.
|
|
|
|
Close( TRUE );
|
|
|
|
} else {
|
|
|
|
SIM->set_notify_callback (&MyApp::DefaultCallback, this);
|
|
|
|
// ask the simulator to stop. When it stops it will close this frame.
|
|
|
|
SetStatusText ("Waiting for simulation to stop...");
|
|
|
|
OnKillSim (event);
|
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
wxString str;
|
|
|
|
str.Printf ("Bochs x86 Emulator version %s (wxWindows port)", VER_STRING);
|
2003-08-23 09:34:40 +04:00
|
|
|
wxMessageBox( str, "About Bochs", wxOK | wxICON_INFORMATION, this );
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
// update the menu items, status bar, etc.
|
2002-10-25 15:44:41 +04:00
|
|
|
void MyFrame::simStatusChanged (StatusChange change, bx_bool popupNotify) {
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
switch (change) {
|
|
|
|
case Start: // running
|
2002-09-05 20:01:34 +04:00
|
|
|
wxLogStatus ("Starting Bochs simulation");
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
menuSimulate->Enable (ID_Simulate_Start, FALSE);
|
|
|
|
menuSimulate->Enable (ID_Simulate_PauseResume, TRUE);
|
|
|
|
menuSimulate->Enable (ID_Simulate_Stop, TRUE);
|
|
|
|
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Pause");
|
|
|
|
break;
|
|
|
|
case Stop: // not running
|
2002-09-05 20:01:34 +04:00
|
|
|
wxLogStatus ("Simulation stopped");
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
menuSimulate->Enable (ID_Simulate_Start, TRUE);
|
|
|
|
menuSimulate->Enable (ID_Simulate_PauseResume, FALSE);
|
|
|
|
menuSimulate->Enable (ID_Simulate_Stop, FALSE);
|
|
|
|
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Pause");
|
|
|
|
// 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)
|
2002-11-01 18:28:41 +03:00
|
|
|
wxMessageBox("Bochs simulation has stopped.", "Bochs Stopped",
|
2003-08-23 09:34:40 +04:00
|
|
|
wxOK | wxICON_INFORMATION, this);
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
break;
|
|
|
|
case Pause: // pause
|
2002-09-05 20:01:34 +04:00
|
|
|
wxLogStatus ("Pausing simulation");
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Resume");
|
|
|
|
break;
|
|
|
|
case Resume: // resume
|
2002-09-05 20:01:34 +04:00
|
|
|
wxLogStatus ("Resuming simulation");
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
menuSimulate->SetLabel (ID_Simulate_PauseResume, "&Pause");
|
|
|
|
break;
|
|
|
|
}
|
2002-08-30 03:18:10 +04:00
|
|
|
bool canConfigure = (change == Stop);
|
|
|
|
menuConfiguration->Enable (ID_Config_New, canConfigure);
|
|
|
|
menuConfiguration->Enable (ID_Config_Read, canConfigure);
|
2002-10-25 16:36:44 +04:00
|
|
|
#ifdef __GNUC__
|
2002-09-23 00:56:12 +04:00
|
|
|
#warning For now, leave ATA devices so that you configure them during runtime. Otherwise you cannot change the CD image at runtime.
|
2002-10-25 16:36:44 +04:00
|
|
|
#endif
|
2002-12-30 20:04:43 +03:00
|
|
|
// only enabled ATA channels with a cdrom connected are available at runtime
|
|
|
|
for (unsigned i=0; i<4; i++) {
|
|
|
|
if (!SIM->get_param_bool((bx_id)(BXP_ATA0_PRESENT+i))->get ()) {
|
|
|
|
menuEdit->Enable (ID_Edit_ATA0+i, canConfigure);
|
|
|
|
} else {
|
|
|
|
if ( (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_TYPE+i*2))->get () != BX_ATA_DEVICE_CDROM) &&
|
|
|
|
(SIM->get_param_num((bx_id)(BXP_ATA0_SLAVE_TYPE+i*2))->get () != BX_ATA_DEVICE_CDROM) ) {
|
|
|
|
menuEdit->Enable (ID_Edit_ATA0+i, canConfigure);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-08-30 03:18:10 +04:00
|
|
|
menuEdit->Enable( ID_Edit_Boot, canConfigure);
|
|
|
|
menuEdit->Enable( ID_Edit_Memory, canConfigure);
|
|
|
|
menuEdit->Enable( ID_Edit_Sound, canConfigure);
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
menuEdit->Enable( ID_Edit_Cmos, canConfigure);
|
2003-08-22 20:52:38 +04:00
|
|
|
menuEdit->Enable( ID_Edit_Timing, canConfigure);
|
2002-08-30 03:18:10 +04:00
|
|
|
menuEdit->Enable( ID_Edit_Network, canConfigure);
|
|
|
|
menuEdit->Enable( ID_Edit_Keyboard, canConfigure);
|
- add generic dialog class called ParamDialog. You create it, call
a method to add the parameters (bx_param_c) that you want to edit,
and display it. It knows how to display and edit boolean, int,
enum, and string, so it can do a reasonable job on any parameter.
The end result is not as nice as a box that you lay out by hand, but
it's decent. The most obvious thing that's missing from
ParamDialog-generated dialogs is that I haven't found a way to
make an "Enable" button that enables/disables a bunch of other
parameters. I'll keep thinking about that.
- using ParamDialog, I made dialogs for Sound, Cmos, Serial/Parallel,
32bitOSloader, and an ugly catch-all category called other.
Now I believe you can edit every single option using wxWindows.
2002-09-03 09:32:49 +04:00
|
|
|
menuEdit->Enable( ID_Edit_Serial_Parallel, canConfigure);
|
|
|
|
menuEdit->Enable( ID_Edit_LoadHack, canConfigure);
|
2002-08-30 03:18:10 +04:00
|
|
|
menuEdit->Enable( ID_Edit_Other, canConfigure);
|
|
|
|
// during simulation, certain menu options like the floppy disk
|
|
|
|
// can be modified under some circumstances. A floppy drive can
|
|
|
|
// only be edited if it was enabled at boot time.
|
2002-08-30 10:06:36 +04:00
|
|
|
bx_param_c *param;
|
|
|
|
param = SIM->get_param(BXP_FLOPPYA);
|
|
|
|
menuEdit->Enable (ID_Edit_FD_0, canConfigure || param->get_enabled ());
|
|
|
|
param = SIM->get_param(BXP_FLOPPYB);
|
|
|
|
menuEdit->Enable (ID_Edit_FD_1, canConfigure || param->get_enabled ());
|
2002-09-23 00:56:12 +04:00
|
|
|
/*
|
|
|
|
// this menu item removed, since you can configure the cdrom from the
|
|
|
|
// ATA controller menu items instead.
|
|
|
|
param = SIM->get_first_cdrom ();
|
|
|
|
menuEdit->Enable (ID_Edit_Cdrom, canConfigure || (param&¶m->get_enabled ()));
|
|
|
|
*/
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
}
|
|
|
|
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
void MyFrame::OnStartSim(wxCommandEvent& event)
|
2002-04-18 04:22:20 +04:00
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(sim_thread_lock);
|
|
|
|
if (sim_thread != NULL) {
|
2002-11-01 18:28:41 +03:00
|
|
|
wxMessageBox (
|
|
|
|
"Can't start Bochs simulator, because it is already running",
|
2003-08-23 09:34:40 +04:00
|
|
|
"Already Running", wxOK | wxICON_ERROR, this);
|
2002-11-01 18:28:41 +03:00
|
|
|
return;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
2002-10-26 17:22:47 +04:00
|
|
|
// check that display library is set to wx. If not, give a warning and
|
|
|
|
// change it to wx. It is technically possible to use other vga libraries
|
|
|
|
// with the wx config interface, but there are still some significant
|
|
|
|
// problems.
|
2002-10-25 01:07:56 +04:00
|
|
|
bx_param_enum_c *gui_param = SIM->get_param_enum(BXP_SEL_DISPLAY_LIBRARY);
|
|
|
|
char *gui_name = gui_param->get_choice (gui_param->get ());
|
|
|
|
if (strcmp (gui_name, "wx") != 0) {
|
|
|
|
wxMessageBox (
|
2002-10-26 17:22:47 +04:00
|
|
|
"The display library was not set to wxWindows. When you use the\n"
|
|
|
|
"wxWindows configuration interface, you must also select the wxWindows\n"
|
|
|
|
"display library. I will change it to 'wx' now.",
|
2003-08-23 09:34:40 +04:00
|
|
|
"display library error", wxOK | wxICON_WARNING, this);
|
2002-10-25 01:07:56 +04:00
|
|
|
if (!gui_param->set_by_name ("wx")) {
|
2002-10-26 17:22:47 +04:00
|
|
|
wxASSERT (0 && "Could not set display library setting to 'wx");
|
2002-10-25 01:07:56 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// give warning about restarting the simulation
|
2002-04-18 04:22:20 +04:00
|
|
|
start_bochs_times++;
|
|
|
|
if (start_bochs_times>1) {
|
2002-11-01 18:28:41 +03:00
|
|
|
wxMessageBox (
|
|
|
|
"You have already started the simulator once this session. Due to memory leaks and bugs in init code, you may get unstable behavior.",
|
2003-08-23 09:34:40 +04:00
|
|
|
"2nd time warning", wxOK | wxICON_WARNING, this);
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
num_events = 0; // clear the queue of events for bochs to handle
|
|
|
|
sim_thread = new SimThread (this);
|
|
|
|
sim_thread->Create ();
|
|
|
|
sim_thread->Run ();
|
|
|
|
wxLogDebug ("Simulator thread has started.");
|
|
|
|
// set up callback for events from simulator thread
|
|
|
|
SIM->set_notify_callback (&SimThread::SiminterfaceCallback, sim_thread);
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
simStatusChanged (Start);
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnPauseResumeSim(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(sim_thread_lock);
|
|
|
|
if (sim_thread) {
|
|
|
|
if (sim_thread->IsPaused ()) {
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
simStatusChanged (Resume);
|
2002-11-01 18:28:41 +03:00
|
|
|
sim_thread->Resume ();
|
|
|
|
} else {
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
simStatusChanged (Pause);
|
2002-11-01 18:28:41 +03:00
|
|
|
sim_thread->Pause ();
|
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnKillSim(wxCommandEvent& WXUNUSED(event))
|
|
|
|
{
|
|
|
|
// DON'T use a critical section here. Delete implicitly calls
|
|
|
|
// OnSimThreadExit, which also tries to lock sim_thread_lock.
|
|
|
|
// If we grab the lock at this level, deadlock results.
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
wxLogDebug ("OnKillSim()");
|
2002-09-14 01:53:37 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
// the sim_thread may be waiting for a debugger command. If so, send
|
|
|
|
// it a "quit"
|
|
|
|
DebugCommand ("quit");
|
|
|
|
#endif
|
2002-04-18 04:22:20 +04:00
|
|
|
if (sim_thread) {
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
sim_thread->Delete ();
|
|
|
|
// Next time the simulator reaches bx_real_sim_c::periodic() it
|
|
|
|
// will quit. This is better than killing the thread because it
|
|
|
|
// gives it a chance to clean up after itself.
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MyFrame::OnSimThreadExit () {
|
|
|
|
wxCriticalSectionLocker lock (sim_thread_lock);
|
|
|
|
sim_thread = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
MyFrame::HandleAskParamString (bx_param_string_c *param)
|
|
|
|
{
|
|
|
|
wxLogDebug ("HandleAskParamString start");
|
|
|
|
bx_param_num_c *opt = param->get_options ();
|
|
|
|
wxASSERT (opt != NULL);
|
|
|
|
int n_opt = opt->get ();
|
2003-08-23 13:52:26 +04:00
|
|
|
char *msg = param->get_name ();
|
2002-04-18 04:22:20 +04:00
|
|
|
char *newval = NULL;
|
|
|
|
wxDialog *dialog = NULL;
|
- fixed up ParamDialog to correctly handle "trees" of parameters. A
bx_list_c can now be displayed as either a wxStaticBox with the
child parameters inside, or as a wxNotebook with each child
parameter in a separate tab. (The children can also be lists of
course.) The default display is the wxStaticBox type, but if you
set the option bit bx_list_c::USE_TAB_WINDOW in the list,
ParamDialog will use the wxNotebook display instead.
- to get the param trees working, I created a new struct
AddParamContext, which is passed to AddParam(). This struct is
critical when AddParam calls itself recursively to display lists
within lists.
- use the wxNotebook display feature for the ATA0,1,2,3 controller
dialog box. Now instead of being hundreds of pixels tall, it is
reasonable height with three different tabs. This fixed bug
#619074: "wx: ATA interface editor too tall" and was the whole
reason I started messing with this at all.
plus some minor cleanups
- when I added the enum constant bx_list_c::USE_TAB_WINDOW, I also
removed the BX_ prefix from all the other enum constants that are
used in parameter options in siminterface.cc. Since these constants
are enums within a class, there is no possibility of namespace
conflicts so the prefix is not needed.
- added wxADJUST_MINSIZE to all wxChoice controls, since that tells
wxWindows to adjust its size to the length of the longest string.
- instead of calling SetSize or SetSizeHints on every textcontrol with
a hardcoded width, I am using just two wxSize specifications for
everything: either normalTextSize or longTextSize.
- edit names of a few menus and params. For example now instead of
the tab saying "Master ATA device on channel 0" it will say
"First HD/CD on channel 0".
Modified Files:
main.cc gui/control.cc gui/gui.cc gui/siminterface.cc gui/siminterface.h
gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
2002-10-06 06:37:28 +04:00
|
|
|
if (n_opt & param->IS_FILENAME) {
|
2002-04-18 04:22:20 +04:00
|
|
|
// use file open dialog
|
2002-11-01 18:28:41 +03:00
|
|
|
long style =
|
|
|
|
(n_opt & param->SAVE_FILE_DIALOG) ? wxSAVE|wxOVERWRITE_PROMPT : wxOPEN;
|
2002-04-18 04:22:20 +04:00
|
|
|
wxLogDebug ("HandleAskParamString: create dialog");
|
2002-11-01 18:28:41 +03:00
|
|
|
wxFileDialog *fdialog = new wxFileDialog (this, msg, "", "", "*.*", style);
|
2002-04-18 04:22:20 +04:00
|
|
|
wxLogDebug ("HandleAskParamString: before showmodal");
|
2002-11-01 18:28:41 +03:00
|
|
|
if (fdialog->ShowModal() == wxID_OK)
|
|
|
|
newval = (char *)fdialog->GetPath().c_str ();
|
2002-04-18 04:22:20 +04:00
|
|
|
wxLogDebug ("HandleAskParamString: after showmodal");
|
2002-11-01 18:28:41 +03:00
|
|
|
dialog = fdialog; // so I can delete it
|
2002-04-18 04:22:20 +04:00
|
|
|
} else {
|
|
|
|
// use simple string dialog
|
2002-11-01 18:28:41 +03:00
|
|
|
long style = wxOK|wxCANCEL;
|
|
|
|
wxTextEntryDialog *tdialog = new wxTextEntryDialog (this, msg, "Enter new value", wxString(param->getptr ()), style);
|
|
|
|
if (tdialog->ShowModal() == wxID_OK)
|
|
|
|
newval = (char *)tdialog->GetValue().c_str ();
|
|
|
|
dialog = tdialog; // so I can delete it
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// newval points to memory inside the dialog. As soon as dialog is deleted,
|
|
|
|
// newval points to junk. So be sure to copy the text out before deleting
|
|
|
|
// it!
|
2002-04-18 04:22:20 +04:00
|
|
|
if (newval && strlen(newval)>0) {
|
2002-11-01 18:28:41 +03:00
|
|
|
// change floppy path to this value.
|
|
|
|
wxLogDebug ("Setting param %s to '%s'", param->get_name (), newval);
|
|
|
|
param->set (newval);
|
|
|
|
delete dialog;
|
|
|
|
return 1;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
delete dialog;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is called when the simulator needs to ask the user to choose
|
|
|
|
// a value or setting. For example, when the user indicates that he wants
|
|
|
|
// to change the floppy disk image for drive A, an ask-param event is created
|
|
|
|
// with the parameter id set to BXP_FLOPPYA_PATH. The simulator blocks until
|
|
|
|
// the gui has displayed a dialog and received a selection from the user.
|
|
|
|
// In the current implemention, the GUI will look up the parameter's
|
|
|
|
// data structure using SIM->get_param() and then call the set method on the
|
|
|
|
// parameter to change the param. The return value only needs to return
|
|
|
|
// success or failure (failure = cancelled, or not implemented).
|
|
|
|
// Returns 1 if the user chose a value and the param was modified.
|
|
|
|
// Returns 0 if the user cancelled.
|
|
|
|
// Returns -1 if the gui doesn't know how to ask for that param.
|
|
|
|
int
|
|
|
|
MyFrame::HandleAskParam (BxEvent *event)
|
|
|
|
{
|
|
|
|
wxASSERT (event->type == BX_SYNC_EVT_ASK_PARAM);
|
|
|
|
|
|
|
|
bx_param_c *param = event->u.param.param;
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
Raise (); // bring window to front so that you will see the dialog
|
2002-04-18 04:22:20 +04:00
|
|
|
switch (param->get_type ())
|
|
|
|
{
|
|
|
|
case BXT_PARAM_STRING:
|
|
|
|
return HandleAskParamString ((bx_param_string_c *)param);
|
|
|
|
default:
|
|
|
|
{
|
2002-11-01 18:28:41 +03:00
|
|
|
wxString msg;
|
2002-12-01 19:11:12 +03:00
|
|
|
msg.Printf ("ask param for parameter type %d is not implemented in wxWindows",
|
|
|
|
param->get_type ());
|
2003-08-23 09:34:40 +04:00
|
|
|
wxMessageBox( msg, "not implemented", wxOK | wxICON_ERROR, this );
|
2002-11-01 18:28:41 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
switch (param) {
|
|
|
|
case BXP_FLOPPYA_PATH:
|
|
|
|
case BXP_FLOPPYB_PATH:
|
|
|
|
case BXP_DISKC_PATH:
|
|
|
|
case BXP_DISKD_PATH:
|
|
|
|
case BXP_CDROM_PATH:
|
2002-11-01 18:28:41 +03:00
|
|
|
{
|
|
|
|
Raise(); // bring window to front so dialog shows
|
|
|
|
char *msg;
|
|
|
|
if (param==BXP_FLOPPYA_PATH || param==BXP_FLOPPYB_PATH)
|
|
|
|
msg = "Choose new floppy disk image file";
|
2002-04-18 04:22:20 +04:00
|
|
|
else if (param==BXP_DISKC_PATH || param==BXP_DISKD_PATH)
|
2002-11-01 18:28:41 +03:00
|
|
|
msg = "Choose new hard disk image file";
|
2002-04-18 04:22:20 +04:00
|
|
|
else if (param==BXP_CDROM_PATH)
|
2002-11-01 18:28:41 +03:00
|
|
|
msg = "Choose new CDROM image file";
|
|
|
|
else
|
|
|
|
msg = "Choose new image file";
|
|
|
|
wxFileDialog dialog(this, msg, "", "", "*.*", 0);
|
|
|
|
int ret = dialog.ShowModal();
|
|
|
|
if (ret == wxID_OK)
|
|
|
|
{
|
|
|
|
char *newpath = (char *)dialog.GetPath().c_str ();
|
|
|
|
if (newpath && strlen(newpath)>0) {
|
|
|
|
// change floppy path to this value.
|
|
|
|
bx_param_string_c *Opath = SIM->get_param_string (param);
|
|
|
|
assert (Opath != NULL);
|
|
|
|
wxLogDebug ("Setting floppy %c path to '%s'",
|
|
|
|
param == BXP_FLOPPYA_PATH ? 'A' : 'B',
|
|
|
|
newpath);
|
|
|
|
Opath->set (newpath);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
default:
|
2002-11-01 18:28:41 +03:00
|
|
|
wxLogError ("HandleAskParam: parameter %d, not implemented", event->u.param.id);
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return -1; // could not display
|
|
|
|
}
|
|
|
|
|
2002-08-29 18:59:37 +04:00
|
|
|
// This is called from the wxWindows GUI thread, when a Sim2CI event
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
// is found. (It got there via wxPostEvent in SiminterfaceCallback2, which is
|
|
|
|
// executed in the simulator Thread.)
|
2002-04-18 04:22:20 +04:00
|
|
|
void
|
2002-08-29 18:59:37 +04:00
|
|
|
MyFrame::OnSim2CIEvent (wxCommandEvent& event)
|
2002-04-18 04:22:20 +04:00
|
|
|
{
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
IFDBG_EVENT (wxLogDebug ("received a bochs event in the GUI thread"));
|
2002-04-18 04:22:20 +04:00
|
|
|
BxEvent *be = (BxEvent *) event.GetEventObject ();
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
IFDBG_EVENT (wxLogDebug ("event type = %d", (int) be->type));
|
2002-04-18 04:22:20 +04:00
|
|
|
// all cases should return. sync event handlers MUST send back a
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
// response. async event handlers MUST delete the event.
|
2002-04-18 04:22:20 +04:00
|
|
|
switch (be->type) {
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
case BX_ASYNC_EVT_REFRESH:
|
|
|
|
RefreshDialogs ();
|
2002-09-26 02:54:23 +04:00
|
|
|
break;
|
2002-04-18 04:22:20 +04:00
|
|
|
case BX_SYNC_EVT_ASK_PARAM:
|
|
|
|
wxLogDebug ("before HandleAskParam");
|
|
|
|
be->retcode = HandleAskParam (be);
|
|
|
|
wxLogDebug ("after HandleAskParam");
|
2002-09-26 02:54:23 +04:00
|
|
|
// return a copy of the event back to the sender.
|
2002-04-18 04:22:20 +04:00
|
|
|
sim_thread->SendSyncResponse(be);
|
|
|
|
wxLogDebug ("after SendSyncResponse");
|
2002-09-26 02:54:23 +04:00
|
|
|
break;
|
2002-09-19 00:59:05 +04:00
|
|
|
#if BX_DEBUGGER
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
case BX_ASYNC_EVT_DBG_MSG:
|
|
|
|
showDebugLog->AppendText (be->u.logmsg.msg);
|
|
|
|
// free the char* which was allocated in dbg_printf
|
2002-09-16 19:28:19 +04:00
|
|
|
delete [] ((char*) be->u.logmsg.msg);
|
2002-09-26 02:54:23 +04:00
|
|
|
break;
|
2002-09-16 19:28:19 +04:00
|
|
|
#endif
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
case BX_SYNC_EVT_LOG_ASK:
|
2002-04-18 04:22:20 +04:00
|
|
|
case BX_ASYNC_EVT_LOG_MSG:
|
2002-09-25 22:40:15 +04:00
|
|
|
OnLogMsg (be);
|
2002-09-26 02:54:23 +04:00
|
|
|
break;
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
case BX_SYNC_EVT_GET_DBG_COMMAND:
|
|
|
|
wxLogDebug ("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 ()) {
|
2002-11-01 18:28:41 +03:00
|
|
|
wxCommandEvent unused;
|
|
|
|
OnShowCpu (unused);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// a debugger command is waiting for us!
|
2002-09-22 06:43:37 +04:00
|
|
|
wxLogDebug ("sending debugger command '%s' that was waiting", debugCommand);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
be->u.debugcmd.command = debugCommand;
|
|
|
|
debugCommand = NULL; // ready for the next one
|
|
|
|
debugCommandEvent = NULL;
|
|
|
|
be->retcode = 1;
|
|
|
|
sim_thread->SendSyncResponse (be);
|
|
|
|
}
|
2002-09-26 02:54:23 +04:00
|
|
|
break;
|
2002-04-18 04:22:20 +04:00
|
|
|
default:
|
2002-08-29 18:59:37 +04:00
|
|
|
wxLogDebug ("OnSim2CIEvent: event type %d ignored", (int)be->type);
|
2002-09-26 02:54:23 +04:00
|
|
|
if (!BX_EVT_IS_ASYNC(be->type)) {
|
|
|
|
// if it's a synchronous event, and we fail to send back a response,
|
|
|
|
// the sim thread will wait forever. So send something!
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
sim_thread->SendSyncResponse(be);
|
|
|
|
}
|
2002-09-26 02:54:23 +04:00
|
|
|
break;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
2002-09-26 02:54:23 +04:00
|
|
|
if (BX_EVT_IS_ASYNC(be->type))
|
|
|
|
delete be;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
2002-09-25 22:40:15 +04:00
|
|
|
void MyFrame::OnLogMsg (BxEvent *be) {
|
|
|
|
wxLogDebug ("log msg: level=%d, prefix='%s', msg='%s'",
|
|
|
|
be->u.logmsg.level,
|
|
|
|
be->u.logmsg.prefix,
|
|
|
|
be->u.logmsg.msg);
|
2002-09-26 02:54:23 +04:00
|
|
|
if (be->type == BX_ASYNC_EVT_LOG_MSG)
|
|
|
|
return; // we don't have any place to display log messages
|
|
|
|
else
|
2002-09-25 22:40:15 +04:00
|
|
|
wxASSERT (be->type == BX_SYNC_EVT_LOG_ASK);
|
|
|
|
wxString levelName (SIM->get_log_level_name (be->u.logmsg.level));
|
|
|
|
LogMsgAskDialog dlg (this, -1, levelName); // panic, error, etc.
|
|
|
|
#if !BX_DEBUGGER
|
|
|
|
dlg.EnableButton (dlg.DEBUG, FALSE);
|
|
|
|
#endif
|
|
|
|
dlg.SetContext (be->u.logmsg.prefix);
|
|
|
|
dlg.SetMessage (be->u.logmsg.msg);
|
|
|
|
int n = dlg.ShowModal ();
|
2002-10-25 15:44:41 +04:00
|
|
|
bx_bool dontAsk = dlg.GetDontAsk ();
|
2002-09-25 22:40:15 +04:00
|
|
|
// turn the return value into the constant that logfunctions::ask is
|
|
|
|
// expecting. 0=continue, 1=continue but ignore future messages from this
|
|
|
|
// device, 2=die, 3=dump core, 4=debugger. FIXME: yuck. replace hardcoded
|
|
|
|
// constants in logfunctions::ask with enum or defined constant.
|
|
|
|
if (n==0) {
|
|
|
|
n = dontAsk? 1 : 0;
|
|
|
|
} else {
|
|
|
|
n=n+1;
|
|
|
|
}
|
|
|
|
be->retcode = n;
|
|
|
|
wxLogDebug ("you chose %d", n);
|
|
|
|
// This can be called from two different contexts:
|
|
|
|
// 1) before sim_thread starts, the default application callback can
|
|
|
|
// call OnLogMsg to display messages.
|
|
|
|
// 2) after the sim_thread starts, the sim_thread callback can call
|
|
|
|
// OnLogMsg to display messages
|
|
|
|
if (sim_thread)
|
|
|
|
sim_thread->SendSyncResponse (be); // only for case #2
|
|
|
|
}
|
|
|
|
|
2002-08-28 11:54:53 +04:00
|
|
|
bool
|
|
|
|
MyFrame::editFloppyValidate (FloppyConfigDialog *dialog)
|
|
|
|
{
|
2002-08-30 10:06:36 +04:00
|
|
|
// haven't done anything with this 'feature'
|
2002-08-28 11:54:53 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::editFloppyConfig (int drive)
|
|
|
|
{
|
|
|
|
FloppyConfigDialog dlg (this, -1);
|
2002-09-01 19:27:33 +04:00
|
|
|
dlg.SetDriveName (wxString (drive==0? BX_FLOPPY0_NAME : BX_FLOPPY1_NAME));
|
2002-08-28 11:54:53 +04:00
|
|
|
dlg.SetCapacityChoices (n_floppy_type_names, floppy_type_names);
|
|
|
|
bx_list_c *list = (bx_list_c*) SIM->get_param ((drive==0)? BXP_FLOPPYA : BXP_FLOPPYB);
|
|
|
|
if (!list) { wxLogError ("floppy object param is null"); return; }
|
|
|
|
bx_param_filename_c *fname = (bx_param_filename_c*) list->get(0);
|
|
|
|
bx_param_enum_c *disktype = (bx_param_enum_c *) list->get(1);
|
|
|
|
bx_param_enum_c *status = (bx_param_enum_c *) list->get(2);
|
|
|
|
if (fname->get_type () != BXT_PARAM_STRING
|
|
|
|
|| disktype->get_type () != BXT_PARAM_ENUM
|
|
|
|
|| status->get_type() != BXT_PARAM_ENUM) {
|
|
|
|
wxLogError ("floppy params have wrong type");
|
2002-08-28 19:27:26 +04:00
|
|
|
return;
|
2002-08-28 11:54:53 +04:00
|
|
|
}
|
2002-08-30 10:06:36 +04:00
|
|
|
dlg.AddRadio ("Not Present", "");
|
2002-08-30 03:18:10 +04:00
|
|
|
dlg.AddRadio ("Ejected", "none");
|
2002-09-04 22:39:20 +04:00
|
|
|
#if defined(__linux__)
|
2002-08-28 11:54:53 +04:00
|
|
|
dlg.AddRadio ("Physical floppy drive /dev/fd0", "/dev/fd0");
|
|
|
|
dlg.AddRadio ("Physical floppy drive /dev/fd1", "/dev/fd1");
|
2002-09-04 22:39:20 +04:00
|
|
|
#elif defined(WIN32)
|
|
|
|
dlg.AddRadio ("Physical floppy drive A:", "A:");
|
|
|
|
dlg.AddRadio ("Physical floppy drive B:", "B:");
|
|
|
|
#else
|
|
|
|
// add your favorite operating system here
|
|
|
|
#endif
|
2002-08-28 11:54:53 +04:00
|
|
|
dlg.SetCapacity (disktype->get () - disktype->get_min ());
|
|
|
|
dlg.SetFilename (fname->getptr ());
|
|
|
|
dlg.SetValidateFunc (editFloppyValidate);
|
2002-08-30 10:06:36 +04:00
|
|
|
if (disktype->get() == BX_FLOPPY_NONE) {
|
|
|
|
dlg.SetRadio (0);
|
|
|
|
} else if (!strcmp ("none", fname->getptr ())) {
|
|
|
|
dlg.SetRadio (1);
|
|
|
|
} else {
|
|
|
|
// otherwise the SetFilename() should have done the right thing.
|
|
|
|
}
|
2002-08-28 11:54:53 +04:00
|
|
|
int n = dlg.ShowModal ();
|
2002-09-05 20:27:06 +04:00
|
|
|
wxLogMessage ("floppy config returned %d", n);
|
2002-09-01 23:38:08 +04:00
|
|
|
if (n==wxID_OK) {
|
2002-09-01 19:27:33 +04:00
|
|
|
char filename[1024];
|
|
|
|
wxString fn (dlg.GetFilename ());
|
|
|
|
strncpy (filename, fn.c_str (), sizeof(filename));
|
2002-09-05 20:27:06 +04:00
|
|
|
wxLogMessage ("filename is '%s'", filename);
|
|
|
|
wxLogMessage ("capacity = %d (%s)", dlg.GetCapacity(), floppy_type_names[dlg.GetCapacity ()]);
|
2002-09-01 19:27:33 +04:00
|
|
|
fname->set (filename);
|
2002-08-28 11:54:53 +04:00
|
|
|
disktype->set (disktype->get_min () + dlg.GetCapacity ());
|
2002-08-30 10:06:36 +04:00
|
|
|
if (dlg.GetRadio () == 0)
|
|
|
|
disktype->set (BX_FLOPPY_NONE);
|
2002-08-28 11:54:53 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-12 19:31:41 +03:00
|
|
|
void MyFrame::editFirstCdrom ()
|
2002-08-30 10:06:36 +04:00
|
|
|
{
|
2002-12-12 19:31:41 +03:00
|
|
|
bx_param_c *firstcd = SIM->get_first_cdrom ();
|
2002-12-12 19:52:21 +03:00
|
|
|
if (!firstcd) {
|
2003-08-23 09:34:40 +04:00
|
|
|
wxMessageBox ("No CDROM drive is enabled. Use Edit:ATA to set one up.",
|
|
|
|
"No CDROM", wxOK | wxICON_ERROR, this );
|
2002-12-12 19:52:21 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
ParamDialog dlg (this, -1);
|
2002-12-12 19:31:41 +03:00
|
|
|
dlg.SetTitle ("Configure CDROM");
|
|
|
|
dlg.AddParam (firstcd);
|
|
|
|
dlg.ShowModal ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::OnEditATA (wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
int id = event.GetId ();
|
|
|
|
int channel = id - ID_Edit_ATA0;
|
|
|
|
ParamDialog dlg (this, -1);
|
|
|
|
wxString str;
|
|
|
|
str.Printf ("Configure ATA%d", channel);
|
|
|
|
dlg.SetTitle (str);
|
- fixed up ParamDialog to correctly handle "trees" of parameters. A
bx_list_c can now be displayed as either a wxStaticBox with the
child parameters inside, or as a wxNotebook with each child
parameter in a separate tab. (The children can also be lists of
course.) The default display is the wxStaticBox type, but if you
set the option bit bx_list_c::USE_TAB_WINDOW in the list,
ParamDialog will use the wxNotebook display instead.
- to get the param trees working, I created a new struct
AddParamContext, which is passed to AddParam(). This struct is
critical when AddParam calls itself recursively to display lists
within lists.
- use the wxNotebook display feature for the ATA0,1,2,3 controller
dialog box. Now instead of being hundreds of pixels tall, it is
reasonable height with three different tabs. This fixed bug
#619074: "wx: ATA interface editor too tall" and was the whole
reason I started messing with this at all.
plus some minor cleanups
- when I added the enum constant bx_list_c::USE_TAB_WINDOW, I also
removed the BX_ prefix from all the other enum constants that are
used in parameter options in siminterface.cc. Since these constants
are enums within a class, there is no possibility of namespace
conflicts so the prefix is not needed.
- added wxADJUST_MINSIZE to all wxChoice controls, since that tells
wxWindows to adjust its size to the length of the longest string.
- instead of calling SetSize or SetSizeHints on every textcontrol with
a hardcoded width, I am using just two wxSize specifications for
everything: either normalTextSize or longTextSize.
- edit names of a few menus and params. For example now instead of
the tab saying "Master ATA device on channel 0" it will say
"First HD/CD on channel 0".
Modified Files:
main.cc gui/control.cc gui/gui.cc gui/siminterface.cc gui/siminterface.h
gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
2002-10-06 06:37:28 +04:00
|
|
|
dlg.AddParam (SIM->get_param ((bx_id)(BXP_ATA0_MENU+channel)));
|
2002-09-23 00:56:12 +04:00
|
|
|
dlg.ShowModal ();
|
2002-08-28 19:27:26 +04:00
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
void MyFrame::OnToolbarClick(wxCommandEvent& event)
|
|
|
|
{
|
|
|
|
wxLogDebug ("clicked toolbar thingy");
|
|
|
|
bx_toolbar_buttons which = BX_TOOLBAR_UNDEFINED;
|
|
|
|
int id = event.GetId ();
|
|
|
|
switch (id) {
|
|
|
|
case ID_Toolbar_Power:which = BX_TOOLBAR_POWER; break;
|
|
|
|
case ID_Toolbar_Reset: which = BX_TOOLBAR_RESET; break;
|
2002-08-30 03:18:10 +04:00
|
|
|
case ID_Edit_FD_0:
|
2002-08-28 11:54:53 +04:00
|
|
|
// floppy config dialog box
|
|
|
|
editFloppyConfig (0);
|
|
|
|
break;
|
2002-08-30 03:18:10 +04:00
|
|
|
case ID_Edit_FD_1:
|
2002-08-28 11:54:53 +04:00
|
|
|
// floppy config dialog box
|
|
|
|
editFloppyConfig (1);
|
|
|
|
break;
|
2002-12-12 19:31:41 +03:00
|
|
|
case ID_Edit_Cdrom:
|
|
|
|
// cdrom config dialog box (first cd only)
|
|
|
|
editFirstCdrom ();
|
|
|
|
break;
|
2002-04-18 04:22:20 +04:00
|
|
|
case ID_Toolbar_Copy: which = BX_TOOLBAR_COPY; break;
|
|
|
|
case ID_Toolbar_Paste: which = BX_TOOLBAR_PASTE; break;
|
|
|
|
case ID_Toolbar_Snapshot: which = BX_TOOLBAR_SNAPSHOT; break;
|
|
|
|
case ID_Toolbar_Config: which = BX_TOOLBAR_CONFIG; break;
|
|
|
|
case ID_Toolbar_Mouse_en: which = BX_TOOLBAR_MOUSE_EN; break;
|
2002-08-09 10:16:43 +04:00
|
|
|
case ID_Toolbar_User: which = BX_TOOLBAR_USER; break;
|
2002-04-18 04:22:20 +04:00
|
|
|
default:
|
|
|
|
wxLogError ("unknown toolbar id %d", id);
|
|
|
|
}
|
|
|
|
if (num_events < MAX_EVENTS) {
|
|
|
|
event_queue[num_events].type = BX_ASYNC_EVT_TOOLBAR;
|
|
|
|
event_queue[num_events].u.toolbar.button = which;
|
|
|
|
num_events++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
// warning: This can be called from the simulator thread!!!
|
|
|
|
bool MyFrame::WantRefresh () {
|
|
|
|
bool anyShowing = false;
|
|
|
|
if (showCpu!=NULL && showCpu->IsShowing ()) anyShowing = true;
|
|
|
|
if (showKbd!=NULL && showKbd->IsShowing ()) anyShowing = true;
|
|
|
|
return anyShowing;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MyFrame::RefreshDialogs () {
|
2002-09-22 08:36:09 +04:00
|
|
|
if (showCpu!=NULL && showCpu->IsShowing ()) showCpu->CopyParamToGui ();
|
|
|
|
if (showKbd!=NULL && showKbd->IsShowing ()) showKbd->CopyParamToGui ();
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Simulation Thread
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
void *
|
|
|
|
SimThread::Entry (void)
|
2002-09-05 20:01:34 +04:00
|
|
|
{
|
2002-04-18 04:22:20 +04:00
|
|
|
// run all the rest of the Bochs simulator code. This function will
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// run forever, unless a "kill_bochs_request" is issued. The shutdown
|
|
|
|
// procedure is as follows:
|
2002-04-18 04:22:20 +04:00
|
|
|
// - user selects "Kill Simulation" or GUI decides to kill bochs
|
|
|
|
// - GUI calls sim_thread->Delete ()
|
|
|
|
// - sim continues to run until the next time it reaches SIM->periodic().
|
|
|
|
// - SIM->periodic() sends a synchronous tick event to the GUI, which
|
|
|
|
// finally calls TestDestroy() and realizes it needs to stop. It
|
2002-10-07 08:01:00 +04:00
|
|
|
// sets the sync event return code to -1. SIM->periodic() notices
|
|
|
|
// the -1 and calls quit_sim, which longjumps to quit_context, which is
|
|
|
|
// right here in SimThread::Entry.
|
2002-04-18 04:22:20 +04:00
|
|
|
// - Entry() exits and the thread stops. Whew.
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
wxLogDebug ("in SimThread, starting at bx_continue_after_config_interface");
|
|
|
|
static jmp_buf context; // this must not go out of scope. maybe static not needed
|
|
|
|
if (setjmp (context) == 0) {
|
2002-09-05 20:01:34 +04:00
|
|
|
SIM->set_quit_context (&context);
|
2002-11-01 18:19:48 +03:00
|
|
|
SIM->begin_simulation (bx_startup_flags.argc, bx_startup_flags.argv);
|
2002-10-25 01:07:56 +04:00
|
|
|
wxLogDebug ("in SimThread, SIM->begin_simulation() exited normally");
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
} else {
|
2002-10-25 01:07:56 +04:00
|
|
|
wxLogDebug ("in SimThread, SIM->begin_simulation() exited by longjmp");
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
}
|
2002-10-06 23:21:05 +04:00
|
|
|
SIM->set_quit_context (NULL);
|
2002-09-05 20:01:34 +04:00
|
|
|
// it is possible that the whole interface has already been shut down.
|
|
|
|
// If so, we must end immediately.
|
2002-10-07 08:01:00 +04:00
|
|
|
// we're in the sim thread, so we must get a gui mutex before calling
|
|
|
|
// wxwindows methods.
|
|
|
|
wxLogDebug ("SimThread::Entry: get gui mutex");
|
|
|
|
wxMutexGuiEnter();
|
|
|
|
if (!wxBochsClosing) {
|
|
|
|
wxLogDebug ("SimThread::Entry: sim thread ending. call simStatusChanged");
|
2002-09-05 20:01:34 +04:00
|
|
|
theFrame->simStatusChanged (theFrame->Stop, true);
|
2002-10-07 08:01:00 +04:00
|
|
|
} else {
|
|
|
|
wxLogMessage ("SimThread::Entry: the gui is waiting for sim to finish. Now that it has finished, I will close the frame.");
|
|
|
|
theFrame->Close (TRUE);
|
2002-09-05 20:01:34 +04:00
|
|
|
}
|
2002-10-07 08:01:00 +04:00
|
|
|
wxMutexGuiLeave();
|
2002-04-18 04:22:20 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SimThread::OnExit ()
|
|
|
|
{
|
|
|
|
// notify the MyFrame that the bochs thread has died. I can't adjust
|
|
|
|
// the sim_thread directly because it's private.
|
|
|
|
frame->OnSimThreadExit ();
|
2002-09-25 22:40:15 +04:00
|
|
|
// don't use this SimThread's callback function anymore. Use the
|
|
|
|
// application default callback.
|
|
|
|
SIM->set_notify_callback (&MyApp::DefaultCallback, this);
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// Event handler function for BxEvents coming from the simulator.
|
|
|
|
// This function is declared static so that I can get a usable
|
|
|
|
// function pointer for it. The function pointer is passed to
|
|
|
|
// SIM->set_notify_callback so that the siminterface can call this
|
|
|
|
// function when it needs to contact the gui. It will always be
|
|
|
|
// called with a pointer to the SimThread as the first argument, and
|
|
|
|
// it will be called from the simulator thread, not the GUI thread.
|
2002-04-18 04:22:20 +04:00
|
|
|
BxEvent *
|
|
|
|
SimThread::SiminterfaceCallback (void *thisptr, BxEvent *event)
|
|
|
|
{
|
|
|
|
SimThread *me = (SimThread *)thisptr;
|
|
|
|
// call the normal non-static method now that we know the this pointer.
|
|
|
|
return me->SiminterfaceCallback2 (event);
|
|
|
|
}
|
|
|
|
|
|
|
|
// callback function for sim thread events. This is called from
|
|
|
|
// the sim thread, not the GUI thread. So any GUI actions must be
|
|
|
|
// thread safe. Most events are handled by packaging up the event
|
|
|
|
// in a wxEvent of some kind, and posting it to the GUI thread for
|
|
|
|
// processing.
|
|
|
|
BxEvent *
|
|
|
|
SimThread::SiminterfaceCallback2 (BxEvent *event)
|
|
|
|
{
|
|
|
|
//wxLogDebug ("SiminterfaceCallback with event type=%d", (int)event->type);
|
|
|
|
event->retcode = 0; // default return code
|
|
|
|
int async = BX_EVT_IS_ASYNC(event->type);
|
|
|
|
if (!async) {
|
|
|
|
// for synchronous events, clear away any previous response. There
|
2002-11-01 18:28:41 +03:00
|
|
|
// can only be one synchronous event pending at a time.
|
2002-04-18 04:22:20 +04:00
|
|
|
ClearSyncResponse ();
|
2002-11-01 18:28:41 +03:00
|
|
|
event->retcode = -1; // default to error
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// tick event must be handled right here in the bochs thread.
|
|
|
|
if (event->type == BX_SYNC_EVT_TICK) {
|
2002-11-01 18:28:41 +03:00
|
|
|
if (TestDestroy ()) {
|
|
|
|
// tell simulator to quit
|
|
|
|
event->retcode = -1;
|
|
|
|
} else {
|
|
|
|
event->retcode = 0;
|
|
|
|
}
|
|
|
|
return event;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
//encapsulate the bxevent in a wxwindows event
|
2002-08-29 18:59:37 +04:00
|
|
|
wxCommandEvent wxevent (wxEVT_COMMAND_MENU_SELECTED, ID_Sim2CI_Event);
|
2002-04-18 04:22:20 +04:00
|
|
|
wxevent.SetEventObject ((wxEvent *)event);
|
2002-09-11 07:52:27 +04:00
|
|
|
if (isSimThread ()) {
|
|
|
|
IFDBG_EVENT (wxLogDebug ("Sending an event to the window"));
|
|
|
|
wxPostEvent (frame, wxevent);
|
|
|
|
// if it is an asynchronous event, return immediately. The event will be
|
|
|
|
// freed by the recipient in the GUI thread.
|
|
|
|
if (async) return NULL;
|
|
|
|
wxLogDebug ("SiminterfaceCallback2: synchronous event; waiting for response");
|
|
|
|
// now wait forever for the GUI to post a response.
|
|
|
|
BxEvent *response = NULL;
|
|
|
|
while (response == NULL) {
|
2002-11-01 18:28:41 +03:00
|
|
|
response = GetSyncResponse ();
|
|
|
|
if (!response) {
|
|
|
|
//wxLogDebug ("no sync response yet, waiting");
|
|
|
|
this->Sleep (20);
|
|
|
|
}
|
|
|
|
// don't get stuck here if the gui is trying to close.
|
|
|
|
if (wxBochsClosing) {
|
|
|
|
wxLogDebug ("breaking out of sync event wait because gui is closing");
|
|
|
|
event->retcode = -1;
|
|
|
|
return event;
|
|
|
|
}
|
2002-09-11 07:52:27 +04:00
|
|
|
}
|
|
|
|
wxASSERT (response != NULL);
|
|
|
|
return response;
|
|
|
|
} else {
|
|
|
|
wxLogDebug ("sim2ci event sent from the GUI thread. calling handler directly");
|
|
|
|
theFrame->OnSim2CIEvent (wxevent);
|
|
|
|
return event;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SimThread::ClearSyncResponse ()
|
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(sim2gui_mailbox_lock);
|
|
|
|
if (sim2gui_mailbox != NULL) {
|
|
|
|
wxLogDebug ("WARNING: ClearSyncResponse is throwing away an event that was previously in the mailbox");
|
|
|
|
}
|
|
|
|
sim2gui_mailbox = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SimThread::SendSyncResponse (BxEvent *event)
|
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(sim2gui_mailbox_lock);
|
|
|
|
if (sim2gui_mailbox != NULL) {
|
|
|
|
wxLogDebug ("WARNING: SendSyncResponse is throwing away an event that was previously in the mailbox");
|
|
|
|
}
|
|
|
|
sim2gui_mailbox = event;
|
|
|
|
}
|
|
|
|
|
|
|
|
BxEvent *
|
|
|
|
SimThread::GetSyncResponse ()
|
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(sim2gui_mailbox_lock);
|
|
|
|
BxEvent *event = sim2gui_mailbox;
|
|
|
|
sim2gui_mailbox = NULL;
|
|
|
|
return event;
|
|
|
|
}
|
|
|
|
|
2002-09-03 00:13:52 +04:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// utility
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
void
|
|
|
|
safeWxStrcpy (char *dest, wxString src, int destlen)
|
|
|
|
{
|
|
|
|
wxString tmp (src);
|
|
|
|
strncpy (dest, tmp.c_str (), destlen);
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
dest[destlen-1] = 0;
|
2002-09-03 00:13:52 +04:00
|
|
|
}
|
2002-10-25 01:07:56 +04:00
|
|
|
|
2002-11-19 08:47:45 +03:00
|
|
|
#endif /* if BX_WITH_WX */
|