From 985d4b7923f715acaf7857e846293f7fbf1949ab Mon Sep 17 00:00:00 2001 From: Bryce Denney Date: Mon, 11 Jun 2001 06:35:18 +0000 Subject: [PATCH] - 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. --- bochs/bochs.h | 24 ++-- bochs/gui/control.cc | 111 ++++++++++------- bochs/gui/siminterface.cc | 36 +++--- bochs/gui/siminterface.h | 3 +- bochs/main.cc | 253 +++++++++++++++++++++++++++++++++----- 5 files changed, 331 insertions(+), 96 deletions(-) diff --git a/bochs/bochs.h b/bochs/bochs.h index 39ee4a675..c4bb794b2 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -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=0 && level=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; diff --git a/bochs/gui/control.cc b/bochs/gui/control.cc index 41349bfa8..be99701e9 100644 --- a/bochs/gui/control.cc +++ b/bochs/gui/control.cc @@ -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); } diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index babbc6f1c..93f1e0f0b 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -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; } diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 1882d30f1..758c2c985 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -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;} diff --git a/bochs/main.cc b/bochs/main.cc index 4000b8cb5..ab997908b 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -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; iset_log_action (level, bx_options.log_actions[level]); + for (int level=0; levelset_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 4) { if (strncmp(params[4], "ethmod=", 7)) { BX_PANIC(("%s: ne2k directive malformed.", context)); + return; } bx_options.ne2k.ethmod = strdup(¶ms[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(¶ms[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; iget_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 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