- more work on text-mode control panel. Now the control panel starts before

the simulation begins, to give you a chance to choose between bochsrcs,
  choose the boot disk, etc.
This commit is contained in:
Bryce Denney 2001-06-09 20:01:12 +00:00
parent c8c5a94297
commit 8b7fbca53e
12 changed files with 1161 additions and 496 deletions

View File

@ -82,7 +82,9 @@ extern "C" {
#include "debug/debug.h"
#include "bxversion.h"
#if BX_USE_CONTROL_PANEL
#include "gui/siminterface.h"
#endif
//
// some macros to interface the CPU and memory to external environment
@ -502,7 +504,7 @@ typedef struct {
void* record_io;
} bx_debug_t;
#define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%s\n", #x, __FILE__, __LINE__));} while (0)
#define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%d\n", #x, __FILE__, __LINE__));} while (0)
void bx_signal_handler (int signum);
void bx_atexit(void);
extern bx_debug_t bx_dbg;
@ -555,8 +557,16 @@ extern bx_devices_c bx_devices;
#define BX_RESET_SOFTWARE 10
#define BX_RESET_HARDWARE 11
char *bx_find_bochsrc (void);
int bx_read_configuration (char *rcfile, int argc, char *argv[]);
#if BX_USE_CONTROL_PANEL==0
// with control panel enabled, this is defined in gui/siminterface.h instead.
#define BX_PATHNAME_LEN 512
// for control panel, I moved these into gui/siminterface.h. BBD
typedef struct {
char path[BX_PATHNAME_LEN];
unsigned type;
@ -577,6 +587,7 @@ struct bx_cdrom_options
char dev[BX_PATHNAME_LEN];
Boolean inserted;
};
#endif /* if BX_USE_CONTROL_PANEL==0 */
typedef struct {
char *path;
@ -652,6 +663,7 @@ typedef struct {
// 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_options_t;
extern bx_options_t bx_options;
@ -665,7 +677,7 @@ extern bx_options_t bx_options;
#define BX_USE_PS2_MOUSE 1
int bx_bochs_init(int argc, char *argv[]);
int bx_init_hardware ();
#include "instrument.h"

View File

@ -40,6 +40,8 @@
// USER CONFIGURABLE OPTIONS : EDIT ONLY OPTIONS IN THIS SECTION //
///////////////////////////////////////////////////////////////////
#define BX_USE_CONTROL_PANEL 1
// I have tested the following combinations:
// * processors=1, bootstrap=0, ioapic_id=1 (uniprocessor system)
// * processors=2, bootstrap=0, ioapic_id=2

383
bochs/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,24 @@ AC_TRY_COMPILE([#include <hash_map.h>], [],
], AC_MSG_RESULT(no))
AC_LANG_RESTORE
AC_MSG_CHECKING(for control panel)
AC_ARG_ENABLE(control-panel,
[ --enable-control-panel allows split hard disk image],
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_USE_CONTROL_PANEL, 1)
else
AC_MSG_RESULT(no)
AC_DEFINE(BX_USE_CONTROL_PANEL, 0)
fi],
[
AC_MSG_RESULT(yes)
AC_DEFINE(BX_USE_CONTROL_PANEL, 1)
]
)
AC_SUBST(BX_USE_CONTROL_PANEL)
AC_MSG_CHECKING(for number of processors)
AC_ARG_ENABLE(processors,
[ --enable-processors select number of processors (1,2,4)],

View File

@ -61,7 +61,7 @@ BX_GUI_OBJS = $(GUI_OBJS)
BX_INCLUDES = iodev.h control.h siminterface.h
.@CPP_SUFFIX@.o:
.@CPP_SUFFIX@.o: $(BX_INCLUDES)
$(CXX) @DASH@c $(CXXFLAGS) $(LOCAL_CXXFLAGS) $(BX_INCDIRS) @CXXFP@$< @OFP@$@

View File

@ -1,6 +1,6 @@
/*
* gui/control.cc
* $Id: control.cc,v 1.2 2001-06-08 07:20:07 bdenney Exp $
* $Id: control.cc,v 1.3 2001-06-09 20:01:12 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
@ -52,21 +52,35 @@ 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.
say we need to implement prototypes and type checking. Why not just
write a compiler!
*/
extern "C" {
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
}
#include "control.h"
#include "siminterface.h"
#define BX_PANIC(x) printf x
void bx_floppy_change ();
/* functions for changing particular options */
void bx_edit_floppy (int drive);
void bx_edit_hard_disk (int drive);
void bx_edit_cdrom ();
void bx_newhd_support ();
void bx_boot_from ();
void bx_ips_change ();
void bx_log_options ();
int bx_read_rc (char *rc);
void bx_log_file ();
void bx_log_options (int individual);
void bx_vga_update_interval ();
void bx_mouse_enable ();
/******************************************************************/
/* lots of code stolen from bximage.c */
@ -97,7 +111,7 @@ ask_int (char *prompt, int min, int max, int the_default, int *out)
char *clean;
int illegal;
while (1) {
printf ("%s", prompt);
printf (prompt, the_default);
if (!fgets (buffer, sizeof(buffer), stdin))
return -1;
clean = clean_string (buffer);
@ -126,7 +140,7 @@ ask_menu (char *prompt, int n_choices, char *choice[], int the_default, int *out
int i;
*out = -1;
while (1) {
printf ("%s", prompt);
printf (prompt, choice[the_default]);
if (!fgets (buffer, sizeof(buffer), stdin))
return -1;
clean = clean_string (buffer);
@ -158,7 +172,8 @@ ask_yn (char *prompt, int the_default, int *out)
char *clean;
*out = -1;
while (1) {
printf ("%s", prompt);
// if there's a %s field, substitute in the default yes/no.
printf (prompt, the_default ? "yes" : "no");
if (!fgets (buffer, sizeof(buffer), stdin))
return -1;
clean = clean_string (buffer);
@ -181,7 +196,7 @@ ask_string (char *prompt, char *the_default, char *out)
char buffer[1024];
char *clean;
out[0] = 0;
printf ("%s", prompt);
printf (prompt, the_default);
if (!fgets (buffer, sizeof(buffer), stdin))
return -1;
clean = clean_string (buffer);
@ -196,83 +211,377 @@ ask_string (char *prompt, char *the_default, char *out)
/******************************************************************/
/*
What should I be able to change?
- floppy disk image name
- ips value
- debug for each device.
- vga update interval
- mouse enabled
- keyboard serial delay
- floppy command delay
- start tracing instructions?
- simulate a particular keystroke
- continue simulation
*/
static char *main_menu_prompt =
static char *ask_about_control_panel =
"\n\
-------------------------------\n\
Bochs Control Panel (text mode)\n\
-------------------------------\n\
1. floppy disk image name \n\
2. ips value \n\
3. set logging options \n\
4. vga update interval \n\
5. mouse enabled \n\
6. keyboard serial delay \n\
7. floppy command delay \n\
8. start tracing instructions? \n\
9. simulate a particular keystroke \n\
10. Continue simulation \n\
11. Quit simulation\n\
This version of Bochs has a prototype configuration interface. Would\n\
you like to try it?\n\
\n\
Please choose one: [10] ";
If you choose yes, you can use a menu to choose configuration options.\n\
If you choose no, Bochs will read a bochsrc file and run as usual.\n\
Type yes or no: [yes] ";
void bx_control_panel_main ()
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\
\n\
Please choose one: [%d] ";
static char *startup_options_prompt =
"------------------\n\
Bochs Options Menu\n\
------------------\n\
0. Return to previous menu\n\
1. Log file: %s\n\
2. Log options for all devices\n\
3. Log options for individual devices\n\
4. Boot options\n\
5. Interface options\n\
6. Disk options\n\
7. Sound options\n\
8. Other options\n\
\n\
Please choose one: [0] ";
static char *startup_boot_options_prompt =
"------------------\n\
Bochs Boot Options\n\
------------------\n\
0. Return to previous menu\n\
1. Memory in Megabytes: %d\n\
2. VGA ROM image: %s\n\
3. ROM image: %s\n\
4. ROM address: 0x%05x\n\
\n\
Please choose one: [0] ";
static char *startup_interface_options =
"------------------\n\
Bochs Interface Options\n\
------------------\n\
0. Return to previous menu\n\
1. VGA Update Interval: 300000\n\
2. Mouse: enabled\n\
3. Emulated instructions per second (IPS): 1000000\n\
4. Private Colormap: enabled=0\n\
\n\
Please choose one: [0] ";
static char *startup_disk_options_prompt =
"------------------\n\
Bochs Disk Options\n\
------------------\n\
0. Return to previous menu\n\
1. Floppy disk 0: %s\n\
2. Floppy disk 1: %s\n\
3. Hard disk 0: %s\n\
4. Hard disk 1: %s\n\
5. CDROM: %s\n\
6. New Hard Drive Support: %s\n\
7. Boot from: %s\n\
\n\
Please choose one: [0] ";
static char *startup_sound_options_prompt =
"------------------\n\
Bochs Sound Options\n\
------------------\n\
0. Return to previous menu\n\
1. Sound Blaster 16: disabled\n\
2. MIDI mode: 1, \n\
3. MIDI output file: /dev/midi00\n\
4. Wave mode: 1\n\
5. Wave output file: dev/dsp\n\
6. SB16 log level: 2\n\
7. SB16 log file: sb16.log\n\
8. DMA Timer: 600000\n\
\n\
Please choose one: [0] ";
static char *startup_misc_options_prompt =
"---------------------------\n\
Bochs Miscellaneous Options\n\
---------------------------\n\
1. Keyboard Serial Delay: 250\n\
2. Floppy command delay: 500\n\
\n\
Please choose one: [0] ";
static char *runtime_menu_prompt =
"---------------------\n\
Bochs Runtime Options\n\
---------------------\n\
1. Floppy disk 0 (example:a.img, 1.44MB, inserted)\n\
2. Floppy disk 1 (example:b.img, 1.44MB, inserted)\n\
3. Emulated instructions per second (IPS)\n\
4. Logging options\n\
5. VGA Update Interval\n\
6. Mouse: enabled\n\
7. Instruction tracing: off (doesn't exist yet)\n\
8. Continue simulation\n\
9. Quit now\n\
\n\
Please choose one: [8] ";
char *menu_prompt_list[BX_CPANEL_N_MENUS] = {
ask_about_control_panel,
startup_menu_prompt,
startup_options_prompt,
startup_boot_options_prompt,
startup_interface_options,
startup_disk_options_prompt,
startup_sound_options_prompt,
startup_misc_options_prompt,
runtime_menu_prompt
};
#define NOT_IMPLEMENTED(choice) \
fprintf (stderr, "ERROR: choice %d not implemented\n", choice);
#define BAD_OPTION(menu,choice) \
do {fprintf (stderr, "ERROR: control panel menu %d has no choice %d\n", menu, choice); \
assert (0); } while (0)
char *fdsize_choices[] = { "0.72","1.2","1.44","2.88" };
int fdsize_n_choices = 4;
void build_disk_options_prompt (char *format, char *buf, int size)
{
int choice;
while (1) {
if (ask_int (main_menu_prompt, 1, 11, 10, &choice) < 0) return;
switch (choice)
{
case 1:
bx_floppy_change ();
break;
case 2:
bx_ips_change ();
break;
case 3:
bx_log_options ();
break;
case 10:
fprintf (stderr, "Continuing simulation\n");
return;
case 11:
fprintf (stderr, "You chose quit on the control panel.\n");
SIM->quit_sim ();
break;
default:
fprintf (stderr, "Menu choice %d not implemented.\n", choice);
}
bx_floppy_options floppyop;
bx_disk_options diskop;
bx_cdrom_options cdromop;
char buffer[6][128];
for (int i=0; i<2; i++) {
SIM->get_floppy_options (i, &floppyop);
sprintf (buffer[i], "%s, size=%s, %s", floppyop.path,
SIM->get_floppy_type_name (floppyop.type),
floppyop.initial_status ? "inserted" : "ejected");
if (!floppyop.path[0]) strcpy (buffer[i], "none");
SIM->get_disk_options (i, &diskop);
sprintf (buffer[2+i], "%s, %d cylinders, %d heads, %d sectors/track",
diskop.path, diskop.cylinders, diskop.heads, diskop.spt);
if (!diskop.path[0]) strcpy (buffer[2+i], "none");
}
SIM->get_cdrom_options (0, &cdromop);
sprintf (buffer[4], "%s, %spresent, %s",
cdromop.dev, cdromop.present?"":"not ",
cdromop.inserted?"inserted":"ejected");
if (!cdromop.dev[0]) strcpy (buffer[4], "none");
sprintf (buffer[5], "%s", SIM->get_newhd_support () ? "yes":"no");
sprintf (buffer[6], "%s", SIM->get_boot_hard_disk () ? "hard drive":"floppy drive");
snprintf (buf, size, format, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6]);
}
// return value of bx_control_panel:
// -1: error while reading, like if stdin closed
// 0: no error
// BX_DISABLE_CONTROL_PANEL: returned from BX_CPANEL_START_MAIN if
// user chooses to revert to the normal way of running without the
// control panel.
int bx_control_panel (int menu)
{
int choice;
while (1) {
switch (menu)
{
case BX_CPANEL_START_MAIN:
{
if (ask_yn (ask_about_control_panel, 1, &choice) < 0) return -1;
if (choice == 0) return BX_DISABLE_CONTROL_PANEL;
else return bx_control_panel (BX_CPANEL_START_MENU);
}
case BX_CPANEL_START_MENU:
{
char rc[512], prompt[512];
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;
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;
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);
sprintf (prompt, startup_options_prompt, oldpath);
if (ask_int (prompt, 0, 7, 0, &choice) < 0) return -1;
switch (choice) {
case 0: return 0;
case 1: bx_log_file (); break;
case 2: bx_log_options (0); break;
case 3: bx_log_options (1); break;
case 4: bx_control_panel (BX_CPANEL_START_OPTS_BOOT); break;
case 5: bx_control_panel (BX_CPANEL_START_OPTS_INTERFACE); break;
case 6: bx_control_panel (BX_CPANEL_START_OPTS_DISK); break;
case 7: bx_control_panel (BX_CPANEL_START_OPTS_SOUND); break;
case 8: bx_control_panel (BX_CPANEL_START_OPTS_MISC); break;
default: BAD_OPTION(menu, choice);
}
}
break;
case BX_CPANEL_START_OPTS_BOOT:
{
char prompt[512];
build_disk_options_prompt (startup_boot_options_prompt, prompt, 512);
if (ask_int (prompt, 0, 4, 0, &choice) < 0) return -1;
switch (choice) {
case 0: return 0;
case 1: NOT_IMPLEMENTED (choice); break;
case 2: NOT_IMPLEMENTED (choice); break;
case 3: NOT_IMPLEMENTED (choice); break;
case 4: NOT_IMPLEMENTED (choice); break;
default: BAD_OPTION(menu, choice);
}
}
break;
case BX_CPANEL_START_OPTS_DISK:
{
char prompt[512];
build_disk_options_prompt (startup_disk_options_prompt, prompt, 512);
if (ask_int (prompt, 0, 7, 0, &choice) < 0) return -1;
switch (choice) {
case 0: return 0;
case 1: bx_edit_floppy (0); break;
case 2: bx_edit_floppy (1); break;
case 3: bx_edit_hard_disk (0); break;
case 4: bx_edit_hard_disk (1); break;
case 5: bx_edit_cdrom (); break;
case 6: bx_newhd_support (); break;
case 7: bx_boot_from (); break;
default: BAD_OPTION(menu, choice);
}
}
break;
case BX_CPANEL_RUNTIME:
if (ask_int (runtime_menu_prompt, 1, 9, 8, &choice) < 0) return -1;
switch (choice) {
case 1: bx_edit_floppy (0); break;
case 2: bx_edit_floppy (1); break;
case 3: bx_ips_change (); break;
case 4: bx_log_options (1); break;
case 5: bx_vga_update_interval (); break;
case 6: bx_mouse_enable (); break;
case 7: NOT_IMPLEMENTED (choice); break;
case 8: fprintf (stderr, "Continuing simulation\n"); return 0;
case 9:
fprintf (stderr, "You chose quit on the control panel.\n");
SIM->quit_sim (1);
return -1;
default: fprintf (stderr, "Menu choice %d not implemented.\n", choice);
}
break;
default:
assert (menu >=0 && menu < BX_CPANEL_N_MENUS);
fprintf (stderr, "--THIS IS A SAMPLE MENU, NO OPTIONS ARE IMPLEMENTED EXCEPT #0--\n");
if (ask_int (menu_prompt_list[menu], 0, 99, 0, &choice) < 0) return -1;
if (choice == 0) return 0;
fprintf (stderr, "This is a sample menu. Option %d is not implemented.\n", choice);
}
}
}
void bx_edit_floppy (int drive)
{
bx_floppy_options opt, newopt;
assert (SIM->get_floppy_options (drive, &opt) >= 0);
newopt = opt;
fprintf (stderr, "Changing options for floppy drive %d\n", drive);
if (ask_string ("Enter new pathname: [%s] ", opt.path, newopt.path) < 0)
return;
int newtype, oldtype = opt.type - BX_FLOPPY_NONE;
if (ask_menu ("What is the floppy disk size?\nChoices are 720K, 1.2M, 1.44M, 2.88M. [%s] ", n_floppy_type_names, floppy_type_names, oldtype, &newtype) < 0) return;
newopt.type = newtype + BX_FLOPPY_NONE;
if (SIM->set_floppy_options (drive, &newopt) < 0) {
fprintf (stderr, "The disk image %s could not be opened.\n", newopt.path);
}
}
void bx_floppy_change ()
void bx_edit_hard_disk (int drive)
{
int drive;
if (ask_int ("Change floppy 0 or 1? [0] ", 0, 1, 0, &drive) < 0)
bx_disk_options opt, newopt;
assert (SIM->get_disk_options (drive, &opt) >= 0);
newopt = opt;
fprintf (stderr, "Changing options for hard drive %d\n", drive);
if (ask_string ("Enter new pathname, or type 'none' for no disk: [%s] ", opt.path, newopt.path) < 0)
return;
char oldpath[1024], newpath[1024];
SIM->get_floppy_path (drive, oldpath, 1024);
char prompt[1024];
sprintf (prompt, "Enter new pathname: [%s] ", oldpath);
if (ask_string (prompt, oldpath, newpath) < 0)
if (!strcmp (newopt.path, "none")) newopt.path[0] = 0;
if (newopt.path[0]) { // skip if "none" is the path.
// ask cyl, head, sec.
int n;
if (ask_int ("How many cylinders? [%d] ", 1, 65535, opt.cylinders, &n) < 0)
return;
newopt.cylinders = n;
if (ask_int ("How many heads? [%d] ", 1, 256, opt.heads, &n) < 0)
return;
newopt.heads = n;
if (ask_int ("How many sectors per track? [%d] ", 1, 255, opt.spt, &n) < 0)
return;
newopt.spt = n;
}
if (SIM->set_disk_options (drive, &newopt) < 0) {
fprintf (stderr, "The disk image %s could not be opened.\n", newopt.path);
}
}
void bx_edit_cdrom ()
{
bx_cdrom_options opt, newopt;
assert (SIM->get_cdrom_options (0, &opt) >= 0);
newopt = opt;
newopt.present = 1;
if (ask_string ("Enter pathname of the cdrom device, or 'none' for no cdrom: [%s] ", opt.dev, newopt.dev) < 0)
return;
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);
if (!strcmp (newopt.dev, "none")) {
newopt.dev[0] = 0;
newopt.present = 0;
}
if (SIM->set_cdrom_options (0, &newopt) < 0) {
fprintf (stderr, "The device at %s could not be opened.\n", newopt.dev);
}
}
void bx_newhd_support ()
{
int newval, oldval = SIM->get_newhd_support ();
if (ask_yn ("Use new hard disk support (recommended)? [%s] ", oldval, &newval) < 0) return;
if (newval == oldval) return;
SIM->set_newhd_support (newval);
}
void bx_boot_from ()
{
int newval, oldval = SIM->get_boot_hard_disk ();
char *choices[] = {"fd","hd"};
if (ask_menu ("Boot floppy disk or hard disk? Type hd or fd. [%s] ",
2, choices, oldval, &newval) < 0) return;
SIM->set_boot_hard_disk (newval);
}
void bx_ips_change ()
@ -286,12 +595,24 @@ void bx_ips_change ()
SIM->setips (newips);
}
void bx_vga_update_interval ()
{
char prompt[1024];
int old = SIM->get_vga_update_interval ();
sprintf (prompt, "Type a new value for VGA update interval: [%d] ", old);
int newinterval;
if (ask_int (prompt, 1, 1<<30, old, &newinterval) < 0)
return;
SIM->set_vga_update_interval (newinterval);
}
static void bx_print_log_action_table ()
{
// just try to print all the prefixes first.
fprintf (stderr, "Current log settings:\n");
fprintf (stderr, " Debug Info Error Panic\n");
fprintf (stderr, "ID Device Action Action Action Action\n");
fprintf (stderr, "---- --------- --------- --------- ---------- ----------\n");
int i, imax=SIM->get_n_log_modules ();
for (int i=0; i<imax; i++) {
fprintf (stderr, "%3d. %s ", i, SIM->get_prefix (i));
@ -303,26 +624,75 @@ static void bx_print_log_action_table ()
}
static char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
static char *log_level_choices[] = { "ignore", "report", "fatal" };
static char *log_level_choices[] = { "ignore", "report", "fatal", "no change" };
void bx_log_options ()
void bx_log_options (int individual)
{
int done = 0;
while (!done) {
bx_print_log_action_table ();
int id, level, action;
int maxid = SIM->get_n_log_modules ();
if (ask_int (log_options_prompt1, -1, maxid-1, -1, &id) < 0)
return;
if (id < 0) return;
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 = 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)
if (individual) {
int done = 0;
while (!done) {
bx_print_log_action_table ();
int id, level, action;
int maxid = SIM->get_n_log_modules ();
if (ask_int (log_options_prompt1, -1, maxid-1, -1, &id) < 0)
return;
SIM->set_log_action (id, level, action);
if (id < 0) return;
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 = 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));
// don't show the no change choice (choices=3)
if (ask_menu (prompt, 3, log_level_choices, default_action, &action)<0)
return;
SIM->set_log_action (id, level, action);
}
}
} else {
// provide an easy way to set log options for all devices at once
bx_print_log_action_table ();
for (int level=0; level<SIM->get_max_log_level (); level++) {
char prompt[1024];
int action, default_action = 3; // default to no change
sprintf (prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name (level));
// do show the no change choice (choices=4)
if (ask_menu (prompt, 4, log_level_choices, default_action, &action)<0)
return;
if (action < 3) {
for (int i=0; i<SIM->get_n_log_modules (); i++)
SIM->set_log_action (i, level, action);
}
}
}
}
void bx_mouse_enable ()
{
int newval, oldval = SIM->get_mouse_enabled ();
if (ask_yn ("Enable the mouse? [%s] ", oldval, &newval) < 0) return;
if (newval == oldval) return;
SIM->set_mouse_enabled (newval);
}
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];
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 (!strcmp (newrc, "none")) return 0;
if (SIM->read_rc (newrc) >= 0) return 0;
fprintf (stderr, "The file '%s' could not be found.\n", newrc);
}
}
void bx_log_file ()
{
char oldpath[512], newpath[512];
assert (SIM->get_log_file (oldpath, 512) >= 0);
if (ask_string ("Enter log file name: [%s] ", oldpath, newpath) < 0) return;
SIM->set_log_file (newpath);
}

View File

@ -1 +1,17 @@
void bx_control_panel_main ();
enum {
BX_CPANEL_START_MAIN,
BX_CPANEL_START_MENU,
BX_CPANEL_START_OPTS,
BX_CPANEL_START_OPTS_BOOT,
BX_CPANEL_START_OPTS_INTERFACE,
BX_CPANEL_START_OPTS_DISK,
BX_CPANEL_START_OPTS_SOUND,
BX_CPANEL_START_OPTS_MISC,
BX_CPANEL_RUNTIME,
BX_CPANEL_N_MENUS
};
/* special return value from bx_control_panl */
#define BX_DISABLE_CONTROL_PANEL 10
int bx_control_panel (int menu);

View File

@ -51,7 +51,6 @@ 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,
@ -95,8 +94,7 @@ bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
BX_GRAVITY_LEFT, floppyB_handler);
// Mouse button
BX_GUI_THIS mouse_status = gui_get_mouse_enable();
if (BX_GUI_THIS mouse_status)
if (bx_options.mouse_enabled)
BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS mouse_bmap_id,
BX_GRAVITY_LEFT, mouse_handler);
else
@ -176,20 +174,14 @@ bx_gui_c::power_handler(void)
void
bx_gui_c::snapshot_handler(void)
{
bx_control_panel_main ();
bx_control_panel (BX_CPANEL_RUNTIME);
}
void
bx_gui_c::mouse_handler(void)
{
BX_GUI_THIS mouse_status = ! BX_GUI_THIS mouse_status;
if (BX_GUI_THIS mouse_status)
replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS mouse_bmap_id);
else
replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS nomouse_bmap_id);
gui_set_mouse_enable(BX_GUI_THIS mouse_status);
int old = gui_get_mouse_enable ();
gui_set_mouse_enable (!old);
}
Boolean
@ -202,6 +194,11 @@ bx_gui_c::gui_get_mouse_enable(void)
bx_gui_c::gui_set_mouse_enable(Boolean val)
{
bx_options.mouse_enabled = val;
BX_DEBUG (("maybe this should happen only if window has been created"));
if (bx_options.mouse_enabled)
replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS mouse_bmap_id);
else
replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS nomouse_bmap_id);
}
void

View File

@ -77,7 +77,6 @@ private:
unsigned power_bmap_id, power_hbar_id;
unsigned reset_bmap_id, reset_hbar_id;
unsigned snapshot_bmap_id, snapshot_hbar_id;
Boolean mouse_status;
unsigned mouse_bmap_id, nomouse_bmap_id, mouse_hbar_id;
};

View File

@ -1,6 +1,6 @@
/*
* gui/siminterface.cc
* $Id: siminterface.cc,v 1.3 2001-06-08 18:02:54 bdenney Exp $
* $Id: siminterface.cc,v 1.4 2001-06-09 20:01:12 bdenney Exp $
*
* Defines the actual link between bx_simulator_interface_c methods
* and the simulator. This file includes bochs.h because it needs
@ -25,56 +25,46 @@ 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 ();
virtual int getips ();
virtual void setips (int ips);
virtual int get_vga_update_interval ();
virtual void set_vga_update_interval (unsigned interval);
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);
virtual char *get_log_level_name (int level);
virtual int get_max_log_level ();
virtual void quit_sim (int clean);
virtual int get_mouse_enabled ();
virtual void set_mouse_enabled (int en);
virtual int get_default_rc (char *path, int len);
virtual int read_rc (char *path);
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);
virtual int set_floppy_options (int drive, bx_floppy_options *in);
virtual int get_disk_options (int drive, bx_disk_options *out);
virtual int set_disk_options (int drive, bx_disk_options *out);
virtual int get_cdrom_options (int drive, bx_cdrom_options *out);
virtual int set_cdrom_options (int drive, bx_cdrom_options *out);
virtual int get_newhd_support ();
virtual void set_newhd_support (int en);
virtual char *get_floppy_type_name (int type);
virtual int get_boot_hard_disk ();
virtual int set_boot_hard_disk (int val);
};
void init_siminterface ()
{
fprintf (stderr, "INIT Interface\n");
if (SIM == NULL) {
BX_INFO (("init_siminterface"));
if (SIM == NULL)
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);
init_done = 0;
}
int
@ -86,6 +76,7 @@ bx_real_sim_c::getips ()
void
bx_real_sim_c::setips (int ips)
{
BX_ERROR (("Changing ips during simulation doesn't really work yet. We need to reschedule the timers or something."));
bx_options.ips = ips;
}
@ -135,7 +126,149 @@ bx_real_sim_c::get_max_log_level ()
}
void
bx_real_sim_c::quit_sim () {
BX_PANIC (("Quit simulation command"));
bx_real_sim_c::quit_sim (int clean) {
if (!clean)
BX_PANIC (("Quit simulation command"));
::exit (0);
}
int
bx_real_sim_c::get_vga_update_interval () {
return bx_options.vga_update_interval;
}
void
bx_real_sim_c::set_vga_update_interval (unsigned interval) {
bx_vga.set_update_interval (interval);
}
int bx_real_sim_c::get_mouse_enabled () {
return bx_gui.gui_get_mouse_enable ();
}
void bx_real_sim_c::set_mouse_enabled (int en) {
bx_gui.gui_set_mouse_enable (en!=0);
}
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)
{
return bx_read_configuration (rc, 0, NULL);
}
int
bx_real_sim_c::get_log_file (char *path, int len)
{
strncpy (path, bx_options.logfilename, len);
return 0;
}
int
bx_real_sim_c::set_log_file (char *path)
{
strncpy (bx_options.logfilename, path, sizeof(bx_options.logfilename));
return 0;
}
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;
}
// return values:
// 0: success
// -1: could not open the file given by path (unless type==none)
// -2: could open file but need hint on size
int
bx_real_sim_c::set_floppy_options (int drive, bx_floppy_options *in)
{
bx_floppy_options *dest =
(drive==0)? &bx_options.floppya : &bx_options.floppyb;
if (!get_init_done ()) {
*dest = *in;
return 0;
} else {
// bochs is already running. Try to open the image file
*dest = *in;
bx_devices.floppy->set_media_status (drive, 0);
int status = bx_devices.floppy->set_media_status (drive, 1);
BX_INFO (("set_media_status for drive %d returned %d\n", drive, status));
if (status==0) return -1;
return 0;
}
}
int
bx_real_sim_c::get_disk_options (int drive, bx_disk_options *out)
{
*out = (drive==0)? bx_options.diskc : bx_options.diskd;
}
int
bx_real_sim_c::set_disk_options (int drive, bx_disk_options *in)
{
bx_disk_options *dest = (drive==0)? &bx_options.diskc : &bx_options.diskd;
*dest = *in;
return 0;
}
int
bx_real_sim_c::get_cdrom_options (int drive, bx_cdrom_options *out)
{
BX_ASSERT (drive == 0);
*out = bx_options.cdromd;
}
int
bx_real_sim_c::set_cdrom_options (int drive, bx_cdrom_options *out)
{
BX_ASSERT (drive == 0);
bx_options.cdromd = *out;
}
int
bx_real_sim_c::get_newhd_support ()
{
return bx_options.newHardDriveSupport;
}
void
bx_real_sim_c::set_newhd_support (int en)
{
bx_options.newHardDriveSupport = (en != 0);
}
char *floppy_type_names[] = { "none", "1.2M", "1.44M", "2.88M", "720K" };
int n_floppy_type_names = 5;
char *
bx_real_sim_c::get_floppy_type_name (int type)
{
BX_ASSERT (type >= BX_FLOPPY_NONE && type <= BX_FLOPPY_720K);
type -= BX_FLOPPY_NONE;
return floppy_type_names[type];
}
int
bx_real_sim_c::get_boot_hard_disk ()
{
return bx_options.bootdrive[0] == 'c';
}
int
bx_real_sim_c::set_boot_hard_disk (int val)
{
bx_options.bootdrive[0] = val? 'c' : 'a';
bx_options.bootdrive[1] = 0;
}

View File

@ -1,6 +1,6 @@
/*
* gui/siminterface.h
* $Id: siminterface.h,v 1.1 2001-06-08 07:20:07 bdenney Exp $
* $Id: siminterface.h,v 1.2 2001-06-09 20:01:12 bdenney Exp $
*
* Interface to the simulator, currently only used by control.cc.
* The base class bx_simulator_interface_c, contains only virtual functions
@ -14,14 +14,54 @@
*
*/
#define BX_PATHNAME_LEN 512
#define BX_FLOPPY_NONE 10 // floppy not present
#define BX_FLOPPY_1_2 11 // 1.2M 5.25"
#define BX_FLOPPY_1_44 12 // 1.44M 3.5"
#define BX_FLOPPY_2_88 13 // 2.88M 3.5"
#define BX_FLOPPY_720K 14 // 720K 3.5"
#define BX_FLOPPY_LAST 14 // last legal value of floppy type
#define BX_FLOPPY_GUESS 20 // decide based on image size
extern char *floppy_type_names[];
extern int n_floppy_type_names;
typedef struct {
char path[BX_PATHNAME_LEN];
unsigned type;
unsigned initial_status;
} bx_floppy_options;
typedef struct {
int present;
char path[BX_PATHNAME_LEN];
unsigned int cylinders;
unsigned int heads;
unsigned int spt;
} bx_disk_options;
struct bx_cdrom_options
{
int present;
char dev[BX_PATHNAME_LEN];
int inserted;
};
typedef char *string_list_t[0];
class bx_simulator_interface_c {
int init_done;
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) {}
int get_init_done () { return init_done; }
int set_init_done (int n) { init_done = n; }
virtual int getips () {return -1;}
virtual void setips (int ips) {}
virtual int get_vga_update_interval () {return -1;}
virtual void set_vga_update_interval (unsigned interval) {}
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;}
@ -29,7 +69,24 @@ public:
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 () {}
virtual void quit_sim (int clean) {}
virtual int get_mouse_enabled () {return -1;}
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 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;}
virtual int set_floppy_options (int drive, bx_floppy_options *in) {return -1;}
virtual int get_disk_options (int drive, bx_disk_options *out) {return -1;}
virtual int set_disk_options (int drive, bx_disk_options *in) {return -1;}
virtual int get_cdrom_options (int drive, bx_cdrom_options *out) {return -1;}
virtual int set_cdrom_options (int drive, bx_cdrom_options *out) {return -1;}
virtual int get_newhd_support () {return -1;}
virtual void set_newhd_support (int en) {}
virtual char *get_floppy_type_name (int type) {return NULL;}
virtual int get_boot_hard_disk () {return -1;}
virtual int set_boot_hard_disk (int val) {return -1;}
};
extern bx_simulator_interface_c *SIM;

View File

@ -46,7 +46,7 @@ void bx_close_harddrive(void);
void bx_init_debug(void);
void bx_init_bx_dbg (void);
void bx_emulate_hga_dumps_timer(void);
static char *divider = "========================================================================";
@ -83,18 +83,16 @@ 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
} // ignore debugs, report infos and errors, fatal on panics.
},
"-" // default log file name (stdout)
};
static char bochsrc_path[512];
static char logfilename[512] = "-";
static void parse_line_unformatted(char *line);
static void parse_line_formatted(int num_params, char *params[]);
static void parse_bochsrc(int argc);
static void parse_line_unformatted(char *context, char *line);
static void parse_line_formatted(char *context, int num_params, char *params[]);
static int parse_bochsrc(char *rcfile);
// Just for the iofunctions
@ -430,30 +428,69 @@ void bx_print_header ()
int
main(int argc, char *argv[])
{
// To deal with initialization order problems inherent in C++, use
// the macros SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog"
// in all constructors or functions called by constructors. The macros
// test for NULL and create the object if necessary, then return it.
// Ensure that io and genlog get created, by making one reference to
// each macro right here. All other code can call them directly.
// To deal with initialization order problems inherent in C++, use the macros
// SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog" in all
// constructors or functions called by constructors. The macros test for
// NULL and create the object if necessary, then return it. Ensure that io
// and genlog get created, by making one reference to each macro right here.
// All other code can reference io and genlog directly.
SAFE_GET_IOFUNC();
SAFE_GET_GENLOG();
bx_print_header ();
bx_init_bx_dbg ();
int read_rc_already = 0;
#if BX_USE_CONTROL_PANEL
// Display the pre-simulation control panel.
init_siminterface ();
if ((bx_control_panel (BX_CPANEL_START_MAIN)) != BX_DISABLE_CONTROL_PANEL)
read_rc_already = 1;
#endif
if (!read_rc_already) {
/* parse configuration file and command line arguments */
char *bochsrc = bx_find_bochsrc ();
if (bochsrc)
bx_read_configuration (bochsrc, argc, argv);
if (bochsrc == NULL && argc == 1) {
// no bochsrc used. This is legal since they may have
// everything on the command line. However if they have no
// arguments then give them some friendly advice.
fprintf (stderr, "%s\n", divider);
fprintf (stderr, "Before running Bochs, you should cd to a directory which contains\n");
fprintf (stderr, "a .bochsrc file and a disk image. If you downloaded a binary package,\n");
fprintf (stderr, "all the necessary files are already on your disk.\n");
#if defined(WIN32)
fprintf (stderr, "\nFor Windows installations, go to the dlxlinux direectory and\n");
fprintf (stderr, "double-click on the start.bat script.\n");
#elif !defined(macintosh)
fprintf (stderr, "\nFor UNIX installations, try running \"bochs-dlx\" for a demo. This script\n");
fprintf (stderr, "is basically equivalent to typing:\n");
fprintf (stderr, " cd /usr/local/bochs/dlxlinux\n");
fprintf (stderr, " bochs\n");
#endif
exit(1);
}
}
#if BX_DEBUGGER
// If using the debugger, it will take control and call
// bx_bochs_init() and cpu_loop()
// bx_init_hardware() and cpu_loop()
bx_dbg_main(argc, argv);
#else
// If not using the debugger, pass control on normally
bx_bochs_init(argc, argv);
bx_init_hardware();
if (bx_options.load32bitOSImage.whichOS) {
void bx_load32bitOSimagehack(void);
bx_load32bitOSimagehack();
}
#if BX_USE_CONTROL_PANEL
SIM->set_init_done (1);
#endif
if (BX_SMP_PROCESSORS == 1) {
// only one processor, run as fast as possible by not messing with
// quantums and loops.
@ -477,45 +514,41 @@ main(int argc, char *argv[])
return(0);
}
int
bx_read_configuration (char *rcfile, int argc, char *argv[])
{
// parse rcfile first, then parse arguments in order.
BX_INFO (("reading configuration from %s", rcfile));
if (parse_bochsrc(rcfile) < 0) {
BX_ERROR (("reading from %s failed", rcfile));
return -1;
}
if (argc > 1)
BX_INFO (("parsing command line arguments"));
int n = 2;
while (n <= argc) {
parse_line_unformatted("cmdline args", argv[n-1]);
n++;
}
return 0;
}
int
bx_bochs_init(int argc, char *argv[])
bx_init_hardware()
{
int n;
#ifdef MAGIC_BREAKPOINT
bx_dbg.magic_break_enabled = 0;
#endif
/* read the .bochsrc file */
parse_bochsrc(argc);
// 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]);
//#if BX_PROVIDE_CPU_MEMORY==1
// else if (!strcmp(argv[n-1], "-sanity-check")) {
// BX_CPU.sanity_checks();
// n += 1;
// exit(0);
// }
//#endif
// Pass all command line options to be parsed,
// just like they came from the .bochsrc. Thus
// command line options will override .bochsrc options.
n = 2;
while (n <= argc) {
parse_line_unformatted(argv[n-1]);
n++;
}
bx_pc_system.init_ips(bx_options.ips);
if(logfilename[0]!='-') {
BX_INFO (("using log file %s", logfilename));
io->init_log(logfilename);
if(bx_options.logfilename[0]!='-') {
BX_INFO (("using log file %s", bx_options.logfilename));
io->init_log(bx_options.logfilename);
}
// set up memory and CPU objects
@ -545,14 +578,12 @@ bx_bochs_init(int argc, char *argv[])
}
#endif
bx_init_debug();
#if BX_DEBUGGER == 0
bx_devices.init(BX_MEM(0));
bx_gui.init_signal_handlers ();
bx_pc_system.start_timers();
#endif
BX_DEBUG(("bx_bochs_init is setting signal handlers"));
BX_DEBUG(("bx_init_hardware is setting signal handlers"));
// if not using debugger, then we can take control of SIGINT.
// If using debugger, it needs control of this.
#if BX_DEBUGGER==0
@ -572,7 +603,7 @@ bx_bochs_init(int argc, char *argv[])
void
bx_init_debug(void)
bx_init_bx_dbg (void)
{
bx_dbg.floppy = 0;
bx_dbg.keyboard = 0;
@ -601,6 +632,10 @@ bx_init_debug(void)
bx_dbg.record_io = 0;
bx_dbg.serial = 0;
bx_dbg.cdrom = 0;
#ifdef MAGIC_BREAKPOINT
bx_dbg.magic_break_enabled = 0;
#endif
}
@ -638,64 +673,55 @@ bx_emulate_hga_dumps_timer(void)
}
#endif
#if BX_PROVIDE_MAIN
static void
parse_bochsrc(int argc)
{
FILE *fd = NULL;
char *ret;
char line[512];
Bit32u retry = 0, found = 0;
char *
bx_find_bochsrc ()
{
FILE *fd;
char rcfile[512];
Bit32u retry = 0, found = 0;
// try several possibilities for the bochsrc before giving up
while (!found) {
bochsrc_path[0] = 0;
rcfile[0] = 0;
switch (retry++) {
case 0: strcpy (bochsrc_path, ".bochsrc"); break;
case 1: strcpy (bochsrc_path, "bochsrc"); break;
case 2: strcpy (bochsrc_path, "bochsrc.txt"); break;
case 0: strcpy (rcfile, ".bochsrc"); break;
case 1: strcpy (rcfile, "bochsrc"); break;
case 2: strcpy (rcfile, "bochsrc.txt"); break;
case 3:
#if (!defined(WIN32) && !defined(macintosh))
// only try this on unix
{
char *ptr = getenv("HOME");
if (ptr) sprintf (bochsrc_path, "%s/.bochsrc", ptr);
if (ptr) sprintf (rcfile, "%s/.bochsrc", ptr);
}
#endif
break;
default:
// no bochsrc used. This is still legal since they may have
// everything on the command line. However if they have no
// arguments then give them some friendly advice.
BX_INFO(( "could not find a bochsrc file"));
if (argc==1) {
fprintf (stderr, "%s\n", divider);
fprintf (stderr, "Before running Bochs, you should cd to a directory which contains\n");
fprintf (stderr, "a .bochsrc file and a disk image. If you downloaded a binary package,\n");
fprintf (stderr, "all the necessary files are already on your disk.\n");
#if defined(WIN32)
fprintf (stderr, "\nFor Windows installations, go to the dlxlinux direectory and\n");
fprintf (stderr, "double-click on the start.bat script.\n");
#elif !defined(macintosh)
fprintf (stderr, "\nFor UNIX installations, try running \"bochs-dlx\" for a demo. This script\n");
fprintf (stderr, "is basically equivalent to typing:\n");
fprintf (stderr, " cd /usr/local/bochs/dlxlinux\n");
fprintf (stderr, " bochs\n");
#endif
exit(1);
}
return;
return NULL;
}
if (bochsrc_path[0]) {
BX_INFO (("looking for configuration in %s", bochsrc_path));
fd = fopen(bochsrc_path, "r");
if (rcfile[0]) {
BX_DEBUG (("looking for configuration in %s", rcfile));
fd = fopen(rcfile, "r");
if (fd) found = 1;
}
}
assert (fd != NULL && bochsrc_path[0] != 0);
assert (fd != NULL && rcfile[0] != 0);
fclose (fd);
return strdup (rcfile);
}
BX_INFO(("reading configuration from %s", bochsrc_path));
static int
parse_bochsrc(char *rcfile)
{
FILE *fd = NULL;
char *ret;
char line[512];
// try several possibilities for the bochsrc before giving up
fd = fopen (rcfile, "r");
if (!fd) return -1;
do {
ret = fgets(line, sizeof(line)-1, fd);
@ -704,13 +730,13 @@ parse_bochsrc(int argc)
if (len>0)
line[len-1] = '\0';
if ((ret != NULL) && strlen(line)) {
parse_line_unformatted(line);
parse_line_unformatted(rcfile, line);
}
} while (!feof(fd));
}
static void
parse_line_unformatted(char *line)
parse_line_unformatted(char *context, char *line)
{
char *ptr;
unsigned i, string_i;
@ -746,11 +772,11 @@ parse_line_unformatted(char *line)
params[num_params++] = ptr;
ptr = strtok(NULL, ",");
}
parse_line_formatted(num_params, &params[0]);
parse_line_formatted(context, num_params, &params[0]);
}
static void
parse_line_formatted(int num_params, char *params[])
parse_line_formatted(char *context, int num_params, char *params[])
{
int i;
@ -782,7 +808,7 @@ parse_line_formatted(int num_params, char *params[])
bx_options.floppya.initial_status = BX_INSERTED;
}
else {
BX_PANIC(("%s: floppya attribute '%s' not understood.", bochsrc_path,
BX_PANIC(("%s: floppya attribute '%s' not understood.", context,
params[i]));
}
}
@ -813,7 +839,7 @@ parse_line_formatted(int num_params, char *params[])
bx_options.floppyb.initial_status = BX_INSERTED;
}
else {
BX_PANIC(("%s: floppyb attribute '%s' not understood.", bochsrc_path,
BX_PANIC(("%s: floppyb attribute '%s' not understood.", context,
params[i]));
}
}
@ -821,13 +847,13 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp(params[0], "diskc")) {
if (num_params != 5) {
BX_PANIC(("%s: diskc directive malformed.", bochsrc_path));
BX_PANIC(("%s: diskc directive malformed.", context));
}
if (strncmp(params[1], "file=", 5) ||
strncmp(params[2], "cyl=", 4) ||
strncmp(params[3], "heads=", 6) ||
strncmp(params[4], "spt=", 4)) {
BX_PANIC(("%s: diskc directive malformed.", bochsrc_path));
BX_PANIC(("%s: diskc directive malformed.", context));
}
strcpy(bx_options.diskc.path, &params[1][5]);
bx_options.diskc.cylinders = atol( &params[2][4] );
@ -837,13 +863,13 @@ parse_line_formatted(int num_params, char *params[])
}
else if (!strcmp(params[0], "diskd")) {
if (num_params != 5) {
BX_PANIC(("%s: diskd directive malformed.", bochsrc_path));
BX_PANIC(("%s: diskd directive malformed.", context));
}
if (strncmp(params[1], "file=", 5) ||
strncmp(params[2], "cyl=", 4) ||
strncmp(params[3], "heads=", 6) ||
strncmp(params[4], "spt=", 4)) {
BX_PANIC(("%s: diskd directive malformed.", bochsrc_path));
BX_PANIC(("%s: diskd directive malformed.", context));
}
strcpy(bx_options.diskd.path, &params[1][5]);
bx_options.diskd.cylinders = atol( &params[2][4] );
@ -854,10 +880,10 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp(params[0], "cdromd")) {
if (num_params != 3) {
BX_PANIC(("%s: cdromd directive malformed.", bochsrc_path));
BX_PANIC(("%s: cdromd directive malformed.", context));
}
if (strncmp(params[1], "dev=", 4) || strncmp(params[2], "status=", 7)) {
BX_PANIC(("%s: cdromd directive malformed.", bochsrc_path));
BX_PANIC(("%s: cdromd directive malformed.", context));
}
strcpy(bx_options.cdromd.dev, &params[1][4]);
if (!strcmp(params[2], "status=inserted"))
@ -865,7 +891,7 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp(params[2], "status=ejected"))
bx_options.cdromd.inserted = 0;
else {
BX_PANIC(("%s: cdromd directive malformed.", bochsrc_path));
BX_PANIC(("%s: cdromd directive malformed.", context));
}
bx_options.cdromd.present = 1;
}
@ -876,21 +902,21 @@ parse_line_formatted(int num_params, char *params[])
strcpy(bx_options.bootdrive, params[1]);
}
else {
BX_PANIC(("%s: boot directive with unknown boot device '%s'. use 'a' or 'c'.", bochsrc_path, params[1]));
BX_PANIC(("%s: boot directive with unknown boot device '%s'. use 'a' or 'c'.", context, params[1]));
}
}
else if (!strcmp(params[0], "log")) {
if (num_params != 2) {
BX_PANIC(("%s: log directive has wrong # args.", bochsrc_path));
BX_PANIC(("%s: log directive has wrong # args.", context));
}
strcpy(logfilename, params[1]);
strcpy(bx_options.logfilename, params[1]);
}
else if (!strcmp(params[0], "panic")) {
if (num_params != 2) {
BX_PANIC(("%s: panic directive malformed.", bochsrc_path));
BX_PANIC(("%s: panic directive malformed.", context));
}
if (strncmp(params[1], "action=", 7)) {
BX_PANIC(("%s: panic directive malformed.", bochsrc_path));
BX_PANIC(("%s: panic directive malformed.", context));
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
@ -900,15 +926,15 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_PANIC] = ACT_IGNORE;
else {
BX_PANIC(("%s: panic directive malformed.", bochsrc_path));
BX_PANIC(("%s: panic directive malformed.", context));
}
}
else if (!strcmp(params[0], "error")) {
if (num_params != 2) {
BX_PANIC(("%s: error directive malformed.", bochsrc_path));
BX_PANIC(("%s: error directive malformed.", context));
}
if (strncmp(params[1], "action=", 7)) {
BX_PANIC(("%s: error directive malformed.", bochsrc_path));
BX_PANIC(("%s: error directive malformed.", context));
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
@ -918,15 +944,15 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_ERROR] = ACT_IGNORE;
else {
BX_PANIC(("%s: error directive malformed.", bochsrc_path));
BX_PANIC(("%s: error directive malformed.", context));
}
}
else if (!strcmp(params[0], "info")) {
if (num_params != 2) {
BX_PANIC(("%s: info directive malformed.", bochsrc_path));
BX_PANIC(("%s: info directive malformed.", context));
}
if (strncmp(params[1], "action=", 7)) {
BX_PANIC(("%s: info directive malformed.", bochsrc_path));
BX_PANIC(("%s: info directive malformed.", context));
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
@ -936,15 +962,15 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_INFO] = ACT_IGNORE;
else {
BX_PANIC(("%s: info directive malformed.", bochsrc_path));
BX_PANIC(("%s: info directive malformed.", context));
}
}
else if (!strcmp(params[0], "debug")) {
if (num_params != 2) {
BX_PANIC(("%s: debug directive malformed.", bochsrc_path));
BX_PANIC(("%s: debug directive malformed.", context));
}
if (strncmp(params[1], "action=", 7)) {
BX_PANIC(("%s: debug directive malformed.", bochsrc_path));
BX_PANIC(("%s: debug directive malformed.", context));
}
char *action = 7 + params[1];
if (!strcmp(action, "fatal"))
@ -954,18 +980,18 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp (action, "ignore"))
bx_options.log_actions[LOGLEV_DEBUG] = ACT_IGNORE;
else {
BX_PANIC(("%s: debug directive malformed.", bochsrc_path));
BX_PANIC(("%s: debug directive malformed.", context));
}
}
else if (!strcmp(params[0], "romimage")) {
if (num_params != 3) {
BX_PANIC(("%s: romimage directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: romimage directive: wrong # args.", context));
}
if (strncmp(params[1], "file=", 5)) {
BX_PANIC(("%s: romimage directive malformed.", bochsrc_path));
BX_PANIC(("%s: romimage directive malformed.", context));
}
if (strncmp(params[2], "address=", 8)) {
BX_PANIC(("%s: romimage directive malformed.", bochsrc_path));
BX_PANIC(("%s: romimage directive malformed.", context));
}
bx_options.rom.path = strdup(&params[1][5]);
if ( (params[2][8] == '0') && (params[2][9] == 'x') )
@ -975,81 +1001,81 @@ parse_line_formatted(int num_params, char *params[])
}
else if (!strcmp(params[0], "vgaromimage")) {
if (num_params != 2) {
BX_PANIC(("%s: vgaromimage directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: vgaromimage directive: wrong # args.", context));
}
bx_options.vgarom.path = strdup(params[1]);
}
else if (!strcmp(params[0], "vga_update_interval")) {
if (num_params != 2) {
BX_PANIC(("%s: vga_update_interval directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: vga_update_interval directive: wrong # args.", context));
}
bx_options.vga_update_interval = atol(params[1]);
if (bx_options.vga_update_interval < 50000) {
BX_PANIC(("%s: vga_update_interval not big enough!", bochsrc_path));
BX_PANIC(("%s: vga_update_interval not big enough!", context));
}
}
else if (!strcmp(params[0], "keyboard_serial_delay")) {
if (num_params != 2) {
BX_PANIC(("%s: keyboard_serial_delay directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: keyboard_serial_delay directive: wrong # args.", context));
}
bx_options.keyboard_serial_delay = atol(params[1]);
if (bx_options.keyboard_serial_delay < 5) {
BX_PANIC(("%s: keyboard_serial_delay not big enough!", bochsrc_path));
BX_PANIC(("%s: keyboard_serial_delay not big enough!", context));
}
}
else if (!strcmp(params[0], "megs")) {
if (num_params != 2) {
BX_PANIC(("%s: megs directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: megs directive: wrong # args.", context));
}
bx_options.memory.megs = atol(params[1]);
}
else if (!strcmp(params[0], "floppy_command_delay")) {
if (num_params != 2) {
BX_PANIC(("%s: floppy_command_delay directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: floppy_command_delay directive: wrong # args.", context));
}
bx_options.floppy_command_delay = atol(params[1]);
if (bx_options.floppy_command_delay < 100) {
BX_PANIC(("%s: floppy_command_delay not big enough!", bochsrc_path));
BX_PANIC(("%s: floppy_command_delay not big enough!", context));
}
}
else if (!strcmp(params[0], "ips")) {
if (num_params != 2) {
BX_PANIC(("%s: ips directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: ips directive: wrong # args.", context));
}
bx_options.ips = atol(params[1]);
if (bx_options.ips < 200000) {
BX_INFO(("%s: WARNING: ips is AWFULLY low!", bochsrc_path));
BX_INFO(("%s: WARNING: ips is AWFULLY low!", context));
}
}
else if (!strcmp(params[0], "mouse")) {
if (num_params != 2) {
BX_PANIC(("%s: mouse directive malformed.", bochsrc_path));
BX_PANIC(("%s: mouse directive malformed.", context));
}
if (strncmp(params[1], "enabled=", 8)) {
BX_PANIC(("%s: mouse directive malformed.", bochsrc_path));
BX_PANIC(("%s: mouse directive malformed.", context));
}
if (params[1][8] == '0')
bx_options.mouse_enabled = 0;
else if (params[1][8] == '1')
bx_options.mouse_enabled = 1;
else {
BX_PANIC(("%s: mouse directive malformed.", bochsrc_path));
BX_PANIC(("%s: mouse directive malformed.", context));
}
}
else if (!strcmp(params[0], "private_colormap")) {
if (num_params != 2) {
BX_PANIC(("%s: private_colormap directive malformed.", bochsrc_path));
BX_PANIC(("%s: private_colormap directive malformed.", context));
}
if (strncmp(params[1], "enabled=", 8)) {
BX_PANIC(("%s: private_colormap directive malformed.", bochsrc_path));
BX_PANIC(("%s: private_colormap directive malformed.", context));
}
if (params[1][8] == '0')
bx_options.private_colormap = 0;
else if (params[1][8] == '1')
bx_options.private_colormap = 1;
else {
BX_PANIC(("%s: private_colormap directive malformed.", bochsrc_path));
BX_PANIC(("%s: private_colormap directive malformed.", context));
}
}
@ -1081,54 +1107,54 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp(params[0], "i440fxsupport")) {
if (num_params != 2) {
BX_PANIC(("%s: i440FXSupport directive malformed.", bochsrc_path));
BX_PANIC(("%s: i440FXSupport directive malformed.", context));
}
if (strncmp(params[1], "enabled=", 8)) {
BX_PANIC(("%s: i440FXSupport directive malformed.", bochsrc_path));
BX_PANIC(("%s: i440FXSupport directive malformed.", context));
}
if (params[1][8] == '0')
bx_options.i440FXSupport = 0;
else if (params[1][8] == '1')
bx_options.i440FXSupport = 1;
else {
BX_PANIC(("%s: i440FXSupport directive malformed.", bochsrc_path));
BX_PANIC(("%s: i440FXSupport directive malformed.", context));
}
}
else if (!strcmp(params[0], "newharddrivesupport")) {
if (num_params != 2) {
BX_PANIC(("%s: newharddrivesupport directive malformed.", bochsrc_path));
BX_PANIC(("%s: newharddrivesupport directive malformed.", context));
}
if (strncmp(params[1], "enabled=", 8)) {
BX_PANIC(("%s: newharddrivesupport directive malformed.", bochsrc_path));
BX_PANIC(("%s: newharddrivesupport directive malformed.", context));
}
if (params[1][8] == '0')
bx_options.newHardDriveSupport = 0;
else if (params[1][8] == '1')
bx_options.newHardDriveSupport = 1;
else {
BX_PANIC(("%s: newharddrivesupport directive malformed.", bochsrc_path));
BX_PANIC(("%s: newharddrivesupport directive malformed.", context));
}
}
else if (!strcmp(params[0], "cmosimage")) {
if (num_params != 2) {
BX_PANIC(("%s: cmosimage directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: cmosimage directive: wrong # args.", context));
}
bx_options.cmos.path = strdup(params[1]);
bx_options.cmos.cmosImage = 1; // CMOS Image is true
}
else if (!strcmp(params[0], "time0")) {
if (num_params != 2) {
BX_PANIC(("%s: time0 directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: time0 directive: wrong # args.", context));
}
bx_options.cmos.time0 = atoi(params[1]);
}
#ifdef MAGIC_BREAKPOINT
else if (!strcmp(params[0], "magic_break")) {
if (num_params != 2) {
BX_PANIC(("%s: magic_break directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: magic_break directive: wrong # args.", context));
}
if (strncmp(params[1], "enabled=", 8)) {
BX_PANIC(("%s: magic_break directive malformed.", bochsrc_path));
BX_PANIC(("%s: magic_break directive malformed.", context));
}
if (params[1][8] == '0') {
BX_INFO(("Ignoring magic break points"));
@ -1139,7 +1165,7 @@ parse_line_formatted(int num_params, char *params[])
bx_dbg.magic_break_enabled = 1;
}
else {
BX_PANIC(("%s: magic_break directive malformed.", bochsrc_path));
BX_PANIC(("%s: magic_break directive malformed.", context));
}
}
#endif
@ -1147,35 +1173,35 @@ parse_line_formatted(int num_params, char *params[])
int tmp[6];
bx_options.ne2k.valid = 0;
if ((num_params < 4) || (num_params > 6)) {
BX_PANIC(("%s: ne2k directive malformed.", bochsrc_path));
BX_PANIC(("%s: ne2k directive malformed.", context));
}
bx_options.ne2k.ethmod = "null";
if (strncmp(params[1], "ioaddr=", 7)) {
BX_PANIC(("%s: ne2k directive malformed.", bochsrc_path));
BX_PANIC(("%s: ne2k directive malformed.", context));
}
if (strncmp(params[2], "irq=", 4)) {
BX_PANIC(("%s: ne2k directive malformed.", bochsrc_path));
BX_PANIC(("%s: ne2k directive malformed.", context));
}
if (strncmp(params[3], "mac=", 4)) {
BX_PANIC(("%s: ne2k directive malformed.", bochsrc_path));
BX_PANIC(("%s: ne2k directive malformed.", context));
}
bx_options.ne2k.ioaddr = strtoul(&params[1][7], NULL, 16);
bx_options.ne2k.irq = atol(&params[2][4]);
i = sscanf(&params[3][4], "%x:%x:%x:%x:%x:%x",
&tmp[0],&tmp[1],&tmp[2],&tmp[3],&tmp[4],&tmp[5]);
if (i != 6) {
BX_PANIC(("%s: ne2k mac address malformed.", bochsrc_path));
BX_PANIC(("%s: ne2k mac address malformed.", context));
}
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.", bochsrc_path));
BX_PANIC(("%s: ne2k directive malformed.", context));
}
bx_options.ne2k.ethmod = strdup(&params[4][7]);
if (num_params == 6) {
if (strncmp(params[5], "ethdev=", 7)) {
BX_PANIC(("%s: ne2k directive malformed.", bochsrc_path));
BX_PANIC(("%s: ne2k directive malformed.", context));
}
bx_options.ne2k.ethdev = strdup(&params[5][7]);
}
@ -1185,10 +1211,10 @@ parse_line_formatted(int num_params, char *params[])
else if (!strcmp(params[0], "load32bitOSImage")) {
if ( (num_params!=4) && (num_params!=5) ) {
BX_PANIC(("%s: load32bitOSImage directive: wrong # args.", bochsrc_path));
BX_PANIC(("%s: load32bitOSImage directive: wrong # args.", context));
}
if (strncmp(params[1], "os=", 3)) {
BX_PANIC(("%s: load32bitOSImage: directive malformed.", bochsrc_path));
BX_PANIC(("%s: load32bitOSImage: directive malformed.", context));
}
if (!strcmp(&params[1][3], "nullkernel")) {
bx_options.load32bitOSImage.whichOS = Load32bitOSNullKernel;
@ -1197,26 +1223,26 @@ parse_line_formatted(int num_params, char *params[])
bx_options.load32bitOSImage.whichOS = Load32bitOSLinux;
}
else {
BX_PANIC(("%s: load32bitOSImage: unsupported OS.", bochsrc_path));
BX_PANIC(("%s: load32bitOSImage: unsupported OS.", context));
}
if (strncmp(params[2], "path=", 5)) {
BX_PANIC(("%s: load32bitOSImage: directive malformed.", bochsrc_path));
BX_PANIC(("%s: load32bitOSImage: directive malformed.", context));
}
if (strncmp(params[3], "iolog=", 6)) {
BX_PANIC(("%s: load32bitOSImage: directive malformed.", bochsrc_path));
BX_PANIC(("%s: load32bitOSImage: directive malformed.", context));
}
bx_options.load32bitOSImage.path = strdup(&params[2][5]);
bx_options.load32bitOSImage.iolog = strdup(&params[3][6]);
if (num_params == 5) {
if (strncmp(params[4], "initrd=", 7)) {
BX_PANIC(("%s: load32bitOSImage: directive malformed.", bochsrc_path));
BX_PANIC(("%s: load32bitOSImage: directive malformed.", context));
}
bx_options.load32bitOSImage.initrd = strdup(&params[4][7]);
}
}
else {
BX_PANIC(( "%s: directive '%s' not understood", bochsrc_path, params[0]));
BX_PANIC(( "%s: directive '%s' not understood", context, params[0]));
}
if (bx_options.diskd.present && bx_options.cdromd.present)