- implemented bx_write_configuration which, for the first time ever,

writes a bochsrc for you.
- since there were two options related to logging, I moved them both
  into a new struct called bx_log_options.  This follows the pattern
  used by other devices.
- in control.cc: removed option 1 from main menu, the one that said
  "Read options from bochsrc.txt."  This was identical to choosing
  the next option, "Read options from..." and only saved you one
  keystroke, so I removed it.
This commit is contained in:
Bryce Denney 2001-06-11 06:35:18 +00:00
parent 17f2be70b9
commit 985d4b7923
5 changed files with 331 additions and 96 deletions

View File

@ -237,7 +237,7 @@ extern Bit8u DTPageDirty[];
#define LOGLEV_INFO 1
#define LOGLEV_ERROR 2
#define LOGLEV_PANIC 3
#define MAX_LOGLEV 4
#define N_LOGLEV 4
typedef class logfunctions {
char *prefix;
@ -246,7 +246,8 @@ typedef class logfunctions {
#define ACT_IGNORE 0
#define ACT_REPORT 1
#define ACT_FATAL 2
int onoff[MAX_LOGLEV];
#define N_ACT 3
int onoff[N_LOGLEV];
class iofunctions *logio;
public:
logfunctions(void);
@ -262,12 +263,12 @@ public:
void settype(int);
void setio(class iofunctions *);
void setonoff(int loglev, int value) {
assert (loglev >= 0 && loglev < MAX_LOGLEV);
assert (loglev >= 0 && loglev < N_LOGLEV);
onoff[loglev] = value;
}
char *getprefix () { return prefix; }
int getonoff(int level) {
assert (level>=0 && level<MAX_LOGLEV);
assert (level>=0 && level<N_LOGLEV);
return onoff[level];
}
} logfunc_t;
@ -398,7 +399,7 @@ public:
}
char *getaction(int i) {
static char *name[] = { "ignore", "report", "fatal" };
assert (i>=0 && i<3);
assert (i>=ACT_IGNORE && i<=ACT_FATAL);
return name[i];
}
@ -560,6 +561,7 @@ extern bx_devices_c bx_devices;
char *bx_find_bochsrc (void);
int bx_read_configuration (char *rcfile, int argc, char *argv[]);
int bx_write_configuration (char *rcfile, int overwrite);
#if BX_USE_CONTROL_PANEL==0
// with control panel enabled, this is defined in gui/siminterface.h instead.
@ -631,8 +633,15 @@ typedef struct {
char *initrd;
} bx_load32bitOSImage_t;
typedef struct {
char filename[BX_PATHNAME_LEN];
// one array item for each log level, indexed by LOGLEV_*.
// values: ACT_IGNORE, ACT_REPORT, ACT_FATAL
unsigned char actions[N_LOGLEV];
} bx_log_options;
typedef struct {
int present;
char *midifile, *wavefile, *logfile;
unsigned int midimode, wavemode, loglevel;
Bit32u dmatimer;
@ -660,10 +669,7 @@ typedef struct {
bx_ne2k_options ne2k;
Boolean newHardDriveSupport;
bx_load32bitOSImage_t load32bitOSImage;
// one array item for each log level, indexed by LOGLEV_*.
// values: 0=ignore event, 1=report event in log, 2=fatal
unsigned char log_actions[MAX_LOGLEV];
char logfilename[BX_PATHNAME_LEN];
bx_log_options log;
} bx_options_t;
extern bx_options_t bx_options;

View File

@ -1,6 +1,6 @@
/*
* gui/control.cc
* $Id: control.cc,v 1.8 2001-06-10 05:30:27 bdenney Exp $
* $Id: control.cc,v 1.9 2001-06-11 06:35:18 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
@ -70,6 +70,7 @@ extern "C" {
#include "siminterface.h"
#define BX_PANIC(x) printf x
#define CPANEL_PATH_LEN 512
/* functions for changing particular options */
void bx_edit_mem ();
@ -84,6 +85,7 @@ void bx_private_colormap ();
void bx_boot_from ();
void bx_ips_change ();
int bx_read_rc (char *rc);
int bx_write_rc (char *rc);
void bx_log_file ();
void bx_log_options (int individual);
void bx_vga_update_interval ();
@ -231,12 +233,11 @@ static char *startup_menu_prompt =
"------------------\n\
Bochs Startup Menu\n\
------------------\n\
1. %s%s%s\n\
2. Read options from...\n\
3. Edit options\n\
4. Save options to...\n\
5. Begin simulation\n\
6. Quit now\n\
1. Read options from...\n\
2. Edit options\n\
3. Save options to...\n\
4. Begin simulation\n\
5. Quit now\n\
\n\
Please choose one: [%d] ";
@ -317,6 +318,7 @@ Bochs Miscellaneous Options\n\
---------------------------\n\
1. Keyboard Serial Delay: 250\n\
2. Floppy command delay: 500\n\
To be added someday: magic_break, ne2k, load32bitOSImage,i440fxsupport,time0
\n\
Please choose one: [0] ";
@ -409,38 +411,27 @@ int bx_control_panel (int menu)
}
case BX_CPANEL_START_MENU:
{
char rc[512], prompt[512];
char rc[CPANEL_PATH_LEN];
char *choice_disabled = "Choice 1 not allowed because the default bochsrc file was not found.";
static int read_rc = 0;
int notfound = 0;
int default_choice = 1;
if (SIM->get_default_rc (rc, 512) >= 0) {
default_choice = read_rc ? 5 : 1;
sprintf (prompt, startup_menu_prompt, "Read options from ", rc, "", default_choice);
} else {
default_choice = read_rc ? 5 : 2;
sprintf (prompt, startup_menu_prompt, "DISABLED because a bochsrc file was not found", "", "", default_choice);
notfound = 1;
}
if (ask_int (prompt, 1, 6, default_choice, &choice) < 0) return -1;
default_choice = read_rc ? 4 : 1;
if (ask_int (startup_menu_prompt, 1, 5, default_choice, &choice) < 0) return -1;
switch (choice) {
case 1: if (notfound) fprintf (stderr, "%s\n", choice_disabled);
else if (bx_read_rc (rc) >= 0) read_rc=1;
break;
case 2: if (bx_read_rc (NULL) >= 0) read_rc=1; break;
case 3: bx_control_panel (BX_CPANEL_START_OPTS); break;
case 4: NOT_IMPLEMENTED (choice); break;
case 5: return 0; // return from menu
case 6: SIM->quit_sim (1); return -1;
case 1: if (bx_read_rc (NULL) >= 0) read_rc=1; break;
case 2: bx_control_panel (BX_CPANEL_START_OPTS); break;
case 3: bx_write_rc (NULL); break;
case 4: return 0; // return from menu
case 5: SIM->quit_sim (1); return -1;
default: BAD_OPTION(menu, choice);
}
}
break;
case BX_CPANEL_START_OPTS:
{
char prompt[512];
char oldpath[512];
assert (SIM->get_log_file (oldpath, 512) >= 0);
char prompt[CPANEL_PATH_LEN];
char oldpath[CPANEL_PATH_LEN];
assert (SIM->get_log_file (oldpath, CPANEL_PATH_LEN) >= 0);
sprintf (prompt, startup_options_prompt, oldpath);
if (ask_int (prompt, 0, 8, 0, &choice) < 0) return -1;
switch (choice) {
@ -459,10 +450,10 @@ int bx_control_panel (int menu)
break;
case BX_CPANEL_START_OPTS_BOOT:
{
char prompt[512], vgapath[512], rompath[512];
if (SIM->get_rom_path (rompath, 512) < 0)
char prompt[CPANEL_PATH_LEN], vgapath[CPANEL_PATH_LEN], rompath[CPANEL_PATH_LEN];
if (SIM->get_rom_path (rompath, CPANEL_PATH_LEN) < 0)
strcpy (rompath, "none");
if (SIM->get_vga_path (vgapath, 512) < 0)
if (SIM->get_vga_path (vgapath, CPANEL_PATH_LEN) < 0)
strcpy (vgapath, "none");
sprintf (prompt, startup_boot_options_prompt,
SIM->get_mem_size (),
@ -607,14 +598,14 @@ void bx_edit_cdrom ()
void bx_edit_rom_path (int vga)
{
char oldpath[512], newpath[512];
char oldpath[CPANEL_PATH_LEN], newpath[CPANEL_PATH_LEN];
if (vga) {
if (SIM->get_vga_path (oldpath, 512) < 0) return;
if (SIM->get_vga_path (oldpath, CPANEL_PATH_LEN) < 0) return;
if (ask_string ("Enter pathname of the VGA ROM image: [%s] ", oldpath, newpath) < 0)
return;
SIM->set_vga_path (newpath);
} else {
if (SIM->get_rom_path (oldpath, 512) < 0) return;
if (SIM->get_rom_path (oldpath, CPANEL_PATH_LEN) < 0) return;
if (ask_string ("Enter pathname of the ROM image: [%s] ", oldpath, newpath) < 0)
return;
SIM->set_rom_path (newpath);
@ -748,22 +739,58 @@ void bx_mouse_enable ()
int bx_read_rc (char *rc)
{
if (rc && SIM->read_rc (rc) >= 0) return 0;
char oldrc[512];
if (SIM->get_default_rc (oldrc, 512) < 0)
oldrc[0] = 0;
char newrc[512];
char oldrc[CPANEL_PATH_LEN];
if (SIM->get_default_rc (oldrc, CPANEL_PATH_LEN) < 0)
strcpy (oldrc, "none");
char newrc[CPANEL_PATH_LEN];
while (1) {
if (ask_string ("\nWhat is the configuration file name? If there is no config file\ntype none. [%s] ", oldrc, newrc) < 0) return -1;
if (ask_string ("\nWhat is the configuration file name?\nTo cancel, type 'none'. [%s] ", oldrc, newrc) < 0) return -1;
if (!strcmp (newrc, "none")) return 0;
if (SIM->read_rc (newrc) >= 0) return 0;
fprintf (stderr, "The file '%s' could not be found.\n", newrc);
}
}
int bx_write_rc (char *rc)
{
char oldrc[CPANEL_PATH_LEN], newrc[CPANEL_PATH_LEN];
if (rc == NULL) {
if (SIM->get_default_rc (oldrc, CPANEL_PATH_LEN) < 0)
strcpy (oldrc, "none");
} else {
strncpy (oldrc, rc, CPANEL_PATH_LEN);
}
while (1) {
if (ask_string ("Save configuration to what file? To cancel, type 'none'.\n[%s] ", oldrc, newrc) < 0) return -1;
if (!strcmp (newrc, "none")) return 0;
// try with overwrite off first
int status = SIM->write_rc (newrc, 0);
if (status >= 0) {
fprintf (stderr, "Wrote configuration to '%s'.\n", newrc);
return 0;
} else if (status == -2) {
// return code -2 indicates the file already exists, and overwrite
// confirmation is required.
int overwrite = 0;
char prompt[256];
sprintf (prompt, "Configuration file '%s' already exists. Overwrite it? [no] ", newrc);
if (ask_yn (prompt, 0, &overwrite) < 0) return -1;
if (!overwrite) continue; // if "no", start loop over, asking for a different file
// they confirmed, so try again with overwrite bit set
if (SIM->write_rc (newrc, 1) >= 0) {
fprintf (stderr, "Overwriting existing configuration '%s'.\n", newrc);
return 0;
} else {
fprintf (stderr, "Write failed to '%s'.\n", newrc);
}
}
}
}
void bx_log_file ()
{
char oldpath[512], newpath[512];
assert (SIM->get_log_file (oldpath, 512) >= 0);
char oldpath[CPANEL_PATH_LEN], newpath[CPANEL_PATH_LEN];
assert (SIM->get_log_file (oldpath, CPANEL_PATH_LEN) >= 0);
if (ask_string ("Enter log file name: [%s] ", oldpath, newpath) < 0) return;
SIM->set_log_file (newpath);
}

View File

@ -1,6 +1,6 @@
/*
* gui/siminterface.cc
* $Id: siminterface.cc,v 1.7 2001-06-09 21:29:07 bdenney Exp $
* $Id: siminterface.cc,v 1.8 2001-06-11 06:35:18 bdenney Exp $
*
* Defines the actual link between bx_simulator_interface_c methods
* and the simulator. This file includes bochs.h because it needs
@ -10,19 +10,9 @@
#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 {
public:
siminterface_dummy_c () {
setprefix("[CTRL]"); // control panel
settype(CTRLLOG);
}
};
siminterface_dummy_c siminterface_dummy;
bx_simulator_interface_c *SIM = NULL;
#define LOG_THIS siminterface_dummy.
logfunctions *siminterface_log = NULL;
#define LOG_THIS siminterface_log->
class bx_real_sim_c : public bx_simulator_interface_c {
virtual int getips ();
@ -41,6 +31,7 @@ class bx_real_sim_c : public bx_simulator_interface_c {
virtual void set_mouse_enabled (int en);
virtual int get_default_rc (char *path, int len);
virtual int read_rc (char *path);
virtual int write_rc (char *path, int overwrite);
virtual int get_log_file (char *path, int len);
virtual int set_log_file (char *path);
virtual int get_floppy_options (int drive, bx_floppy_options *out);
@ -68,6 +59,9 @@ class bx_real_sim_c : public bx_simulator_interface_c {
void init_siminterface ()
{
siminterface_log = new logfunctions ();
siminterface_log->setprefix ("[CTRL]");
siminterface_log->settype(CTRLLOG);
if (SIM == NULL)
SIM = new bx_real_sim_c();
}
@ -132,7 +126,7 @@ bx_real_sim_c::get_log_level_name (int level)
int
bx_real_sim_c::get_max_log_level ()
{
return MAX_LOGLEV;
return N_LOGLEV;
}
void
@ -179,17 +173,27 @@ bx_real_sim_c::read_rc (char *rc)
return bx_read_configuration (rc, 0, NULL);
}
// 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);
}
int
bx_real_sim_c::get_log_file (char *path, int len)
{
strncpy (path, bx_options.logfilename, len);
strncpy (path, bx_options.log.filename, len);
return 0;
}
int
bx_real_sim_c::set_log_file (char *path)
{
strncpy (bx_options.logfilename, path, sizeof(bx_options.logfilename));
strncpy (bx_options.log.filename, path, sizeof(bx_options.log.filename));
return 0;
}

View File

@ -1,6 +1,6 @@
/*
* gui/siminterface.h
* $Id: siminterface.h,v 1.4 2001-06-09 21:29:07 bdenney Exp $
* $Id: siminterface.h,v 1.5 2001-06-11 06:35:18 bdenney Exp $
*
* Interface to the simulator, currently only used by control.cc.
* The base class bx_simulator_interface_c, contains only virtual functions
@ -74,6 +74,7 @@ public:
virtual void set_mouse_enabled (int en) {}
virtual int get_default_rc (char *path, int len) {}
virtual int read_rc (char *path) {return -1;}
virtual int write_rc (char *rc, int overwrite) {return -1;}
virtual int get_log_file (char *path, int len) {}
virtual int set_log_file (char *path) {return -1;}
virtual int get_floppy_options (int drive, bx_floppy_options *out) {return -1;}

View File

@ -70,7 +70,7 @@ bx_options_t bx_options = {
{ NULL, 0 }, // rom
{ NULL }, // vgarom
{ BX_DEFAULT_MEM_MEGS }, // memory
{ NULL, NULL, NULL, 0, 0, 0, 0 }, // SB16
{ 0, NULL, NULL, NULL, 0, 0, 0, 0 }, // SB16
"a", // boot drive
300000, // vga update interval
20000, // default keyboard serial path delay (usec)
@ -83,11 +83,8 @@ bx_options_t bx_options = {
{ 0, 0, 0, {0,0,0,0,0,0}, NULL, NULL }, // ne2k
1, // newHardDriveSupport
{ 0, NULL, NULL, NULL }, // load32bitOSImage hack stuff
{
// ignore debugs, report infos and errors, fatal on panics.
ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_FATAL
},
"-" // default log file name (stdout)
// log options: ignore debug, report info and error, crash on panic.
{ "-", { ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_FATAL } },
};
static void parse_line_unformatted(char *context, char *line);
@ -259,8 +256,8 @@ logfunctions::logfunctions(void)
setio(io);
// BUG: unfortunately this can be called before the bochsrc is read,
// which means that the bochsrc has no effect on the actions.
for (int i=0; i<MAX_LOGLEV; i++)
onoff[i] = bx_options.log_actions[i];
for (int i=0; i<N_LOGLEV; i++)
onoff[i] = bx_options.log.actions[i];
}
logfunctions::logfunctions(iofunc_t *iofunc)
@ -270,8 +267,8 @@ logfunctions::logfunctions(iofunc_t *iofunc)
setio(iofunc);
// BUG: unfortunately this can be called before the bochsrc is read,
// which means that the bochsrc has no effect on the actions.
for (int i=0; i<MAX_LOGLEV; i++)
onoff[i] = bx_options.log_actions[i];
for (int i=0; i<N_LOGLEV; i++)
onoff[i] = bx_options.log.actions[i];
}
logfunctions::~logfunctions(void)
@ -541,14 +538,14 @@ bx_init_hardware()
// This function used to
// all configuration has been read, now initialize everything.
for (int level=0; level<MAX_LOGLEV; level++)
io->set_log_action (level, bx_options.log_actions[level]);
for (int level=0; level<N_LOGLEV; level++)
io->set_log_action (level, bx_options.log.actions[level]);
bx_pc_system.init_ips(bx_options.ips);
if(bx_options.logfilename[0]!='-') {
BX_INFO (("using log file %s", bx_options.logfilename));
io->init_log(bx_options.logfilename);
if(bx_options.log.filename[0]!='-') {
BX_INFO (("using log file %s", bx_options.log.filename));
io->init_log(bx_options.log.filename);
}
// set up memory and CPU objects
@ -909,7 +906,7 @@ parse_line_formatted(char *context, int num_params, char *params[])
if (num_params != 2) {
BX_PANIC(("%s: log directive has wrong # args.", context));
}
strcpy(bx_options.logfilename, params[1]);
strcpy(bx_options.log.filename, params[1]);
}
else if (!strcmp(params[0], "panic")) {
if (num_params != 2) {
@ -920,11 +917,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
bx_options.log_actions[LOGLEV_PANIC] = ACT_FATAL;
bx_options.log.actions[LOGLEV_PANIC] = ACT_FATAL;
else if (!strcmp (action, "report"))
bx_options.log_actions[LOGLEV_PANIC] = ACT_REPORT;
bx_options.log.actions[LOGLEV_PANIC] = ACT_REPORT;
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_PANIC] = ACT_IGNORE;
bx_options.log.actions[LOGLEV_PANIC] = ACT_IGNORE;
else {
BX_PANIC(("%s: panic directive malformed.", context));
}
@ -938,11 +935,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
bx_options.log_actions[LOGLEV_ERROR] = ACT_FATAL;
bx_options.log.actions[LOGLEV_ERROR] = ACT_FATAL;
else if (!strcmp (action, "report"))
bx_options.log_actions[LOGLEV_ERROR] = ACT_REPORT;
bx_options.log.actions[LOGLEV_ERROR] = ACT_REPORT;
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_ERROR] = ACT_IGNORE;
bx_options.log.actions[LOGLEV_ERROR] = ACT_IGNORE;
else {
BX_PANIC(("%s: error directive malformed.", context));
}
@ -956,11 +953,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
bx_options.log_actions[LOGLEV_INFO] = ACT_FATAL;
bx_options.log.actions[LOGLEV_INFO] = ACT_FATAL;
else if (!strcmp (action, "report"))
bx_options.log_actions[LOGLEV_INFO] = ACT_REPORT;
bx_options.log.actions[LOGLEV_INFO] = ACT_REPORT;
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_INFO] = ACT_IGNORE;
bx_options.log.actions[LOGLEV_INFO] = ACT_IGNORE;
else {
BX_PANIC(("%s: info directive malformed.", context));
}
@ -974,11 +971,11 @@ parse_line_formatted(char *context, int num_params, char *params[])
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
bx_options.log_actions[LOGLEV_DEBUG] = ACT_FATAL;
bx_options.log.actions[LOGLEV_DEBUG] = ACT_FATAL;
else if (!strcmp (action, "report"))
bx_options.log_actions[LOGLEV_DEBUG] = ACT_REPORT;
bx_options.log.actions[LOGLEV_DEBUG] = ACT_REPORT;
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_DEBUG] = ACT_IGNORE;
bx_options.log.actions[LOGLEV_DEBUG] = ACT_IGNORE;
else {
BX_PANIC(("%s: debug directive malformed.", context));
}
@ -1081,6 +1078,7 @@ parse_line_formatted(char *context, int num_params, char *params[])
else if (!strcmp(params[0], "sb16")) {
for (i=1; i<num_params; i++) {
bx_options.sb16.present = 1;
if (!strncmp(params[i], "midi=", 5)) {
bx_options.sb16.midifile = strdup(&params[i][5]);
}
@ -1174,16 +1172,20 @@ parse_line_formatted(char *context, int num_params, char *params[])
bx_options.ne2k.valid = 0;
if ((num_params < 4) || (num_params > 6)) {
BX_PANIC(("%s: ne2k directive malformed.", context));
return;
}
bx_options.ne2k.ethmod = "null";
if (strncmp(params[1], "ioaddr=", 7)) {
BX_PANIC(("%s: ne2k directive malformed.", context));
return;
}
if (strncmp(params[2], "irq=", 4)) {
BX_PANIC(("%s: ne2k directive malformed.", context));
return;
}
if (strncmp(params[3], "mac=", 4)) {
BX_PANIC(("%s: ne2k directive malformed.", context));
return;
}
bx_options.ne2k.ioaddr = strtoul(&params[1][7], NULL, 16);
bx_options.ne2k.irq = atol(&params[2][4]);
@ -1191,17 +1193,20 @@ parse_line_formatted(char *context, int num_params, char *params[])
&tmp[0],&tmp[1],&tmp[2],&tmp[3],&tmp[4],&tmp[5]);
if (i != 6) {
BX_PANIC(("%s: ne2k mac address malformed.", context));
return;
}
for (i=0;i<6;i++)
bx_options.ne2k.macaddr[i] = tmp[i];
if (num_params > 4) {
if (strncmp(params[4], "ethmod=", 7)) {
BX_PANIC(("%s: ne2k directive malformed.", context));
return;
}
bx_options.ne2k.ethmod = strdup(&params[4][7]);
if (num_params == 6) {
if (strncmp(params[5], "ethdev=", 7)) {
BX_PANIC(("%s: ne2k directive malformed.", context));
return;
}
bx_options.ne2k.ethdev = strdup(&params[5][7]);
}
@ -1248,6 +1253,198 @@ parse_line_formatted(char *context, int num_params, char *params[])
if (bx_options.diskd.present && bx_options.cdromd.present)
BX_PANIC(("At present, using both diskd and cdromd at once is not supported."));
}
static char *fdtypes[] = {
"none", "1_2", "1_44", "2_88", "720k"
};
int
bx_write_floppy_options (FILE *fp, int drive, bx_floppy_options *opt)
{
BX_ASSERT (drive==0 || drive==1);
if (opt->type == BX_FLOPPY_NONE) {
fprintf (fp, "# no floppy%c\n", (char)'a'+drive);
return 0;
}
BX_ASSERT (opt->type > BX_FLOPPY_NONE && opt->type <= BX_FLOPPY_LAST);
fprintf (fp, "floppy%c: %s=%s, status=%s\n",
(char)'a'+drive,
fdtypes[opt->type - BX_FLOPPY_NONE],
opt->path,
opt->initial_status==BX_EJECTED ? "ejected" : "inserted");
return 0;
}
int
bx_write_disk_options (FILE *fp, int drive, bx_disk_options *opt)
{
if (!opt->present) {
fprintf (fp, "# no disk%c\n", (char)'c'+drive);
return 0;
}
fprintf (fp, "disk%c: file=\"%s\", cyl=%d, heads=%d, spt=%d\n",
(char)'c'+drive,
opt->path,
opt->cylinders,
opt->heads,
opt->spt);
return 0;
}
int
bx_write_cdrom_options (FILE *fp, int drive, bx_cdrom_options *opt)
{
BX_ASSERT (drive == 0);
if (!opt->present) {
fprintf (fp, "# no cdromd\n");
return 0;
}
fprintf (fp, "cdromd: dev=%s, status=%s\n",
opt->dev,
opt->inserted ? "inserted" : "ejected");
return 0;
}
int
bx_write_sb16_options (FILE *fp, bx_sb16_options *opt)
{
if (!opt->present) {
fprintf (fp, "# no sb16\n");
return 0;
}
fprintf (fp, "sb16: midimode=%d, midi=%s, wavemode=%d, wave=%s, loglevel=%d, log=%s, dmatimer=%d\n", opt->midimode, opt->midifile, opt->wavemode, opt->wavefile, opt->loglevel, opt->logfile, opt->dmatimer);
return 0;
}
int
bx_write_ne2k_options (FILE *fp, bx_ne2k_options *opt)
{
if (!opt->valid) {
fprintf (fp, "# no ne2k\n");
return 0;
}
fprintf (fp, "ne2k: ioaddr=0x%x, irq=%d, mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s\n",
opt->ioaddr,
opt->irq,
opt->macaddr[0],
opt->macaddr[1],
opt->macaddr[2],
opt->macaddr[3],
opt->macaddr[4],
opt->macaddr[5],
opt->ethmod,
opt->ethdev);
return 0;
}
int
bx_write_loader_options (FILE *fp, bx_load32bitOSImage_t *opt)
{
if (opt->whichOS == 0) {
fprintf (fp, "# no loader\n");
return 0;
}
BX_ASSERT(opt->whichOS == Load32bitOSLinux || opt->whichOS == Load32bitOSNullKernel);
fprintf (fp, "load32bitOSImage: os=%s, path=%s, iolog=%s, initrd=%s\n",
(opt->whichOS == Load32bitOSLinux) ? "linux" : "nullkernel",
opt->path,
opt->iolog,
opt->initrd);
return 0;
}
int
bx_write_log_options (FILE *fp, bx_log_options *opt)
{
fprintf (fp, "log: %s\n", opt->filename);
// no syntax to describe all the possible action settings for every
// device. Instead, take a vote and record the most popular action
// for each level of event.
int action_tally[N_ACT];
int most_popular_action[N_LOGLEV];
int i,j,lev;
for (lev = 0; lev < N_LOGLEV; lev++) {
// clear tally
for (i=0; i<N_ACT; i++)
action_tally[i] = 0;
// count how many devices use each action
for (i=0; i<io->get_n_logfns (); i++) {
logfunc_t *fn = io->get_logfn (i);
int action = fn->getonoff(lev);
BX_ASSERT (action >= 0 && action < N_ACT);
action_tally[action]++;
}
// count the votes
int best = 0, best_votes = action_tally[0];
for (i=1; i<N_ACT; i++) {
if (action_tally[i] > best_votes) {
best = i;
best_votes = action_tally[i];
}
}
most_popular_action[lev] = best;
}
fprintf (fp, "panic: action=%s\n",
io->getaction(most_popular_action[LOGLEV_PANIC]));
fprintf (fp, "error: action=%s\n",
io->getaction(most_popular_action[LOGLEV_ERROR]));
fprintf (fp, "info: action=%s\n",
io->getaction(most_popular_action[LOGLEV_INFO]));
fprintf (fp, "debug: action=%s\n",
io->getaction(most_popular_action[LOGLEV_DEBUG]));
}
// return values:
// 0: written ok
// -1: failed
// -2: already exists, and overwrite was off
int
bx_write_configuration (char *rc, int overwrite)
{
BX_INFO (("write configuration to %s\n", rc));
// check if it exists. If so, only proceed if overwrite is set.
FILE *fp = fopen (rc, "r");
if (fp != NULL) {
fclose (fp);
if (!overwrite) return -2;
}
fp = fopen (rc, "w");
if (fp == NULL) return -1;
// finally it's open and we can start writing.
fprintf (fp, "# configuration file generated by Bochs\n");
// it would be nice to put this type of function as methods on
// the structs like bx_floppy_options::print or something.
bx_write_floppy_options (fp, 0, &bx_options.floppya);
bx_write_floppy_options (fp, 1, &bx_options.floppyb);
bx_write_disk_options (fp, 0, &bx_options.diskc);
bx_write_disk_options (fp, 1, &bx_options.diskd);
bx_write_cdrom_options (fp, 0, &bx_options.cdromd);
if (bx_options.rom.path)
fprintf (fp, "romimage: file=%s, address=0x%05x\n", bx_options.rom.path, bx_options.rom.address);
else
fprintf (fp, "# no romimage\n");
if (bx_options.vgarom.path)
fprintf (fp, "vgaromimage: %s\n", bx_options.vgarom.path);
else
fprintf (fp, "# no vgaromimage\n");
fprintf (fp, "megs: %d\n", bx_options.memory.megs);
bx_write_sb16_options (fp, &bx_options.sb16);
fprintf (fp, "boot: %s\n", bx_options.bootdrive);
fprintf (fp, "vga_update_interval: %d\n", bx_options.vga_update_interval);
fprintf (fp, "keyboard_serial_delay: %d\n", bx_options.keyboard_serial_delay);
fprintf (fp, "floppy_command_delay: %d\n", bx_options.floppy_command_delay);
fprintf (fp, "ips: %d\n", bx_options.ips);
fprintf (fp, "mouse: enabled=%d\n", bx_options.mouse_enabled);
fprintf (fp, "private_colormap: enabled=%d\n", bx_options.private_colormap);
fprintf (fp, "i440fxsupport: enabled=%d\n", bx_options.i440FXSupport);
fprintf (fp, "time0: %u\n", bx_options.cmos.time0);
bx_write_ne2k_options (fp, &bx_options.ne2k);
fprintf (fp, "newharddrivesupport: enabled=%d\n", bx_options.newHardDriveSupport);
bx_write_loader_options (fp, &bx_options.load32bitOSImage);
bx_write_log_options (fp, &bx_options.log);
fclose (fp);
return 0;
}
#endif // #if BX_PROVIDE_MAIN
void