- add a layer of abstraction between the text-mode control panel in
gui/control.cc and the simulator. Now all communication between the control panel and the rest of bochs goes through an object called bx_simulator_interface_c.
This commit is contained in:
parent
b26e2fb362
commit
f2af827a63
@ -82,6 +82,8 @@ extern "C" {
|
||||
#include "debug/debug.h"
|
||||
#include "bxversion.h"
|
||||
|
||||
#include "gui/siminterface.h"
|
||||
|
||||
//
|
||||
// some macros to interface the CPU and memory to external environment
|
||||
// so that these functions can be redirected to the debugger when
|
||||
@ -316,6 +318,7 @@ class iofunctions {
|
||||
#define CPU13LOG 38
|
||||
#define CPU14LOG 39
|
||||
#define CPU15LOG 40
|
||||
#define CTRLLOG 41
|
||||
|
||||
|
||||
public:
|
||||
@ -377,6 +380,7 @@ public:
|
||||
"CPUd",
|
||||
"CPUe",
|
||||
"CPUf",
|
||||
"CTRL"
|
||||
};
|
||||
return logclass[i];
|
||||
}
|
||||
@ -551,16 +555,17 @@ extern bx_devices_c bx_devices;
|
||||
#define BX_RESET_SOFTWARE 10
|
||||
#define BX_RESET_HARDWARE 11
|
||||
|
||||
#define BX_PATHNAME_LEN 512
|
||||
|
||||
typedef struct {
|
||||
char path[512];
|
||||
char path[BX_PATHNAME_LEN];
|
||||
unsigned type;
|
||||
unsigned initial_status;
|
||||
} bx_floppy_options;
|
||||
|
||||
typedef struct {
|
||||
Boolean present;
|
||||
char path[512];
|
||||
char path[BX_PATHNAME_LEN];
|
||||
unsigned int cylinders;
|
||||
unsigned int heads;
|
||||
unsigned int spt;
|
||||
@ -569,7 +574,7 @@ typedef struct {
|
||||
struct bx_cdrom_options
|
||||
{
|
||||
Boolean present;
|
||||
char dev[512];
|
||||
char dev[BX_PATHNAME_LEN];
|
||||
Boolean inserted;
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ GUI_OBJS_MACOS = macintosh.o
|
||||
GUI_OBJS_NOGUI = nogui.o
|
||||
GUI_OBJS_TERM = term.o
|
||||
GUI_OBJS_RFB = rfb.o
|
||||
GUI_OBJS = gui.o control.o @GUI_OBJS@
|
||||
GUI_OBJS = gui.o control.o siminterface.o @GUI_OBJS@
|
||||
|
||||
BX_INCDIRS = -I.. -I../iodev -I../@INSTRUMENT_DIR@
|
||||
LOCAL_CXXFLAGS =
|
||||
@ -59,7 +59,7 @@ LOCAL_CXXFLAGS =
|
||||
BX_GUI_OBJS = $(GUI_OBJS)
|
||||
|
||||
|
||||
BX_INCLUDES = iodev.h control.h
|
||||
BX_INCLUDES = iodev.h control.h siminterface.h
|
||||
|
||||
.@CPP_SUFFIX@.o:
|
||||
$(CXX) @DASH@c $(CXXFLAGS) $(LOCAL_CXXFLAGS) $(BX_INCDIRS) @CXXFP@$< @OFP@$@
|
||||
|
@ -1,13 +1,72 @@
|
||||
#include "bochs.h"
|
||||
/*
|
||||
* gui/control.cc
|
||||
* $Id: control.cc,v 1.2 2001-06-08 07:20:07 bdenney Exp $
|
||||
*
|
||||
* This is code for a text-mode control panel. Note that this file
|
||||
* does NOT include bochs.h. Instead, it does all of its contact with
|
||||
* the simulator through an object called SIM, defined in siminterface.cc
|
||||
* and siminterface.h. This separation adds an extra layer of method
|
||||
* calls before any work can be done, but the benefit is that the compiler
|
||||
* enforces the rules. I can guarantee that control.cc doesn't call any
|
||||
* I/O device objects directly, for example, because the bx_devices symbol
|
||||
* isn't even defined in this context.
|
||||
*
|
||||
|
||||
#define LOG_THIS genlog->
|
||||
Musings by Bryce:
|
||||
|
||||
Now that there are some capabilities here, start moving toward the desired
|
||||
model of separation of gui and simulator. Design a method-call interface
|
||||
between objects which could later be turned into a network protocol.
|
||||
|
||||
void bx_control_panel_entry ()
|
||||
{
|
||||
bx_control_panel_main ();
|
||||
Most messages go from the control panel to bochs, with bochs sending a response
|
||||
back. Examples: turn on debug event logging for the PIC, or set IPS to
|
||||
1.5million. Others kinds of messages go from bochs to the control panel.
|
||||
Example: errors such as "disk image not found", status information such as the
|
||||
current CPU state.
|
||||
|
||||
But because of the nature of a control panel, most information flows from
|
||||
the control panel to Bochs. I think we can take advantage of this to
|
||||
simplify the protocol. The GUI can ask bochs to do things and get a
|
||||
response back. Bochs can tell the GUI something, but will not get a
|
||||
response back.
|
||||
|
||||
The control panel should exist before the Bochs simulator starts, so that the
|
||||
user can get their settings right before booting up a simulator. Once
|
||||
bochs has begun, some settings can no longer be changed, such as how much
|
||||
memory there is. Others can be changed at any time, like the value of IPS
|
||||
or the name of the floppy disk images. If you had the bochs simulator
|
||||
as a shared library, the GUI could let you choose which version of the
|
||||
simulator library to load (one with debugging or SMP support or not,
|
||||
for example).
|
||||
|
||||
When the control panel connects to Bochs, each needs to learn what the other
|
||||
can do. Some versions of Bochs will have cdrom support, others will not.
|
||||
Design a simple and general way for the two parties to describe what they
|
||||
can do, so that the GUI can grey-out some menu choices, and Bochs knows
|
||||
what the GUI can handle. I think Bochs should provide a list of
|
||||
capabilities in something like the form of:
|
||||
typedef struct { Bit16u id; String name; } bx_capability_t;
|
||||
Only the negotiation of capabilities uses the string name, and for everything
|
||||
else the 16-bit id is used (use htons() if sending over network). Each
|
||||
capability is like a function that can be called on the remote object,
|
||||
and each function needs an input list and a return value.
|
||||
|
||||
Hmm.... This sounds like reinventing function calls. Next I'm going to
|
||||
say we need to implement prototypes and type checking.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
}
|
||||
#include "siminterface.h"
|
||||
|
||||
#define BX_PANIC(x) printf x
|
||||
|
||||
void bx_floppy_change ();
|
||||
void bx_ips_change ();
|
||||
void bx_log_options ();
|
||||
|
||||
/******************************************************************/
|
||||
/* lots of code stolen from bximage.c */
|
||||
@ -190,8 +249,8 @@ void bx_control_panel_main ()
|
||||
fprintf (stderr, "Continuing simulation\n");
|
||||
return;
|
||||
case 11:
|
||||
BX_PANIC(("You chose quit on the control panel"));
|
||||
exit(1);
|
||||
fprintf (stderr, "You chose quit on the control panel.\n");
|
||||
SIM->quit_sim ();
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "Menu choice %d not implemented.\n", choice);
|
||||
@ -202,31 +261,29 @@ void bx_control_panel_main ()
|
||||
|
||||
void bx_floppy_change ()
|
||||
{
|
||||
int which;
|
||||
if (ask_int ("Change floppy 0 or 1? [0] ", 0, 1, 0, &which) < 0)
|
||||
int drive;
|
||||
if (ask_int ("Change floppy 0 or 1? [0] ", 0, 1, 0, &drive) < 0)
|
||||
return;
|
||||
char oldpath[1024], newpath[1024];
|
||||
strcpy (oldpath, (which)? bx_options.floppyb.path : bx_options.floppya.path);
|
||||
SIM->get_floppy_path (drive, oldpath, 1024);
|
||||
char prompt[1024];
|
||||
sprintf (prompt, "Enter new pathname: [%s] ", oldpath);
|
||||
if (ask_string (prompt, oldpath, newpath) < 0)
|
||||
return;
|
||||
fprintf (stderr, "Changing floppy %d to new path %s\n", which, newpath);
|
||||
strcpy ((which)? bx_options.floppyb.path : bx_options.floppya.path, newpath);
|
||||
|
||||
// notify
|
||||
bx_devices.floppy->set_media_status (which, 0);
|
||||
bx_devices.floppy->set_media_status (which, 1);
|
||||
fprintf (stderr, "Changing floppy %d to new path %s\n", drive, newpath);
|
||||
SIM->set_floppy_options (drive, 0, newpath);
|
||||
SIM->set_floppy_options (drive, 1, newpath);
|
||||
}
|
||||
|
||||
void bx_ips_change ()
|
||||
{
|
||||
char prompt[1024];
|
||||
sprintf (prompt, "Type a new value for ips: [%d] ", bx_options.ips);
|
||||
int oldips = SIM->getips ();
|
||||
sprintf (prompt, "Type a new value for ips: [%d] ", oldips);
|
||||
int newips;
|
||||
if (ask_int (prompt, 1, 1<<30, bx_options.ips, &newips) < 0)
|
||||
if (ask_int (prompt, 1, 1<<30, oldips, &newips) < 0)
|
||||
return;
|
||||
bx_options.ips = newips;
|
||||
SIM->setips (newips);
|
||||
}
|
||||
|
||||
static void bx_print_log_action_table ()
|
||||
@ -235,11 +292,11 @@ static void bx_print_log_action_table ()
|
||||
fprintf (stderr, "Current log settings:\n");
|
||||
fprintf (stderr, " Debug Info Error Panic\n");
|
||||
fprintf (stderr, "ID Device Action Action Action Action\n");
|
||||
for (int i=0; i<io->get_n_logfns (); i++) {
|
||||
logfunc_t *logfn = io->get_logfn (i);
|
||||
fprintf (stderr, "%3d. %s ", i, logfn->getprefix ());
|
||||
for (int j=0; j<MAX_LOGLEV; j++) {
|
||||
fprintf (stderr, "%10s ", io->getaction (logfn->getonoff(j)));
|
||||
int i, imax=SIM->get_n_log_modules ();
|
||||
for (int i=0; i<imax; i++) {
|
||||
fprintf (stderr, "%3d. %s ", i, SIM->get_prefix (i));
|
||||
for (int j=0; j<SIM->get_max_log_level (); j++) {
|
||||
fprintf (stderr, "%10s ", SIM->get_action_name (SIM->get_log_action (i, j)));
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
@ -254,19 +311,18 @@ void bx_log_options ()
|
||||
while (!done) {
|
||||
bx_print_log_action_table ();
|
||||
int id, level, action;
|
||||
int maxid = io->get_n_logfns ();
|
||||
int maxid = SIM->get_n_log_modules ();
|
||||
if (ask_int (log_options_prompt1, -1, maxid-1, -1, &id) < 0)
|
||||
return;
|
||||
if (id < 0) return;
|
||||
logfunc_t *logfn = io->get_logfn (id);
|
||||
fprintf (stderr, "Editing log options for the device %s\n", logfn->getprefix ());
|
||||
for (level=0; level<MAX_LOGLEV; level++) {
|
||||
fprintf (stderr, "Editing log options for the device %s\n", SIM->get_prefix (id));
|
||||
for (level=0; level<SIM->get_max_log_level (); level++) {
|
||||
char prompt[1024];
|
||||
int default_action = logfn->getonoff (level);
|
||||
sprintf (prompt, "Enter action for %s event: [%s] ", io->getlevel(level), io->getaction (default_action));
|
||||
int default_action = SIM->get_log_action (id, level);
|
||||
sprintf (prompt, "Enter action for %s event: [%s] ", SIM->get_log_level_name (level), SIM->get_action_name(default_action));
|
||||
if (ask_menu (prompt, 3, log_level_choices, default_action, &action)<0)
|
||||
return;
|
||||
logfn->setonoff (level, action);
|
||||
SIM->set_log_action (id, level, action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1 @@
|
||||
void bx_control_panel_entry ();
|
||||
void bx_control_panel_main ();
|
||||
void bx_floppy_change ();
|
||||
void bx_ips_change ();
|
||||
void bx_log_options ();
|
||||
|
@ -51,6 +51,7 @@ bx_gui_c::bx_gui_c(void)
|
||||
bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
|
||||
{
|
||||
specific_init(&bx_gui, argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y);
|
||||
init_siminterface ();
|
||||
|
||||
// Define some bitmaps to use in the headerbar
|
||||
BX_GUI_THIS floppyA_bmap_id = create_bitmap(bx_floppya_bmap,
|
||||
@ -175,8 +176,7 @@ bx_gui_c::power_handler(void)
|
||||
void
|
||||
bx_gui_c::snapshot_handler(void)
|
||||
{
|
||||
BX_INFO(( "# SNAPSHOT callback (unimplemented)." ));
|
||||
bx_control_panel_entry ();
|
||||
bx_control_panel_main ();
|
||||
}
|
||||
|
||||
void
|
||||
|
140
bochs/gui/siminterface.cc
Normal file
140
bochs/gui/siminterface.cc
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* gui/siminterface.cc
|
||||
* $Id: siminterface.cc,v 1.1 2001-06-08 07:20:07 bdenney Exp $
|
||||
*
|
||||
* Defines the actual link between bx_simulator_interface_c methods
|
||||
* and the simulator. This file includes bochs.h because it needs
|
||||
* access to bx_options and other simulator objecst and methods.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bochs.h"
|
||||
|
||||
// this dummy only exists for purposes of log functions. It would be
|
||||
// lovely to get rid of it.
|
||||
class siminterface_dummy_c : public logfunctions {
|
||||
dummy () {
|
||||
setprefix("[CTRL]"); // control panel
|
||||
settype(CTRLLOG);
|
||||
}
|
||||
};
|
||||
siminterface_dummy_c siminterface_dummy;
|
||||
|
||||
bx_simulator_interface_c *SIM = NULL;
|
||||
#define LOG_THIS siminterface_dummy.
|
||||
|
||||
class bx_real_sim_c : public bx_simulator_interface_c {
|
||||
void get_floppy_path (int drive, char *buffer, int size);
|
||||
int get_floppy_present (int drive);
|
||||
void set_floppy_options (int drive, int present, char *path);
|
||||
int getips ();
|
||||
void setips (int ips);
|
||||
int get_n_log_modules ();
|
||||
char *get_prefix (int mod);
|
||||
int get_log_action (int mod, int level);
|
||||
void set_log_action (int mod, int level, int action);
|
||||
char *get_action_name (int action);
|
||||
char *get_log_level_name (int level);
|
||||
int get_max_log_level ();
|
||||
void quit_sim ();
|
||||
};
|
||||
|
||||
void init_siminterface ()
|
||||
{
|
||||
fprintf (stderr, "INIT Interface\n");
|
||||
if (SIM == NULL) {
|
||||
BX_INFO (("init_siminterface"));
|
||||
SIM = new bx_real_sim_c();
|
||||
}
|
||||
}
|
||||
|
||||
bx_simulator_interface_c::bx_simulator_interface_c ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
bx_real_sim_c::get_floppy_path (int drive, char *buffer, int size)
|
||||
{
|
||||
strncpy (buffer,
|
||||
(drive==0)? bx_options.floppya.path : bx_options.floppyb.path,
|
||||
size);
|
||||
}
|
||||
|
||||
int
|
||||
bx_real_sim_c::get_floppy_present (int drive)
|
||||
{
|
||||
BX_ASSERT(0);
|
||||
}
|
||||
|
||||
void
|
||||
bx_real_sim_c::set_floppy_options (int drive, int present, char *path)
|
||||
{
|
||||
bx_devices.floppy->set_media_status (drive, present);
|
||||
strncpy (
|
||||
(drive==0)? bx_options.floppya.path : bx_options.floppyb.path,
|
||||
path,
|
||||
BX_PATHNAME_LEN);
|
||||
}
|
||||
|
||||
int
|
||||
bx_real_sim_c::getips ()
|
||||
{
|
||||
return bx_options.ips;
|
||||
}
|
||||
|
||||
void
|
||||
bx_real_sim_c::setips (int ips)
|
||||
{
|
||||
bx_options.ips = ips;
|
||||
}
|
||||
|
||||
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);
|
||||
return logfn->setonoff (level, action);
|
||||
}
|
||||
|
||||
char *
|
||||
bx_real_sim_c::get_action_name (int action)
|
||||
{
|
||||
return io->getaction (action);
|
||||
}
|
||||
|
||||
char *
|
||||
bx_real_sim_c::get_log_level_name (int level)
|
||||
{
|
||||
return io->getlevel (level);
|
||||
}
|
||||
|
||||
int
|
||||
bx_real_sim_c::get_max_log_level ()
|
||||
{
|
||||
return MAX_LOGLEV;
|
||||
}
|
||||
|
||||
void
|
||||
bx_real_sim_c::quit_sim () {
|
||||
BX_PANIC (("Quit simulation command"));
|
||||
::exit (0);
|
||||
}
|
37
bochs/gui/siminterface.h
Normal file
37
bochs/gui/siminterface.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* gui/siminterface.h
|
||||
* $Id: siminterface.h,v 1.1 2001-06-08 07:20:07 bdenney Exp $
|
||||
*
|
||||
* Interface to the simulator, currently only used by control.cc.
|
||||
* The base class bx_simulator_interface_c, contains only virtual functions
|
||||
* and it defines the interface that control.cc is allowed to use.
|
||||
* In siminterface.cc, a class called bx_real_sim_c is defined with
|
||||
* bx_simulator_interface_c as its parent class. Bx_real_sim_c
|
||||
* implements each of the functions. The separation into parent class
|
||||
* and child class leaves the possibility of making a different child
|
||||
* class that talks to the simulator in a different way (networking
|
||||
* for example).
|
||||
*
|
||||
*/
|
||||
|
||||
class bx_simulator_interface_c {
|
||||
public:
|
||||
bx_simulator_interface_c ();
|
||||
virtual void get_floppy_path (int drive, char *buffer, int size) {}
|
||||
virtual int get_floppy_present (int drive) {return -1;}
|
||||
virtual void set_floppy_options (int drive, int present, char *path) {}
|
||||
virtual int getips () {return -1;}
|
||||
virtual void setips (int ips) {}
|
||||
virtual int get_n_log_modules () {return -1;}
|
||||
virtual char *get_prefix (int mod) {return 0;}
|
||||
virtual int get_log_action (int mod, int level) {return -1;}
|
||||
virtual void set_log_action (int mod, int level, int action) {}
|
||||
virtual char *get_action_name (int action) {return 0;}
|
||||
virtual char *get_log_level_name (int level) {return 0;}
|
||||
virtual int get_max_log_level () {return -1;}
|
||||
virtual void quit_sim () {}
|
||||
};
|
||||
|
||||
extern bx_simulator_interface_c *SIM;
|
||||
|
||||
extern void init_siminterface ();
|
Loading…
Reference in New Issue
Block a user