2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2002-09-03 20:00:50 +04:00
|
|
|
// $Id: siminterface.cc,v 1.51 2002-09-03 16:00:50 bdenney Exp $
|
2001-10-03 17:10:38 +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
|
|
|
// See siminterface.h for description of the siminterface concept.
|
|
|
|
// Basically, the siminterface is visible from both the simulator and
|
|
|
|
// the configuration user interface, and allows them to talk to each other.
|
2001-06-08 11:20:07 +04:00
|
|
|
|
|
|
|
#include "bochs.h"
|
|
|
|
|
|
|
|
bx_simulator_interface_c *SIM = NULL;
|
2001-06-11 10:35:18 +04:00
|
|
|
logfunctions *siminterface_log = NULL;
|
|
|
|
#define LOG_THIS siminterface_log->
|
2001-06-08 11:20:07 +04:00
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
// bx_simulator_interface just defines the interface that the Bochs simulator
|
|
|
|
// and the gui will use to talk to each other. None of the methods of
|
|
|
|
// bx_simulator_interface are implemented; they are all virtual. The
|
|
|
|
// bx_real_sim_c class is a child of bx_simulator_interface_c, and it
|
|
|
|
// implements all the methods. The idea is that a gui needs to know only
|
|
|
|
// definition of bx_simulator_interface to talk to Bochs. The gui should
|
|
|
|
// not need to include bochs.h.
|
|
|
|
//
|
|
|
|
// I made this separation to ensure that all guis use the siminterface to do
|
|
|
|
// access bochs internals, instead of accessing things like
|
|
|
|
// bx_keyboard.s.internal_buffer[4] (or whatever) directly. -Bryce
|
|
|
|
//
|
|
|
|
|
2001-06-08 11:20:07 +04:00
|
|
|
class bx_real_sim_c : public bx_simulator_interface_c {
|
2001-06-11 18:03:35 +04:00
|
|
|
sim_interface_callback_t callback;
|
2002-04-18 04:22:20 +04:00
|
|
|
void *callback_ptr;
|
2001-06-18 18:11:55 +04:00
|
|
|
int init_done;
|
|
|
|
bx_param_c **param_registry;
|
|
|
|
int registry_alloc_size;
|
2001-06-22 01:24:05 +04:00
|
|
|
int 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
|
|
|
// save context to jump to if we must quit unexpectedly
|
|
|
|
jmp_buf *quit_context;
|
2001-06-11 18:03:35 +04:00
|
|
|
public:
|
|
|
|
bx_real_sim_c ();
|
2001-12-22 23:58:25 +03:00
|
|
|
virtual ~bx_real_sim_c ();
|
- 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
|
|
|
virtual void set_quit_context (jmp_buf *context) { quit_context = context; }
|
2001-06-18 18:11:55 +04:00
|
|
|
virtual int get_init_done () { return init_done; }
|
|
|
|
virtual int set_init_done (int n) { init_done = n; return 0;}
|
2002-04-18 04:22:20 +04:00
|
|
|
virtual void get_param_id_range (int *min, int *max) {
|
|
|
|
*min = BXP_NULL;
|
|
|
|
*max = BXP_THIS_IS_THE_LAST-1;
|
|
|
|
}
|
2001-06-18 18:11:55 +04:00
|
|
|
virtual int register_param (bx_id id, bx_param_c *it);
|
2002-08-30 20:23:36 +04:00
|
|
|
virtual void reset_all_param ();
|
2001-06-16 23:29:59 +04:00
|
|
|
virtual bx_param_c *get_param (bx_id id);
|
|
|
|
virtual bx_param_num_c *get_param_num (bx_id id);
|
2001-06-17 03:08:32 +04:00
|
|
|
virtual bx_param_string_c *get_param_string (bx_id id);
|
2001-06-10 00:01:12 +04:00
|
|
|
virtual int get_n_log_modules ();
|
|
|
|
virtual char *get_prefix (int mod);
|
|
|
|
virtual int get_log_action (int mod, int level);
|
|
|
|
virtual void set_log_action (int mod, int level, int action);
|
|
|
|
virtual char *get_action_name (int action);
|
2001-11-14 03:23:08 +03:00
|
|
|
virtual const char *get_log_level_name (int level);
|
2001-06-10 00:01:12 +04:00
|
|
|
virtual int get_max_log_level ();
|
2002-04-18 04:22:20 +04:00
|
|
|
virtual void quit_sim (int code);
|
2001-06-10 00:01:12 +04:00
|
|
|
virtual int get_default_rc (char *path, int len);
|
|
|
|
virtual int read_rc (char *path);
|
2001-06-11 10:35:18 +04:00
|
|
|
virtual int write_rc (char *path, int overwrite);
|
2001-06-10 00:01:12 +04:00
|
|
|
virtual int get_log_file (char *path, int len);
|
|
|
|
virtual int set_log_file (char *path);
|
2002-06-26 18:42:35 +04:00
|
|
|
virtual int get_log_prefix (char *prefix, int len);
|
|
|
|
virtual int set_log_prefix (char *prefix);
|
2001-06-10 00:01:12 +04:00
|
|
|
virtual int get_floppy_options (int drive, bx_floppy_options *out);
|
|
|
|
virtual int get_cdrom_options (int drive, bx_cdrom_options *out);
|
|
|
|
virtual char *get_floppy_type_name (int type);
|
2002-04-18 04:22:20 +04:00
|
|
|
virtual void set_notify_callback (sim_interface_callback_t func, void *arg);
|
2002-08-29 18:59:37 +04:00
|
|
|
virtual BxEvent* sim_to_ci_event (BxEvent *event);
|
2002-04-18 04:22:20 +04:00
|
|
|
virtual int log_msg (const char *prefix, int level, char *msg);
|
|
|
|
virtual int ask_param (bx_id which);
|
|
|
|
// ask the user for a pathname
|
|
|
|
virtual int ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags);
|
|
|
|
// called at a regular interval, currently by the keyboard handler.
|
|
|
|
virtual void periodic ();
|
2002-08-30 00:13:05 +04:00
|
|
|
virtual int create_disk_image (const char *filename, int sectors, Boolean overwrite);
|
2001-06-08 11:20:07 +04:00
|
|
|
};
|
|
|
|
|
2001-06-16 23:29:59 +04:00
|
|
|
bx_param_c *
|
|
|
|
bx_real_sim_c::get_param (bx_id id)
|
|
|
|
{
|
2001-06-18 18:11:55 +04:00
|
|
|
BX_ASSERT (id >= BXP_NULL && id < BXP_THIS_IS_THE_LAST);
|
|
|
|
int index = (int)id - BXP_NULL;
|
|
|
|
bx_param_c *retval = param_registry[index];
|
2002-04-18 04:22:20 +04:00
|
|
|
if (!retval)
|
|
|
|
BX_INFO (("get_param can't find id %u", id));
|
2001-06-18 18:11:55 +04:00
|
|
|
return retval;
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bx_param_num_c *
|
|
|
|
bx_real_sim_c::get_param_num (bx_id id) {
|
|
|
|
bx_param_c *generic = get_param(id);
|
|
|
|
if (generic==NULL) {
|
|
|
|
BX_PANIC (("get_param_num(%u) could not find a parameter", id));
|
2001-06-17 03:08:32 +04:00
|
|
|
return NULL;
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
2001-06-20 18:01:39 +04:00
|
|
|
int type = generic->get_type ();
|
2001-06-21 18:37:55 +04:00
|
|
|
if (type == BXT_PARAM_NUM || type == BXT_PARAM_BOOL || type == BXT_PARAM_ENUM)
|
2001-06-16 23:29:59 +04:00
|
|
|
return (bx_param_num_c *)generic;
|
|
|
|
BX_PANIC (("get_param_num %u could not find an integer parameter with that id", id));
|
2001-06-17 03:08:32 +04:00
|
|
|
return NULL;
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
|
|
|
|
2001-06-17 03:08:32 +04:00
|
|
|
bx_param_string_c *
|
|
|
|
bx_real_sim_c::get_param_string (bx_id id) {
|
|
|
|
bx_param_c *generic = get_param(id);
|
|
|
|
if (generic==NULL) {
|
|
|
|
BX_PANIC (("get_param_string(%u) could not find a parameter", id));
|
|
|
|
return NULL;
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
2001-06-17 03:08:32 +04:00
|
|
|
if (generic->get_type () == BXT_PARAM_STRING)
|
|
|
|
return (bx_param_string_c *)generic;
|
|
|
|
BX_PANIC (("get_param_string %u could not find an integer parameter with that id", id));
|
|
|
|
return NULL;
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
void bx_init_siminterface ()
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2001-06-11 10:35:18 +04:00
|
|
|
siminterface_log = new logfunctions ();
|
2001-06-27 23:16:01 +04:00
|
|
|
siminterface_log->put ("CTRL");
|
2001-06-11 10:35:18 +04:00
|
|
|
siminterface_log->settype(CTRLLOG);
|
2001-06-10 00:01:12 +04:00
|
|
|
if (SIM == NULL)
|
2001-06-08 11:20:07 +04:00
|
|
|
SIM = new bx_real_sim_c();
|
|
|
|
}
|
|
|
|
|
|
|
|
bx_simulator_interface_c::bx_simulator_interface_c ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2001-06-11 18:03:35 +04:00
|
|
|
bx_real_sim_c::bx_real_sim_c ()
|
|
|
|
{
|
|
|
|
callback = NULL;
|
2002-04-18 04:22:20 +04:00
|
|
|
callback_ptr = NULL;
|
|
|
|
|
|
|
|
enabled = 1;
|
|
|
|
int i;
|
2001-06-19 08:55:01 +04:00
|
|
|
init_done = 0;
|
2001-06-18 18:11:55 +04:00
|
|
|
registry_alloc_size = BXP_THIS_IS_THE_LAST - BXP_NULL;
|
2001-06-19 02:37:46 +04:00
|
|
|
param_registry = new bx_param_c* [registry_alloc_size];
|
2002-04-18 04:22:20 +04:00
|
|
|
for (i=0; i<registry_alloc_size; i++)
|
|
|
|
param_registry[i] = NULL;
|
- 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
|
|
|
quit_context = NULL;
|
2001-06-18 18:11:55 +04:00
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
// called by constructor of bx_param_c, so that every parameter that is
|
|
|
|
// initialized gets registered. This builds a list of all parameters
|
|
|
|
// which can be used to look them up by number (get_param).
|
2001-12-21 22:33:18 +03:00
|
|
|
bx_real_sim_c::~bx_real_sim_c ()
|
|
|
|
{
|
|
|
|
if ( param_registry != NULL )
|
|
|
|
{
|
|
|
|
delete [] param_registry;
|
|
|
|
param_registry = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-18 18:11:55 +04:00
|
|
|
int
|
|
|
|
bx_real_sim_c::register_param (bx_id id, bx_param_c *it)
|
|
|
|
{
|
2002-04-18 04:22:20 +04:00
|
|
|
if (id == BXP_NULL) return 0;
|
2001-06-18 18:11:55 +04:00
|
|
|
BX_ASSERT (id >= BXP_NULL && id < BXP_THIS_IS_THE_LAST);
|
|
|
|
int index = (int)id - BXP_NULL;
|
2002-04-18 04:22:20 +04:00
|
|
|
if (this->param_registry[index] != NULL) {
|
|
|
|
BX_INFO (("register_param is overwriting parameter id %d", id));
|
|
|
|
}
|
2001-06-18 18:11:55 +04:00
|
|
|
this->param_registry[index] = it;
|
2001-06-22 17:37:08 +04:00
|
|
|
return 0;
|
2001-06-11 18:03:35 +04:00
|
|
|
}
|
|
|
|
|
2002-08-30 20:23:36 +04:00
|
|
|
void
|
|
|
|
bx_real_sim_c::reset_all_param ()
|
|
|
|
{
|
|
|
|
bx_reset_options ();
|
|
|
|
}
|
|
|
|
|
2001-06-08 11:20:07 +04:00
|
|
|
int
|
|
|
|
bx_real_sim_c::get_n_log_modules ()
|
|
|
|
{
|
|
|
|
return io->get_n_logfns ();
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
bx_real_sim_c::get_prefix (int mod)
|
|
|
|
{
|
|
|
|
logfunc_t *logfn = io->get_logfn (mod);
|
|
|
|
return logfn->getprefix ();
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::get_log_action (int mod, int level)
|
|
|
|
{
|
|
|
|
logfunc_t *logfn = io->get_logfn (mod);
|
|
|
|
return logfn->getonoff (level);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_real_sim_c::set_log_action (int mod, int level, int action)
|
|
|
|
{
|
|
|
|
logfunc_t *logfn = io->get_logfn (mod);
|
2001-06-22 17:37:08 +04:00
|
|
|
logfn->setonoff (level, action);
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
bx_real_sim_c::get_action_name (int action)
|
|
|
|
{
|
|
|
|
return io->getaction (action);
|
|
|
|
}
|
|
|
|
|
2001-11-14 03:23:08 +03:00
|
|
|
const char *
|
2001-06-08 11:20:07 +04:00
|
|
|
bx_real_sim_c::get_log_level_name (int level)
|
|
|
|
{
|
|
|
|
return io->getlevel (level);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::get_max_log_level ()
|
|
|
|
{
|
2001-06-11 10:35:18 +04:00
|
|
|
return N_LOGLEV;
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-04-18 04:22:20 +04:00
|
|
|
bx_real_sim_c::quit_sim (int code) {
|
|
|
|
BX_INFO (("quit_sim called"));
|
- 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
|
|
|
// use longjmp to quit cleanly, no matter where in the stack we are.
|
|
|
|
//fprintf (stderr, "using longjmp() to jump directly to the quit context!\n");
|
|
|
|
longjmp (*quit_context, 1);
|
|
|
|
BX_PANIC (("in bx_real_sim_c::quit_sim, longjmp should never return"));
|
2002-04-18 04:22:20 +04:00
|
|
|
#if BX_WITH_WX
|
|
|
|
// in wxWindows, the whole simulator is running in a separate thread.
|
|
|
|
// our only job is to end the thread as soon as possible, NOT to shut
|
|
|
|
// down the whole application with an exit.
|
2002-08-25 09:21:16 +04:00
|
|
|
BX_CPU(0)->async_event = 1;
|
|
|
|
BX_CPU(0)->kill_bochs_request = 1;
|
2002-04-18 04:22:20 +04:00
|
|
|
// the cpu loop will exit very soon after this condition is set.
|
|
|
|
#else
|
|
|
|
// just a single thread. Use exit() to stop the application.
|
|
|
|
if (!code)
|
2001-06-10 00:01:12 +04:00
|
|
|
BX_PANIC (("Quit simulation command"));
|
2001-06-08 11:20:07 +04:00
|
|
|
::exit (0);
|
2002-04-18 04:22:20 +04:00
|
|
|
#endif
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
2001-06-10 00:01:12 +04:00
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::get_default_rc (char *path, int len)
|
|
|
|
{
|
|
|
|
char *rc = bx_find_bochsrc ();
|
|
|
|
if (rc == NULL) return -1;
|
|
|
|
strncpy (path, rc, len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::read_rc (char *rc)
|
|
|
|
{
|
2001-06-13 17:36:12 +04:00
|
|
|
return bx_read_configuration (rc);
|
2001-06-10 00:01:12 +04:00
|
|
|
}
|
|
|
|
|
2001-06-11 10:35:18 +04:00
|
|
|
// return values:
|
|
|
|
// 0: written ok
|
|
|
|
// -1: failed
|
|
|
|
// -2: already exists, and overwrite was off
|
|
|
|
int
|
|
|
|
bx_real_sim_c::write_rc (char *rc, int overwrite)
|
|
|
|
{
|
|
|
|
return bx_write_configuration (rc, overwrite);
|
|
|
|
}
|
|
|
|
|
2001-06-10 00:01:12 +04:00
|
|
|
int
|
|
|
|
bx_real_sim_c::get_log_file (char *path, int len)
|
|
|
|
{
|
2001-06-20 18:01:39 +04:00
|
|
|
strncpy (path, bx_options.log.Ofilename->getptr (), len);
|
2001-06-10 00:01:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::set_log_file (char *path)
|
|
|
|
{
|
2001-06-20 18:01:39 +04:00
|
|
|
bx_options.log.Ofilename->set (path);
|
2001-06-10 00:01:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-06-26 18:42:35 +04:00
|
|
|
int
|
|
|
|
bx_real_sim_c::get_log_prefix (char *prefix, int len)
|
|
|
|
{
|
|
|
|
strncpy (prefix, bx_options.log.Oprefix->getptr (), len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::set_log_prefix (char *prefix)
|
|
|
|
{
|
|
|
|
bx_options.log.Oprefix->set (prefix);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-06-10 00:01:12 +04:00
|
|
|
int
|
|
|
|
bx_real_sim_c::get_floppy_options (int drive, bx_floppy_options *out)
|
|
|
|
{
|
|
|
|
*out = (drive==0)? bx_options.floppya : bx_options.floppyb;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
bx_real_sim_c::get_cdrom_options (int drive, bx_cdrom_options *out)
|
|
|
|
{
|
|
|
|
BX_ASSERT (drive == 0);
|
|
|
|
*out = bx_options.cdromd;
|
2001-06-12 00:51:15 +04:00
|
|
|
return 0;
|
2001-06-10 00:01:12 +04:00
|
|
|
}
|
|
|
|
|
2002-08-01 11:37:56 +04:00
|
|
|
char *floppy_type_names[] = { "none", "1.2M", "1.44M", "2.88M", "720K", "360K", NULL };
|
2002-08-30 00:13:05 +04:00
|
|
|
int floppy_type_n_sectors[] = { -1, 80*2*15, 80*2*18, 80*2*36, 80*2*9, 40*2*9 };
|
2002-08-01 11:37:56 +04:00
|
|
|
int n_floppy_type_names = 6;
|
2001-06-20 18:01:39 +04:00
|
|
|
char *floppy_status_names[] = { "ejected", "inserted", NULL };
|
|
|
|
int n_floppy_status_names = 2;
|
2002-01-30 13:30:52 +03:00
|
|
|
char *floppy_bootdisk_names[] = { "floppy", "hard","cdrom", NULL };
|
|
|
|
int n_floppy_bootdisk_names = 3;
|
2001-06-21 23:57:21 +04:00
|
|
|
char *loader_os_names[] = { "none", "linux", "nullkernel", NULL };
|
|
|
|
int n_loader_os_names = 3;
|
2001-12-12 13:38:39 +03:00
|
|
|
char *keyboard_type_names[] = { "xt", "at", "mf", NULL };
|
2002-04-23 11:44:34 +04:00
|
|
|
int n_keyboard_type_names = 3;
|
2001-06-10 00:01:12 +04:00
|
|
|
|
|
|
|
char *
|
|
|
|
bx_real_sim_c::get_floppy_type_name (int type)
|
|
|
|
{
|
2002-08-01 11:37:56 +04:00
|
|
|
BX_ASSERT (type >= BX_FLOPPY_NONE && type <= BX_FLOPPY_LAST);
|
2001-06-10 00:01:12 +04:00
|
|
|
type -= BX_FLOPPY_NONE;
|
|
|
|
return floppy_type_names[type];
|
|
|
|
}
|
|
|
|
|
2001-06-11 18:03:35 +04:00
|
|
|
void
|
2002-04-18 04:22:20 +04:00
|
|
|
bx_real_sim_c::set_notify_callback (sim_interface_callback_t func, void *arg)
|
2001-06-11 18:03:35 +04:00
|
|
|
{
|
|
|
|
callback = func;
|
2002-04-18 04:22:20 +04:00
|
|
|
callback_ptr = arg;
|
2001-06-11 18:03:35 +04:00
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
BxEvent *
|
2002-08-29 18:59:37 +04:00
|
|
|
bx_real_sim_c::sim_to_ci_event (BxEvent *event)
|
2001-06-11 18:03:35 +04:00
|
|
|
{
|
2001-06-12 00:51:15 +04:00
|
|
|
if (callback == NULL) {
|
2001-06-11 18:03:35 +04:00
|
|
|
BX_ERROR (("notify called, but no callback function is registered"));
|
2002-04-18 04:22:20 +04:00
|
|
|
return NULL;
|
2001-06-12 00:51:15 +04:00
|
|
|
} else {
|
2002-04-18 04:22:20 +04:00
|
|
|
return (*callback)(callback_ptr, event);
|
2001-06-11 18:03:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
|
|
|
|
int
|
2002-04-18 04:22:20 +04:00
|
|
|
bx_real_sim_c::log_msg (const char *prefix, int level, char *msg)
|
2001-06-11 18:03:35 +04:00
|
|
|
{
|
2002-04-18 04:22:20 +04:00
|
|
|
BxEvent *be = new BxEvent ();
|
- 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
|
|
|
be->type = BX_SYNC_EVT_LOG_ASK;
|
2002-04-18 04:22:20 +04:00
|
|
|
be->u.logmsg.prefix = (char *)prefix;
|
|
|
|
be->u.logmsg.level = level;
|
|
|
|
be->u.logmsg.msg = msg;
|
2001-06-11 18:03:35 +04:00
|
|
|
//fprintf (stderr, "calling notify.\n");
|
2002-08-29 18:59:37 +04:00
|
|
|
BxEvent *response = sim_to_ci_event (be);
|
2002-04-18 04:22:20 +04:00
|
|
|
return response? response->retcode : -1;
|
2001-06-11 18:03:35 +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
|
|
|
// Called by simulator whenever it needs the user to choose a new value
|
|
|
|
// for a registered parameter. Create a synchronous ASK_PARAM event,
|
2002-08-29 18:59:37 +04:00
|
|
|
// send it to the CI, and wait for the response. The CI will call the
|
- 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
|
|
|
// set() method on the parameter if the user changes the value.
|
|
|
|
int
|
|
|
|
bx_real_sim_c::ask_param (bx_id param)
|
|
|
|
{
|
|
|
|
bx_param_c *paramptr = SIM->get_param(param);
|
|
|
|
BX_ASSERT (paramptr != NULL);
|
|
|
|
// create appropriate event
|
|
|
|
BxEvent *event = new BxEvent ();
|
|
|
|
event->type = BX_SYNC_EVT_ASK_PARAM;
|
|
|
|
event->u.param.param = paramptr;
|
2002-08-29 18:59:37 +04:00
|
|
|
BxEvent *response = sim_to_ci_event (event);
|
- 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
|
|
|
return response->retcode;
|
|
|
|
}
|
2001-06-16 03:52:34 +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
|
|
|
int
|
|
|
|
bx_real_sim_c::ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags)
|
|
|
|
{
|
|
|
|
// implement using ASK_PARAM on a newly created param. I can't use
|
|
|
|
// ask_param because I don't intend to register this param.
|
|
|
|
BxEvent event;
|
|
|
|
bx_param_string_c param (BXP_NULL, "filename", prompt, the_default, maxlen);
|
|
|
|
flags |= param.BX_IS_FILENAME;
|
|
|
|
param.get_options()->set (flags);
|
|
|
|
event.type = BX_SYNC_EVT_ASK_PARAM;
|
|
|
|
event.u.param.param = ¶m;
|
2002-08-29 18:59:37 +04:00
|
|
|
BxEvent *response = sim_to_ci_event (&event);
|
- 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
|
|
|
BX_ASSERT ((response == &event));
|
|
|
|
if (event.retcode >= 0)
|
|
|
|
memcpy (filename, param.getptr(), maxlen);
|
|
|
|
return event.retcode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_real_sim_c::periodic ()
|
|
|
|
{
|
|
|
|
// give the GUI a chance to do periodic things on the bochs thread. in
|
|
|
|
// particular, notice if the thread has been asked to die.
|
|
|
|
BxEvent *tick = new BxEvent ();
|
|
|
|
tick->type = BX_SYNC_EVT_TICK;
|
2002-08-29 18:59:37 +04:00
|
|
|
BxEvent *response = sim_to_ci_event (tick);
|
- 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
|
|
|
int retcode = response->retcode;
|
|
|
|
BX_ASSERT (response == tick);
|
|
|
|
delete tick;
|
|
|
|
if (retcode < 0) {
|
|
|
|
BX_INFO (("Bochs thread has been asked to quit."));
|
|
|
|
quit_sim (0);
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
// watch for memory leaks. Allocate a small block of memory, print the
|
|
|
|
// pointer that is returned, then free.
|
|
|
|
BxEvent *memcheck = new BxEvent ();
|
|
|
|
BX_INFO(("memory allocation at %p", memcheck));
|
|
|
|
delete memcheck;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2002-08-30 00:13:05 +04:00
|
|
|
// create a disk image file called filename, size=512 bytes * sectors.
|
|
|
|
// If overwrite is true and the file exists, returns -1 without changing it.
|
|
|
|
// Otherwise, opens up the image and starts writing. Returns -2 if
|
|
|
|
// the image could not be opened, or -3 if there are failures during
|
|
|
|
// write, e.g. disk full.
|
|
|
|
//
|
|
|
|
// wxWindows: This may be called from the gui thread.
|
|
|
|
int
|
|
|
|
bx_real_sim_c::create_disk_image (
|
|
|
|
const char *filename,
|
|
|
|
int sectors,
|
|
|
|
Boolean overwrite)
|
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
if (!overwrite) {
|
|
|
|
// check for existence first
|
|
|
|
fp = fopen (filename, "r");
|
|
|
|
if (fp) {
|
|
|
|
// yes it exists
|
|
|
|
fclose (fp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fp = fopen (filename, "w");
|
|
|
|
if (fp == NULL) {
|
|
|
|
#ifdef HAVE_PERROR
|
|
|
|
char buffer[1024];
|
|
|
|
sprintf (buffer, "while opening '%s' for writing", filename);
|
|
|
|
perror (buffer);
|
|
|
|
// not sure how to get this back into the CI
|
|
|
|
#endif
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
int sec = sectors;
|
|
|
|
/*
|
|
|
|
* seek to sec*512-1 and write a single character.
|
|
|
|
* can't just do: fseek(fp, 512*sec-1, SEEK_SET)
|
|
|
|
* because 512*sec may be too large for signed int.
|
|
|
|
*/
|
|
|
|
while (sec > 0)
|
|
|
|
{
|
|
|
|
/* temp <-- min(sec, 4194303)
|
|
|
|
* 4194303 is (int)(0x7FFFFFFF/512)
|
|
|
|
*/
|
|
|
|
int temp = ((sec < 4194303) ? sec : 4194303);
|
|
|
|
fseek(fp, 512*temp, SEEK_CUR);
|
|
|
|
sec -= temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
fseek(fp, -1, SEEK_CUR);
|
|
|
|
if (fputc('\0', fp) == EOF)
|
|
|
|
{
|
|
|
|
fclose (fp);
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
fclose (fp);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
- 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
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// define methods of bx_param_* and family
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2001-06-16 03:52:34 +04:00
|
|
|
|
|
|
|
bx_object_c::bx_object_c (bx_id id)
|
|
|
|
{
|
|
|
|
this->id = id;
|
|
|
|
this->type = BXT_OBJECT;
|
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
void
|
|
|
|
bx_object_c::set_type (bx_objtype type)
|
2001-06-16 03:52:34 +04:00
|
|
|
{
|
|
|
|
this->type = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
bx_param_c::bx_param_c (bx_id id, char *name, char *description)
|
|
|
|
: bx_object_c (id)
|
|
|
|
{
|
|
|
|
set_type (BXT_PARAM);
|
|
|
|
this->name = name;
|
|
|
|
this->description = description;
|
2001-06-18 18:11:55 +04:00
|
|
|
this->text_format = NULL;
|
|
|
|
this->ask_format = NULL;
|
|
|
|
this->runtime_param = 0;
|
2001-06-21 18:37:55 +04:00
|
|
|
this->enabled = 1;
|
2001-06-18 18:11:55 +04:00
|
|
|
SIM->register_param (id, this);
|
2001-06-16 03:52:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bx_param_num_c::bx_param_num_c (bx_id id,
|
|
|
|
char *name,
|
|
|
|
char *description,
|
|
|
|
Bit32s min, Bit32s max, Bit32s initial_val)
|
|
|
|
: bx_param_c (id, name, description)
|
|
|
|
{
|
|
|
|
set_type (BXT_PARAM_NUM);
|
|
|
|
this->min = min;
|
|
|
|
this->max = max;
|
|
|
|
this->initial_val = initial_val;
|
|
|
|
this->val = initial_val;
|
|
|
|
this->handler = NULL;
|
2001-06-18 18:11:55 +04:00
|
|
|
this->base = 10;
|
2001-06-21 18:37:55 +04:00
|
|
|
set (initial_val);
|
2001-06-16 03:52:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_param_num_c::reset ()
|
|
|
|
{
|
|
|
|
this->val = initial_val;
|
|
|
|
}
|
|
|
|
|
2001-06-21 18:37:55 +04:00
|
|
|
void
|
|
|
|
bx_param_num_c::set_handler (param_event_handler handler)
|
|
|
|
{
|
|
|
|
this->handler = handler;
|
|
|
|
// now that there's a handler, call set once to run the handler immediately
|
|
|
|
//set (get ());
|
|
|
|
}
|
|
|
|
|
2001-06-16 03:52:34 +04:00
|
|
|
Bit32s
|
|
|
|
bx_param_num_c::get ()
|
|
|
|
{
|
2001-06-19 18:20:24 +04:00
|
|
|
if (handler) {
|
|
|
|
// the handler can decide what value to return and/or do some side effect
|
|
|
|
return (*handler)(this, 0, val);
|
|
|
|
} else {
|
|
|
|
// just return the value
|
|
|
|
return val;
|
|
|
|
}
|
2001-06-16 03:52:34 +04:00
|
|
|
}
|
|
|
|
|
2001-06-16 23:29:59 +04:00
|
|
|
void
|
2001-06-16 03:52:34 +04:00
|
|
|
bx_param_num_c::set (Bit32s newval)
|
|
|
|
{
|
2001-06-19 18:20:24 +04:00
|
|
|
if (handler) {
|
|
|
|
// the handler can override the new value and/or perform some side effect
|
2001-09-28 10:02:12 +04:00
|
|
|
val = newval;
|
|
|
|
(*handler)(this, 1, newval);
|
2001-06-19 18:20:24 +04:00
|
|
|
} else {
|
|
|
|
// just set the value. This code does not check max/min.
|
2001-06-16 03:52:34 +04:00
|
|
|
val = newval;
|
2001-06-19 18:20:24 +04:00
|
|
|
}
|
2001-06-21 18:37:55 +04:00
|
|
|
if (val < min || val > max)
|
|
|
|
BX_PANIC (("numerical parameter %s was set to %d, which is out of range %d to %d", get_name (), val, min, max));
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
|
|
|
|
2001-06-20 18:01:39 +04:00
|
|
|
bx_param_bool_c::bx_param_bool_c (bx_id id,
|
|
|
|
char *name,
|
|
|
|
char *description,
|
|
|
|
Bit32s initial_val)
|
|
|
|
: bx_param_num_c (id, name, description, 0, 1, initial_val)
|
|
|
|
{
|
|
|
|
set_type (BXT_PARAM_BOOL);
|
2002-09-03 20:00:50 +04:00
|
|
|
// dependent_list must be initialized before the set(),
|
|
|
|
// because set calls update_dependents().
|
|
|
|
dependent_list = NULL;
|
2001-06-21 18:37:55 +04:00
|
|
|
set (initial_val);
|
2002-09-03 12:44:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void bx_param_bool_c::update_dependents ()
|
|
|
|
{
|
|
|
|
if (dependent_list) {
|
|
|
|
int en = val? 1 : 0;
|
|
|
|
for (int i=0; i<dependent_list->get_size (); i++)
|
|
|
|
dependent_list->get (i)->set_enabled (en);
|
|
|
|
}
|
2001-06-20 18:01:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bx_param_enum_c::bx_param_enum_c (bx_id id,
|
|
|
|
char *name,
|
|
|
|
char *description,
|
|
|
|
char **choices,
|
|
|
|
Bit32s initial_val,
|
|
|
|
Bit32s value_base)
|
|
|
|
: bx_param_num_c (id, name, description, value_base, BX_MAX_INT, initial_val)
|
|
|
|
{
|
2001-06-21 18:37:55 +04:00
|
|
|
set_type (BXT_PARAM_ENUM);
|
2001-06-20 18:01:39 +04:00
|
|
|
this->choices = choices;
|
|
|
|
// count number of choices, set max
|
|
|
|
char **p = choices;
|
|
|
|
while (*p != NULL) p++;
|
2001-06-21 18:37:55 +04:00
|
|
|
this->min = value_base;
|
|
|
|
// now that the max is known, replace the BX_MAX_INT sent to the parent
|
|
|
|
// class constructor with the real max.
|
2001-06-20 18:01:39 +04:00
|
|
|
this->max = value_base + (p - choices - 1);
|
2001-06-21 18:37:55 +04:00
|
|
|
set (initial_val);
|
2001-06-20 18:01:39 +04:00
|
|
|
}
|
|
|
|
|
2001-06-16 23:29:59 +04:00
|
|
|
bx_param_string_c::bx_param_string_c (bx_id id,
|
|
|
|
char *name,
|
|
|
|
char *description,
|
2001-06-18 18:11:55 +04:00
|
|
|
char *initial_val,
|
|
|
|
int maxsize)
|
2001-06-16 23:29:59 +04:00
|
|
|
: bx_param_c (id, name, description)
|
|
|
|
{
|
2001-06-17 03:08:32 +04:00
|
|
|
set_type (BXT_PARAM_STRING);
|
2001-06-18 18:11:55 +04:00
|
|
|
if (maxsize < 0)
|
2001-06-16 23:29:59 +04:00
|
|
|
maxsize = strlen(initial_val) + 1;
|
|
|
|
this->val = new char[maxsize];
|
|
|
|
this->initial_val = new char[maxsize];
|
2001-06-19 02:34:03 +04:00
|
|
|
this->handler = NULL;
|
2001-06-16 23:29:59 +04:00
|
|
|
this->maxsize = maxsize;
|
|
|
|
strncpy (this->val, initial_val, maxsize);
|
|
|
|
strncpy (this->initial_val, initial_val, maxsize);
|
2001-06-21 23:27:05 +04:00
|
|
|
this->options = new bx_param_num_c (BXP_NULL,
|
|
|
|
"stringoptions", NULL, 0, BX_MAX_INT, 0);
|
2001-06-21 18:37:55 +04:00
|
|
|
set (initial_val);
|
2001-06-16 23:29:59 +04:00
|
|
|
}
|
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
bx_param_filename_c::bx_param_filename_c (bx_id id,
|
|
|
|
char *name,
|
|
|
|
char *description,
|
|
|
|
char *initial_val,
|
|
|
|
int maxsize)
|
|
|
|
: bx_param_string_c (id, name, description, initial_val, maxsize)
|
|
|
|
{
|
|
|
|
get_options()->set (BX_IS_FILENAME);
|
|
|
|
}
|
|
|
|
|
2001-12-21 22:33:18 +03:00
|
|
|
bx_param_string_c::~bx_param_string_c ()
|
|
|
|
{
|
|
|
|
if ( this->val != NULL )
|
|
|
|
{
|
|
|
|
delete [] this->val;
|
|
|
|
this->val = NULL;
|
|
|
|
}
|
|
|
|
if ( this->initial_val != NULL )
|
|
|
|
{
|
|
|
|
delete [] this->initial_val;
|
|
|
|
this->initial_val = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( this->options != NULL )
|
|
|
|
{
|
|
|
|
delete [] this->options;
|
|
|
|
this->options = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-16 23:29:59 +04:00
|
|
|
void
|
|
|
|
bx_param_string_c::reset () {
|
|
|
|
strncpy (this->val, this->initial_val, maxsize);
|
|
|
|
}
|
|
|
|
|
2001-06-21 18:37:55 +04:00
|
|
|
void
|
|
|
|
bx_param_string_c::set_handler (param_string_event_handler handler)
|
|
|
|
{
|
|
|
|
this->handler = handler;
|
|
|
|
// now that there's a handler, call set once to run the handler immediately
|
|
|
|
//set (getptr ());
|
|
|
|
}
|
|
|
|
|
2001-06-16 23:29:59 +04:00
|
|
|
Bit32s
|
|
|
|
bx_param_string_c::get (char *buf, int len)
|
|
|
|
{
|
2001-06-21 23:27:05 +04:00
|
|
|
if (options->get () & BX_RAW_BYTES)
|
|
|
|
memcpy (buf, val, len);
|
|
|
|
else
|
|
|
|
strncpy (buf, val, len);
|
2001-06-21 18:37:55 +04:00
|
|
|
if (handler) {
|
|
|
|
// the handler can choose to replace the value in val/len. Also its
|
|
|
|
// return value is passed back as the return value of get.
|
2001-06-16 23:29:59 +04:00
|
|
|
(*handler)(this, 0, buf, len);
|
2001-06-21 18:37:55 +04:00
|
|
|
}
|
2001-06-16 23:29:59 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_param_string_c::set (char *buf)
|
|
|
|
{
|
2001-06-21 23:27:05 +04:00
|
|
|
if (options->get () & BX_RAW_BYTES)
|
|
|
|
memcpy (val, buf, maxsize);
|
|
|
|
else
|
|
|
|
strncpy (val, buf, maxsize);
|
2001-09-28 10:02:12 +04:00
|
|
|
if (handler) {
|
|
|
|
// the handler can return a different char* to be copied into the value
|
|
|
|
buf = (*handler)(this, 1, buf, -1);
|
|
|
|
}
|
2001-06-16 03:52:34 +04:00
|
|
|
}
|
|
|
|
|
2001-06-18 18:11:55 +04:00
|
|
|
bx_list_c::bx_list_c (bx_id id, int maxsize)
|
|
|
|
: bx_param_c (id, "list", "")
|
2001-06-16 03:52:34 +04:00
|
|
|
{
|
2001-06-18 18:11:55 +04:00
|
|
|
set_type (BXT_LIST);
|
|
|
|
this->size = 0;
|
2001-06-19 08:55:01 +04:00
|
|
|
this->maxsize = maxsize;
|
2001-06-19 02:37:46 +04:00
|
|
|
this->list = new bx_param_c* [maxsize];
|
2001-06-18 18:11:55 +04:00
|
|
|
init ();
|
2001-06-16 03:52:34 +04:00
|
|
|
}
|
|
|
|
|
2001-06-21 18:37:55 +04:00
|
|
|
bx_list_c::bx_list_c (bx_id id, char *name, char *description, bx_param_c **init_list)
|
|
|
|
: bx_param_c (id, name, description)
|
2001-06-18 18:11:55 +04:00
|
|
|
{
|
|
|
|
set_type (BXT_LIST);
|
2001-06-19 08:55:01 +04:00
|
|
|
this->size = 0;
|
|
|
|
while (init_list[this->size] != NULL)
|
|
|
|
this->size++;
|
|
|
|
this->maxsize = this->size;
|
2001-06-19 02:37:46 +04:00
|
|
|
this->list = new bx_param_c* [maxsize];
|
2001-06-19 08:55:01 +04:00
|
|
|
for (int i=0; i<this->size; i++)
|
2001-06-18 18:11:55 +04:00
|
|
|
this->list[i] = init_list[i];
|
|
|
|
init ();
|
|
|
|
}
|
|
|
|
|
2001-12-21 22:33:18 +03:00
|
|
|
bx_list_c::~bx_list_c()
|
|
|
|
{
|
|
|
|
if (this->list)
|
|
|
|
{
|
|
|
|
delete [] this->list;
|
|
|
|
this->list = NULL;
|
|
|
|
}
|
|
|
|
if ( this->title != NULL)
|
|
|
|
{
|
|
|
|
delete this->title;
|
|
|
|
this->title = NULL;
|
|
|
|
}
|
|
|
|
if (this->options != NULL)
|
|
|
|
{
|
|
|
|
delete this->options;
|
|
|
|
this->options = NULL;
|
|
|
|
}
|
|
|
|
if ( this->choice != NULL )
|
|
|
|
{
|
|
|
|
delete this->choice;
|
|
|
|
this->choice = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-18 18:11:55 +04:00
|
|
|
void
|
|
|
|
bx_list_c::init ()
|
|
|
|
{
|
2001-06-21 18:37:55 +04:00
|
|
|
// the title defaults to the name
|
|
|
|
this->title = new bx_param_string_c (BXP_NULL,
|
|
|
|
"title of list",
|
|
|
|
"",
|
|
|
|
get_name (), 80);
|
|
|
|
this->options = new bx_param_num_c (BXP_NULL,
|
|
|
|
"list_option", "", 0, BX_MAX_INT,
|
2001-06-18 18:11:55 +04:00
|
|
|
0);
|
2001-06-21 18:37:55 +04:00
|
|
|
this->choice = new bx_param_num_c (BXP_NULL,
|
|
|
|
"list_choice", "", 0, BX_MAX_INT,
|
2001-06-18 18:11:55 +04:00
|
|
|
1);
|
|
|
|
this->parent = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_list_c::add (bx_param_c *param)
|
|
|
|
{
|
|
|
|
if (this->size >= this->maxsize)
|
|
|
|
BX_PANIC (("bx_list_c::add parameter id=%u exceeds capacity of list", param->get_id ()));
|
|
|
|
list[size] = param;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
bx_param_c *
|
|
|
|
bx_list_c::get (int index)
|
|
|
|
{
|
|
|
|
BX_ASSERT (index >= 0 && index < size);
|
|
|
|
return list[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_list_c::set_parent (bx_param_c *parent)
|
2001-06-16 03:52:34 +04:00
|
|
|
{
|
2001-06-18 18:11:55 +04:00
|
|
|
this->parent = parent;
|
2001-06-16 03:52:34 +04:00
|
|
|
}
|
2002-04-18 04:22:20 +04:00
|
|
|
|