1 /////////////////////////////////////////////////////////////////////////
2 // $Id: config.cc,v 1.119 2007/04/08 15:02:50 vruppert Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2002 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "iodev/iodev.h"
35 #if defined(macintosh)
36 // Work around a bug in SDL 1.2.4 on MacOS X, which redefines getenv to
37 // SDL_getenv, but then neglects to provide SDL_getenv. It happens
38 // because we are defining -Dmacintosh.
43 int bochsrc_include_count
= 0;
45 #define LOG_THIS genlog->
47 extern bx_debug_t bx_dbg
;
49 static char *get_builtin_variable(char *varname
);
50 static Bit32s
parse_line_unformatted(const char *context
, char *line
);
51 static Bit32s
parse_line_formatted(const char *context
, int num_params
, char *params
[]);
52 static int parse_bochsrc(const char *rcfile
);
53 static int get_floppy_type_from_image(const char *filename
);
55 static Bit64s
bx_param_handler(bx_param_c
*param
, int set
, Bit64s val
)
57 char pname
[BX_PATHNAME_LEN
];
58 Bit8u channel
, device
;
60 bx_list_c
*base
= (bx_list_c
*) param
->get_parent();
61 base
->get_param_path(pname
, BX_PATHNAME_LEN
);
62 if (!strncmp(pname
, "ata.", 4)) {
63 channel
= pname
[4] - '0';
64 if (!strcmp(base
->get_name(), "master")) {
69 if (!strcmp(param
->get_name(), "status")) {
70 if ((set
) && (SIM
->get_init_done())) {
71 Bit32u handle
= DEV_hd_get_device_handle(channel
, device
);
72 DEV_hd_set_cd_media_status(handle
, val
== BX_INSERTED
);
73 bx_gui
->update_drive_status_buttons();
75 } else if (!strcmp(param
->get_name(), "mode")) {
78 case BX_ATA_MODE_UNDOABLE
:
79 case BX_ATA_MODE_VOLATILE
:
80 // case BX_ATA_MODE_Z_UNDOABLE:
81 // case BX_ATA_MODE_Z_VOLATILE:
82 SIM
->get_param("journal", base
)->set_enabled(1);
85 SIM
->get_param("journal", base
)->set_enabled(0);
88 } else if (!strcmp(param
->get_name(), "type")) {
91 case BX_ATA_DEVICE_DISK
:
92 SIM
->get_param_num("present", base
)->set(1);
93 SIM
->get_param("mode", base
)->set_enabled(1);
94 SIM
->get_param("path", base
)->set_enabled(1);
95 //SIM->get_param("journal", base)->set_enabled(1);
96 SIM
->get_param("cylinders", base
)->set_enabled(1);
97 SIM
->get_param("heads", base
)->set_enabled(1);
98 SIM
->get_param("spt", base
)->set_enabled(1);
99 SIM
->get_param("status", base
)->set_enabled(0);
100 SIM
->get_param("model", base
)->set_enabled(1);
101 SIM
->get_param("biosdetect", base
)->set_enabled(1);
102 SIM
->get_param("translation", base
)->set_enabled(1);
103 SIM
->get_param("path", base
)->set_runtime_param(0);
104 SIM
->get_param("status", base
)->set_runtime_param(0);
106 case BX_ATA_DEVICE_CDROM
:
107 SIM
->get_param_num("present", base
)->set(1);
108 SIM
->get_param("mode", base
)->set_enabled(0);
109 SIM
->get_param("path", base
)->set_enabled(1);
110 SIM
->get_param("journal", base
)->set_enabled(0);
111 SIM
->get_param("cylinders", base
)->set_enabled(0);
112 SIM
->get_param("heads", base
)->set_enabled(0);
113 SIM
->get_param("spt", base
)->set_enabled(0);
114 SIM
->get_param("status", base
)->set_enabled(1);
115 SIM
->get_param("model", base
)->set_enabled(1);
116 SIM
->get_param("biosdetect", base
)->set_enabled(1);
117 SIM
->get_param("translation", base
)->set_enabled(0);
118 SIM
->get_param("path", base
)->set_runtime_param(1);
119 SIM
->get_param("status", base
)->set_runtime_param(1);
125 param
->get_param_path(pname
, BX_PATHNAME_LEN
);
126 if (!strcmp(pname
, BXPN_LOAD32BITOS_WHICH
)) {
128 int enable
= (val
!= Load32bitOSNone
);
129 SIM
->get_param(BXPN_LOAD32BITOS_PATH
)->set_enabled(enable
);
130 SIM
->get_param(BXPN_LOAD32BITOS_IOLOG
)->set_enabled(enable
);
131 SIM
->get_param(BXPN_LOAD32BITOS_INITRD
)->set_enabled(enable
);
133 } else if (!strcmp(pname
, BXPN_FLOPPYA_TYPE
)) {
135 if (val
== BX_FLOPPY_AUTO
) {
136 val
= get_floppy_type_from_image(SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->getptr());
137 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(val
);
138 } else if (!SIM
->get_init_done()) {
139 SIM
->get_param_enum(BXPN_FLOPPYA_DEVTYPE
)->set(val
);
142 } else if (!strcmp(pname
, BXPN_FLOPPYB_TYPE
)) {
144 if (val
== BX_FLOPPY_AUTO
) {
145 val
= get_floppy_type_from_image(SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->getptr());
146 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(val
);
147 } else if (!SIM
->get_init_done()) {
148 SIM
->get_param_enum(BXPN_FLOPPYB_DEVTYPE
)->set(val
);
151 } else if (!strcmp(pname
, BXPN_FLOPPYA_STATUS
)) {
152 if ((set
) && (SIM
->get_init_done())) {
153 DEV_floppy_set_media_status(0, val
== BX_INSERTED
);
154 bx_gui
->update_drive_status_buttons();
156 } else if (!strcmp(pname
, BXPN_FLOPPYB_STATUS
)) {
157 if ((set
) && (SIM
->get_init_done())) {
158 DEV_floppy_set_media_status(1, val
== BX_INSERTED
);
159 bx_gui
->update_drive_status_buttons();
162 BX_PANIC(("bx_param_handler called with unknown parameter '%s'", pname
));
169 const char *bx_param_string_handler(bx_param_string_c
*param
, int set
, const char *val
, int maxlen
)
171 char pname
[BX_PATHNAME_LEN
];
172 Bit8u channel
, device
;
175 if ((strlen(val
) < 1) || !strcmp ("none", val
)) {
179 bx_list_c
*base
= (bx_list_c
*) param
->get_parent();
180 base
->get_param_path(pname
, BX_PATHNAME_LEN
);
181 if (!strncmp(pname
, "ata.", 4)) {
182 channel
= pname
[4] - '0';
183 if (!strcmp(base
->get_name(), "master")) {
188 if (!strcmp(param
->get_name(), "path")) {
190 if (SIM
->get_init_done()) {
191 Bit32u handle
= DEV_hd_get_device_handle(channel
, device
);
193 DEV_hd_set_cd_media_status(handle
, 0);
194 bx_gui
->update_drive_status_buttons();
196 if (!SIM
->get_param_num("present", base
)->get()) {
197 BX_ERROR(("Cannot add a cdrom drive at runtime"));
198 SIM
->get_param_num("present", base
)->set(0);
200 if (SIM
->get_param_num("type", base
)->get() != BX_ATA_DEVICE_CDROM
) {
201 BX_ERROR(("Device is not a cdrom drive"));
202 SIM
->get_param_num("present", base
)->set(0);
205 if (DEV_hd_present() &&
206 (SIM
->get_param_num("status", base
)->get() == BX_INSERTED
) &&
207 (SIM
->get_param_num("type", base
)->get() == BX_ATA_DEVICE_CDROM
)) {
208 // tell the device model that we removed, then inserted the cd
209 DEV_hd_set_cd_media_status(handle
, 0);
210 DEV_hd_set_cd_media_status(handle
, 1);
216 param
->get_param_path(pname
, BX_PATHNAME_LEN
);
217 if (!strcmp(pname
, BXPN_SCREENMODE
)) {
219 BX_INFO(("Screen mode changed to %s", val
));
221 } else if (!strcmp(pname
, BXPN_FLOPPYA_PATH
)) {
223 if (SIM
->get_init_done()) {
225 DEV_floppy_set_media_status(0, 0);
226 bx_gui
->update_drive_status_buttons();
228 if (!SIM
->get_param_num(BXPN_FLOPPYA_TYPE
)->get_enabled()) {
229 BX_ERROR(("Cannot add a floppy drive at runtime"));
230 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set("none");
233 if ((DEV_floppy_present()) &&
234 (SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->get() == BX_INSERTED
)) {
235 // tell the device model that we removed, then inserted the disk
236 DEV_floppy_set_media_status(0, 0);
237 DEV_floppy_set_media_status(0, 1);
240 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set_enabled(!empty
);
241 SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->set_enabled(!empty
);
244 } else if (!strcmp(pname
, BXPN_FLOPPYB_PATH
)) {
246 if (SIM
->get_init_done()) {
248 DEV_floppy_set_media_status(1, 0);
249 bx_gui
->update_drive_status_buttons();
251 if (!SIM
->get_param_num(BXPN_FLOPPYB_TYPE
)->get_enabled()) {
252 BX_ERROR(("Cannot add a floppy drive at runtime"));
253 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set("none");
256 if ((DEV_floppy_present()) &&
257 (SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->get() == BX_INSERTED
)) {
258 // tell the device model that we removed, then inserted the disk
259 DEV_floppy_set_media_status(1, 0);
260 DEV_floppy_set_media_status(1, 1);
263 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set_enabled(!empty
);
264 SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->set_enabled(!empty
);
268 BX_PANIC(("bx_param_string_handler called with unknown parameter '%s'", pname
));
274 static int bx_param_enable_handler (bx_param_c
*param
, int val
)
276 char pname
[BX_PATHNAME_LEN
];
277 Bit8u channel
, device
;
279 bx_list_c
*base
= (bx_list_c
*) param
->get_parent();
280 base
->get_param_path(pname
, BX_PATHNAME_LEN
);
281 if (!strncmp(pname
, "ata.", 4)) {
282 channel
= pname
[4] - '0';
283 if (!strcmp(base
->get_name(), "master")) {
288 if (!strcmp(param
->get_name(), "status")) {
290 switch (SIM
->get_param_enum("type", base
)->get()) {
291 case BX_ATA_DEVICE_CDROM
:
296 } else if (!strcmp(param
->get_name(), "journal")) {
298 switch (SIM
->get_param_enum("type", base
)->get()) {
299 case BX_ATA_DEVICE_DISK
:
300 switch (SIM
->get_param_enum("mode", base
)->get()) {
301 case BX_ATA_MODE_UNDOABLE
:
302 case BX_ATA_MODE_VOLATILE
:
303 // case BX_ATA_MODE_Z_UNDOABLE:
304 // case BX_ATA_MODE_Z_VOLATILE:
312 BX_PANIC(("bx_param_enable_handler called with unknown parameter '%s'", pname
));
315 BX_PANIC(("bx_param_enable_handler called with unknown parameter '%s'", pname
));
320 void bx_init_options()
325 bx_param_num_c
*ioaddr
, *ioaddr2
, *irq
;
326 bx_param_bool_c
*enabled
;
327 bx_param_enum_c
*mode
, *status
, *type
, *ethmod
;
328 bx_param_string_c
*macaddr
, *ethdev
;
329 bx_param_filename_c
*path
;
330 char name
[BX_PATHNAME_LEN
], descr
[512], group
[16], label
[512];
332 bx_param_c
*root_param
= SIM
->get_param(".");
334 // general options subtree
335 menu
= new bx_list_c(root_param
, "general", "");
337 // config interface option, set in bochsrc or command line
338 static char *config_interface_list
[] = {
339 #if BX_USE_TEXTCONFIG
347 bx_param_enum_c
*sel_config
= new bx_param_enum_c(menu
,
348 "config_interface", "Configuration interface",
349 "Select configuration interface",
350 config_interface_list
,
353 sel_config
->set_by_name(BX_DEFAULT_CONFIG_INTERFACE
);
355 // quick start option, set by command line arg
356 new bx_param_enum_c(menu
,
364 #if BX_SUPPORT_SAVE_RESTORE
365 new bx_param_bool_c(menu
,
367 "Restore Bochs session",
368 "Restore Bochs session",
370 new bx_param_string_c(menu
,
372 "Path to data for restore",
373 "Path to data for restore",
378 // subtree for special menus
379 bx_list_c
*special_menus
= new bx_list_c(root_param
, "menu", "");
382 #define BX_CPU_PROCESSORS_LIMIT 8
383 #define BX_CPU_CORES_LIMIT 4
384 #define BX_CPU_HT_THREADS_LIMIT 4
386 #define BX_CPU_PROCESSORS_LIMIT 1
387 #define BX_CPU_CORES_LIMIT 1
388 #define BX_CPU_HT_THREADS_LIMIT 1
392 bx_list_c
*cpu_param
= new bx_list_c(root_param
, "cpu", "CPU Options");
395 bx_param_num_c
*nprocessors
= new bx_param_num_c(cpu_param
,
396 "n_processors", "Number of CPUs in SMP mode",
397 "Sets the number of CPUs for multiprocessor emulation",
398 1, BX_CPU_PROCESSORS_LIMIT
,
400 nprocessors
->set_enabled(BX_CPU_PROCESSORS_LIMIT
> 1);
401 bx_param_num_c
*ncores
= new bx_param_num_c(cpu_param
,
402 "n_cores", "Number of processor cores in each CPU in SMP mode",
403 "Sets the number of processor cores per CPU for multiprocessor emulation",
404 1, BX_CPU_CORES_LIMIT
,
406 ncores
->set_enabled(BX_CPU_CORES_LIMIT
> 1);
407 bx_param_num_c
*nthreads
= new bx_param_num_c(cpu_param
,
408 "n_threads", "Number of HT threads per each process core in SMP mode",
409 "Sets the number of HT (Intel(R) HyperThreading Technology) threads per core for multiprocessor emulation",
410 1, BX_CPU_HT_THREADS_LIMIT
,
412 nthreads
->set_enabled(BX_CPU_HT_THREADS_LIMIT
> 1);
413 new bx_param_num_c(cpu_param
,
414 "ips", "Emulated instructions per second (IPS)",
415 "Emulated instructions per second, used to calibrate bochs emulated time with wall clock time.",
419 new bx_param_num_c(cpu_param
,
420 "quantum", "Quantum ticks in SMP simulation",
421 "Maximum amount of instructions allowed to execute before returning control to another CPU.",
422 BX_SMP_QUANTUM_MIN
, BX_SMP_QUANTUM_MAX
,
425 new bx_param_bool_c(cpu_param
,
426 "reset_on_triple_fault", "Enable CPU reset on triple fault",
427 "Enable CPU reset if triple fault occured (highly recommended)",
429 cpu_param
->get_options()->set(menu
->SHOW_PARENT
);
432 bx_list_c
*memory
= new bx_list_c(root_param
, "memory", "Memory Options");
433 bx_list_c
*stdmem
= new bx_list_c(memory
, "standard", "Standard Options");
434 bx_list_c
*optrom
= new bx_list_c(memory
, "optrom", "Optional ROM Images");
435 bx_list_c
*optram
= new bx_list_c(memory
, "optram", "Optional RAM Images");
436 bx_list_c
*ram
= new bx_list_c(stdmem
, "ram", "");
437 bx_list_c
*rom
= new bx_list_c(stdmem
, "rom", "");
438 bx_list_c
*vgarom
= new bx_list_c(stdmem
, "vgarom", "");
440 // memory options (ram & rom)
441 bx_param_num_c
*ramsize
= new bx_param_num_c(ram
,
443 "Memory size (megabytes)",
444 "Amount of RAM in megabytes",
446 BX_DEFAULT_MEM_MEGS
);
447 ramsize
->set_ask_format("Enter memory size (MB): [%d] ");
449 ramsize
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
452 path
= new bx_param_filename_c(rom
,
455 "Pathname of ROM image to load",
456 "", BX_PATHNAME_LEN
);
457 path
->set_format("Name of ROM BIOS image: %s");
458 sprintf(name
, "%s/BIOS-bochs-latest", get_builtin_variable("BXSHARE"));
459 path
->set_initial_val(name
);
460 bx_param_num_c
*romaddr
= new bx_param_num_c(rom
,
463 "The address at which the ROM image should be loaded",
466 romaddr
->set_base(16);
467 romaddr
->set_format("0x%05x");
468 romaddr
->set_long_format("ROM BIOS address: 0x%05x");
470 path
= new bx_param_filename_c(vgarom
,
473 "Pathname of VGA ROM image to load",
474 "", BX_PATHNAME_LEN
);
475 path
->set_format("Name of VGA BIOS image: %s");
476 sprintf(name
, "%s/VGABIOS-lgpl-latest", get_builtin_variable("BXSHARE"));
477 path
->set_initial_val(name
);
479 bx_param_num_c
*optaddr
;
481 for (i
=0; i
<BX_N_OPTROM_IMAGES
; i
++) {
482 sprintf(name
, "%d", i
+1);
483 sprintf(descr
, "Pathname of optional ROM image #%d to load", i
+1);
484 sprintf(label
, "Optional ROM image #%d", i
+1);
485 bx_list_c
*optnum1
= new bx_list_c(optrom
, name
, label
);
486 path
= new bx_param_filename_c(optnum1
,
490 "", BX_PATHNAME_LEN
);
491 sprintf(label
, "Name of optional ROM image #%d", i
+1);
492 strcat(label
, " : %s");
493 path
->set_format(strdup(label
));
494 sprintf(descr
, "The address at which the optional ROM image #%d should be loaded", i
+1);
495 optaddr
= new bx_param_num_c(optnum1
,
501 optaddr
->set_base(16);
502 optaddr
->set_format("0x%05x");
503 sprintf(label
, "Optional ROM #%d address:", i
+1);
504 strcat(label
, " 0x%05x");
505 optaddr
->set_long_format(strdup(label
));
506 optnum1
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
508 optrom
->get_options()->set(bx_list_c::SHOW_PARENT
);
510 for (i
=0; i
<BX_N_OPTRAM_IMAGES
; i
++) {
511 sprintf(name
, "%d", i
+1);
512 sprintf(descr
, "Pathname of optional RAM image #%d to load", i
+1);
513 sprintf(label
, "Optional RAM image #%d", i
+1);
514 bx_list_c
*optnum2
= new bx_list_c(optram
, name
, label
);
515 path
= new bx_param_filename_c(optnum2
,
519 "", BX_PATHNAME_LEN
);
520 sprintf(label
, "Name of optional RAM image #%d", i
+1);
521 strcat(label
, " : %s");
522 path
->set_format(strdup(label
));
523 sprintf(descr
, "The address at which the optional RAM image #%d should be loaded", i
+1);
524 optaddr
= new bx_param_num_c(optnum2
,
530 optaddr
->set_base(16);
531 optaddr
->set_format("0x%05x");
532 sprintf(label
, "Optional RAM #%d address:", i
+1);
533 strcat(label
, " 0x%05x");
534 optaddr
->set_long_format(strdup(label
));
535 optnum2
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
537 optrom
->get_options()->set(bx_list_c::SHOW_PARENT
);
538 memory
->get_options()->set(bx_list_c::USE_TAB_WINDOW
);
540 bx_param_c
*memory_init_list
[] = {
541 SIM
->get_param(BXPN_MEM_SIZE
),
542 SIM
->get_param(BXPN_ROM_PATH
),
543 SIM
->get_param(BXPN_ROM_ADDRESS
),
544 SIM
->get_param(BXPN_VGA_ROM_PATH
),
545 SIM
->get_param("memory.optrom"),
546 SIM
->get_param("memory.optram"),
549 menu
= new bx_list_c(special_menus
, "memory", "Bochs Memory Options", memory_init_list
);
550 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
552 // clock & cmos subtree
553 bx_list_c
*clock_cmos
= new bx_list_c(root_param
, "clock_cmos", "Clock & CMOS Options");
555 // clock & cmos options
556 bx_param_enum_c
*clock_sync
= new bx_param_enum_c(clock_cmos
,
557 "clock_sync", "Synchronisation method",
558 "Host to guest time synchronization method",
562 bx_param_num_c
*time0
= new bx_param_num_c(clock_cmos
,
564 "Initial CMOS time for Bochs\n(1:localtime, 2:utc, other:time in seconds)",
565 "Initial time for Bochs CMOS clock, used if you really want two runs to be identical",
567 BX_CLOCK_TIME0_LOCAL
);
569 bx_list_c
*cmosimage
= new bx_list_c(clock_cmos
, "cmosimage", "CMOS Image Options");
570 bx_param_bool_c
*use_cmosimage
= new bx_param_bool_c(cmosimage
,
571 "enabled", "Use a CMOS image",
572 "Controls the usage of a CMOS image",
574 path
= new bx_param_filename_c(cmosimage
,
575 "path", "Pathname of CMOS image",
576 "Pathname of CMOS image",
577 "", BX_PATHNAME_LEN
);
578 bx_param_bool_c
*rtc_init
= new bx_param_bool_c(cmosimage
,
579 "rtc_init", "Initialize RTC from image",
580 "Controls whether to initialize the RTC with values stored in the image",
582 deplist
= new bx_list_c(NULL
, 2);
584 deplist
->add(rtc_init
);
585 use_cmosimage
->set_dependent_list(deplist
);
587 time0
->set_ask_format("Enter Initial CMOS time (1:localtime, 2:utc, other:time in seconds): [%d] ");
588 clock_sync
->set_ask_format("Enter Synchronisation method: [%s] ");
589 clock_cmos
->get_options()->set(bx_list_c::SHOW_PARENT
);
590 cmosimage
->get_options()->set(bx_list_c::SHOW_PARENT
);
593 bx_list_c
*pci
= new bx_list_c(root_param
, "pci", "PCI Options");
596 bx_param_c
*pci_deps_list
[1+BX_N_PCI_SLOTS
];
597 bx_param_c
**pci_deps_ptr
= &pci_deps_list
[0];
599 bx_param_bool_c
*i440fx_support
= new bx_param_bool_c(pci
,
601 "Enable i440FX PCI Support",
602 "Controls whether to emulate the i440FX PCI chipset",
605 bx_list_c
*slot
= new bx_list_c(pci
, "slot", "PCI Slots");
606 *pci_deps_ptr
++ = slot
;
607 for (i
=0; i
<BX_N_PCI_SLOTS
; i
++) {
608 sprintf(name
, "%d", i
+1);
609 sprintf (descr
, "Name of the device connected to PCI slot #%d", i
+1);
610 sprintf (label
, "PCI slot #%d device", i
+1);
611 bx_param_string_c
*devname
= new bx_param_string_c(slot
,
615 "", BX_PATHNAME_LEN
);
617 *pci_deps_ptr
++ = devname
;
620 bx_list_c
*pcidev
= new bx_list_c(pci
, "pcidev", "Host PCI Device Mapping");
621 *pci_deps_ptr
++ = pcidev
;
622 bx_param_num_c
*pcivid
= new bx_param_num_c(pcidev
,
625 "The vendor ID of the host PCI device to map",
627 0xffff); // vendor id 0xffff = no pci device present
628 pcivid
->set_base(16);
629 pcivid
->set_format("0x%04x");
630 pcivid
->set_long_format("PCI Vendor ID: 0x%04x");
631 #if BX_SUPPORT_PCIDEV
632 *pci_deps_ptr
++ = pcivid
;
634 pcivid
->set_enabled(0);
636 bx_param_num_c
*pcidid
= new bx_param_num_c(pcidev
,
639 "The device ID of the host PCI device to map",
642 pcidid
->set_base(16);
643 pcidid
->set_format("0x%04x");
644 pcidid
->set_long_format("PCI Device ID: 0x%04x");
645 #if BX_SUPPORT_PCIDEV
646 *pci_deps_ptr
++ = pcidid
;
648 pcidid
->set_enabled(0);
650 // add final NULL at the end, and build the menu
651 *pci_deps_ptr
= NULL
;
652 i440fx_support
->set_dependent_list(new bx_list_c(NULL
, "", "", pci_deps_list
));
653 pci
->get_options()->set(bx_list_c::SHOW_PARENT
);
654 slot
->get_options()->set(bx_list_c::SHOW_PARENT
);
655 pcidev
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
658 bx_list_c
*display
= new bx_list_c(root_param
, "display", "Bochs Display & Interface Options", 7);
660 // this is a list of gui libraries that are known to be available at
661 // compile time. The one that is listed first will be the default,
662 // which is used unless the user overrides it on the command line or
663 // in a configuration file.
664 static char *display_library_list
[] = {
703 bx_param_enum_c
*sel_displaylib
= new bx_param_enum_c(display
,
704 "display_library", "VGA Display Library",
705 "Select VGA Display Library",
706 display_library_list
,
709 sel_displaylib
->set_by_name(BX_DEFAULT_DISPLAY_LIBRARY
);
710 sel_displaylib
->set_ask_format("Choose which library to use for the Bochs display: [%s] ");
712 new bx_param_string_c(display
,
713 "displaylib_options", "Display Library options",
714 "Options passed to Display Library",
718 new bx_param_bool_c(display
,
719 "private_colormap", "Use a private colormap",
720 "Request that the GUI create and use it's own non-shared colormap. This colormap will be used when in the bochs window. If not enabled, a shared colormap scheme may be used. Not implemented on all GUI's.",
723 bx_param_bool_c
*fullscreen
= new bx_param_bool_c(display
,
724 "fullscreen", "Use full screen mode",
725 "When enabled, bochs occupies the whole screen instead of just a window.",
727 bx_param_string_c
*screenmode
= new bx_param_string_c(display
,
731 "", BX_PATHNAME_LEN
);
732 screenmode
->set_handler(bx_param_string_handler
);
734 fullscreen
->set_enabled(0);
735 screenmode
->set_enabled(0);
738 bx_param_num_c
*vga_update_interval
= new bx_param_num_c(display
,
739 "vga_update_interval",
740 "VGA Update Interval",
741 "Number of microseconds between VGA updates",
744 vga_update_interval
->set_ask_format ("Type a new value for VGA update interval: [%d] ");
746 bx_param_string_c
*vga_extension
= new bx_param_string_c(display
,
749 "Name of the VGA extension",
750 "none", BX_PATHNAME_LEN
);
752 vga_extension
->set_initial_val("vbe");
753 #elif BX_SUPPORT_CLGD54XX
754 vga_extension
->set_initial_val("cirrus");
756 display
->get_options()->set(bx_list_c::SHOW_PARENT
);
758 // keyboard & mouse subtree
759 bx_list_c
*kbd_mouse
= new bx_list_c(root_param
, "keyboard_mouse", "Keyboard & Mouse Options");
760 bx_list_c
*keyboard
= new bx_list_c(kbd_mouse
, "keyboard", "Keyboard Options");
761 bx_list_c
*mouse
= new bx_list_c(kbd_mouse
, "mouse", "Mouse Options");
763 // keyboard & mouse options
764 type
= new bx_param_enum_c(keyboard
,
765 "type", "Keyboard type",
766 "Keyboard type reported by the 'identify keyboard' command",
770 type
->set_ask_format ("Enter keyboard type: [%s] ");
772 new bx_param_num_c(keyboard
,
773 "serial_delay", "Keyboard serial delay",
774 "Approximate time in microseconds that it takes one character to be transfered from the keyboard to controller over the serial path.",
777 new bx_param_num_c(keyboard
,
778 "paste_delay", "Keyboard paste delay",
779 "Approximate time in microseconds between attemps to paste characters to the keyboard controller.",
782 bx_param_bool_c
*use_kbd_mapping
= new bx_param_bool_c(keyboard
,
783 "use_mapping", "Use keyboard mapping",
784 "Controls whether to use the keyboard mapping feature",
786 bx_param_filename_c
*keymap
= new bx_param_filename_c(keyboard
,
787 "keymap", "Keymap filename",
788 "Pathname of the keymap file used",
789 "", BX_PATHNAME_LEN
);
790 deplist
= new bx_list_c(NULL
, 1);
791 deplist
->add(keymap
);
792 use_kbd_mapping
->set_dependent_list(deplist
);
794 bx_param_string_c
*user_shortcut
= new bx_param_string_c(keyboard
,
796 "Userbutton shortcut",
797 "Defines the keyboard shortcut to be sent when you press the 'user' button in the headerbar.",
799 user_shortcut
->set_runtime_param(1);
801 static char *mouse_type_list
[] = {
805 #if BX_SUPPORT_BUSMOUSE
813 type
= new bx_param_enum_c(mouse
,
814 "type", "Mouse type",
815 "The mouse type can be one of these: 'none', 'ps2', 'imps2', 'serial', 'serial_wheel'"
816 #if BX_SUPPORT_BUSMOUSE
823 type
->set_ask_format("Choose the type of mouse [%s] ");
825 new bx_param_bool_c(mouse
,
826 "enabled", "Enable the mouse capture",
827 "Controls whether the mouse sends events to the guest. The hardware emulation is always enabled.",
829 kbd_mouse
->get_options()->set(bx_list_c::SHOW_PARENT
);
830 keyboard
->get_options()->set(bx_list_c::SHOW_PARENT
);
831 mouse
->get_options()->set(bx_list_c::SHOW_PARENT
);
833 // boot parameter subtree
834 bx_list_c
*boot_params
= new bx_list_c(root_param
, "boot_params", "Boot Options");
836 for (i
=0; i
<3; i
++) {
837 sprintf(name
, "boot_drive%d", i
+1);
838 sprintf(label
, "Boot drive #%d", i
+1);
839 sprintf(descr
, "Name of drive #%d in boot sequence (A, C or CD)", i
+1);
840 bx_param_enum_c
*bootdrive
= new bx_param_enum_c(boot_params
,
844 &bochs_bootdisk_names
[(i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
],
845 (i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
,
846 (i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
);
847 bootdrive
->set_ask_format("Boot from floppy drive, hard drive or cdrom ? [%s] ");
850 new bx_param_bool_c(boot_params
,
852 "Skip Floppy Boot Signature Check",
853 "Skips check for the 0xaa55 signature on floppy boot device.",
857 bx_list_c
*load32bitos
= new bx_list_c(boot_params
, "load32bitos", "32-bit OS Loader Hack");
858 bx_param_enum_c
*whichOS
= new bx_param_enum_c(load32bitos
,
860 "Which operating system?",
865 path
= new bx_param_filename_c(load32bitos
,
867 "Pathname of OS to load",
868 "Pathname of the 32-bit OS to load",
869 "", BX_PATHNAME_LEN
);
870 bx_param_filename_c
*iolog
= new bx_param_filename_c(load32bitos
,
872 "Pathname of I/O log file",
873 "I/O logfile used for initializing the hardware",
874 "", BX_PATHNAME_LEN
);
875 bx_param_filename_c
*initrd
= new bx_param_filename_c(load32bitos
,
877 "Pathname of initrd",
878 "Pathname of the initial ramdisk",
879 "", BX_PATHNAME_LEN
);
880 whichOS
->set_ask_format("Enter OS to load: [%s] ");
881 path
->set_ask_format("Enter pathname of OS: [%s]");
882 iolog
->set_ask_format("Enter pathname of I/O log: [%s] ");
883 initrd
->set_ask_format("Enter pathname of initrd: [%s] ");
884 load32bitos
->get_options()->set(menu
->SERIES_ASK
);
885 whichOS
->set_handler(bx_param_handler
);
886 whichOS
->set(Load32bitOSNone
);
887 boot_params
->get_options()->set(bx_list_c::SHOW_PARENT
);
890 bx_list_c
*floppy
= new bx_list_c(root_param
, "floppy", "Floppy Options");
891 bx_list_c
*floppya
= new bx_list_c(floppy
, "0", "Floppy Disk 0");
892 bx_list_c
*floppyb
= new bx_list_c(floppy
, "1", "Floppy Disk 1");
894 bx_param_enum_c
*devtype
;
896 path
= new bx_param_filename_c(floppya
,
898 "First floppy image/device",
899 "Pathname of first floppy image file or device. If you're booting from floppy, this should be a bootable floppy.",
900 "", BX_PATHNAME_LEN
);
901 path
->set_ask_format("Enter new filename, or 'none' for no disk: [%s] ");
902 path
->set_runtime_param(1);
904 devtype
= new bx_param_enum_c(floppya
,
906 "Type of floppy drive",
907 "Type of floppy drive",
911 devtype
->set_enabled(0); // hide devtype parameter
912 type
= new bx_param_enum_c(floppya
,
914 "Type of floppy disk",
915 "Type of floppy disk",
919 type
->set_ask_format("What type of floppy disk? (auto=detect) [%s] ");
920 type
->set_runtime_param(1);
922 status
= new bx_param_enum_c(floppya
,
924 "Is floppya inserted",
925 "Inserted or ejected",
929 status
->set_ask_format("Is the floppy inserted or ejected? [%s] ");
930 status
->set_runtime_param(1);
932 path
->set_handler(bx_param_string_handler
);
933 type
->set_handler(bx_param_handler
);
934 status
->set_handler(bx_param_handler
);
935 path
->set_initial_val("none");
936 floppya
->get_options()->set(bx_list_c::SERIES_ASK
);
938 path
= new bx_param_filename_c(floppyb
,
940 "Second floppy image/device",
941 "Pathname of second floppy image file or device.",
942 "", BX_PATHNAME_LEN
);
943 path
->set_ask_format("Enter new filename, or 'none' for no disk: [%s] ");
944 path
->set_runtime_param(1);
946 devtype
= new bx_param_enum_c(floppyb
,
948 "Type of floppy drive",
949 "Type of floppy drive",
953 devtype
->set_enabled(0); // hide devtype parameter
954 type
= new bx_param_enum_c(floppyb
,
956 "Type of floppy disk",
957 "Type of floppy disk",
961 type
->set_ask_format("What type of floppy disk? (auto=detect) [%s] ");
962 type
->set_runtime_param(1);
964 status
= new bx_param_enum_c(floppyb
,
966 "Is floppyb inserted",
967 "Inserted or ejected",
971 status
->set_ask_format("Is the floppy inserted or ejected? [%s] ");
972 status
->set_runtime_param(1);
974 path
->set_handler(bx_param_string_handler
);
975 type
->set_handler(bx_param_handler
);
976 status
->set_handler(bx_param_handler
);
977 path
->set_initial_val("none");
978 floppyb
->get_options()->set(bx_list_c::SERIES_ASK
);
979 floppy
->get_options()->set(bx_list_c::SHOW_PARENT
);
982 bx_list_c
*ata
= new bx_list_c(root_param
, "ata", "ATA/ATAPI Options");
985 char *s_atachannel
[] = {
991 char *s_atadevname
[2] = {
995 char *s_atadevice
[4][2] = {
996 { "First HD/CD on channel 0",
997 "Second HD/CD on channel 0" },
998 { "First HD/CD on channel 1",
999 "Second HD/CD on channel 1" },
1000 { "First HD/CD on channel 2",
1001 "Second HD/CD on channel 2" },
1002 { "First HD/CD on channel 3",
1003 "Second HD/CD on channel 3" }
1005 Bit16u ata_default_ioaddr1
[4] = {
1006 0x1f0, 0x170, 0x1e8, 0x168
1008 Bit16u ata_default_ioaddr2
[4] = {
1009 0x3f0, 0x370, 0x3e0, 0x360
1011 Bit8u ata_default_irq
[4] = {
1015 #define BXP_PARAMS_PER_ATA_DEVICE 12
1017 bx_list_c
*ata_menu
[BX_MAX_ATA_CHANNEL
];
1018 bx_list_c
*ata_res
[BX_MAX_ATA_CHANNEL
];
1021 for (channel
=0; channel
<BX_MAX_ATA_CHANNEL
; channel
++) {
1023 sprintf(name
, "%d", channel
);
1024 ata_menu
[channel
] = new bx_list_c(ata
, name
, s_atachannel
[channel
]);
1025 ata_menu
[channel
]->get_options()->set(bx_list_c::USE_TAB_WINDOW
);
1026 ata_res
[channel
] = new bx_list_c(ata_menu
[channel
], "resources", s_atachannel
[channel
], 8);
1027 ata_res
[channel
]->get_options()->set(bx_list_c::SERIES_ASK
);
1029 enabled
= new bx_param_bool_c(ata_res
[channel
],
1031 "Enable ATA channel",
1032 "Controls whether ata channel is installed or not",
1034 enabled
->set_ask_format("Channel is enabled: [%s] ");
1036 ioaddr
= new bx_param_num_c(ata_res
[channel
],
1039 "IO adress of ata command block",
1041 ata_default_ioaddr1
[channel
]);
1042 ioaddr
->set_base(16);
1043 ioaddr
->set_ask_format("Enter new ioaddr1: [0x%x] ");
1045 ioaddr2
= new bx_param_num_c(ata_res
[channel
],
1048 "IO adress of ata control block",
1050 ata_default_ioaddr2
[channel
]);
1051 ioaddr2
->set_base(16);
1052 ioaddr2
->set_ask_format("Enter new ioaddr2: [0x%x] ");
1054 irq
= new bx_param_num_c(ata_res
[channel
],
1057 "IRQ used by this ata channel",
1059 ata_default_irq
[channel
]);
1060 irq
->set_ask_format("Enter new IRQ: [%d] ");
1061 irq
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1063 // all items in the ata[channel] menu depend on the enabled flag.
1064 // The menu list is complete, but a few dependent_list items will
1065 // be added later. Use clone() to make a copy of the dependent_list
1066 // so that it can be changed without affecting the menu.
1067 enabled
->set_dependent_list(ata_res
[channel
]->clone());
1069 for (Bit8u slave
=0; slave
<2; slave
++) {
1070 menu
= new bx_list_c(ata_menu
[channel
],
1071 s_atadevname
[slave
],
1072 s_atadevice
[channel
][slave
],
1073 BXP_PARAMS_PER_ATA_DEVICE
+ 1);
1074 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1076 bx_param_bool_c
*present
= new bx_param_bool_c(menu
,
1078 "Enable this device",
1079 "Controls whether ata device is installed or not",
1081 present
->set_ask_format("Device is enabled: [%s] ");
1083 type
= new bx_param_enum_c(menu
,
1085 "Type of ATA device",
1086 "Type of ATA device (disk or cdrom)",
1087 atadevice_type_names
,
1089 BX_ATA_DEVICE_DISK
);
1090 type
->set_ask_format("Enter type of ATA device, disk or cdrom: [%s] ");
1092 path
= new bx_param_filename_c(menu
,
1094 "Path or physical device name",
1095 "Pathname of the image or physical device (cdrom only)",
1096 "", BX_PATHNAME_LEN
);
1097 path
->set_ask_format("Enter new filename: [%s] ");
1099 mode
= new bx_param_enum_c(menu
,
1101 "Type of disk image",
1102 "Mode of the ATA harddisk",
1103 atadevice_mode_names
,
1106 mode
->set_ask_format("Enter mode of ATA device, (flat, concat, etc.): [%s] ");
1108 status
= new bx_param_enum_c(menu
,
1111 "CD-ROM media status (inserted / ejected)",
1112 atadevice_status_names
,
1115 status
->set_ask_format("Is the device inserted or ejected? [%s] ");
1117 bx_param_filename_c
*journal
= new bx_param_filename_c(menu
,
1119 "Path of journal file",
1120 "Pathname of the journal file",
1121 "", BX_PATHNAME_LEN
);
1122 journal
->set_ask_format("Enter path of journal file: [%s]");
1124 bx_param_num_c
*cylinders
= new bx_param_num_c(menu
,
1127 "Number of cylinders",
1130 cylinders
->set_ask_format("Enter number of cylinders: [%d] ");
1131 bx_param_num_c
*heads
= new bx_param_num_c(menu
,
1137 heads
->set_ask_format("Enter number of heads: [%d] ");
1138 bx_param_num_c
*spt
= new bx_param_num_c(menu
,
1140 "Sectors per track",
1141 "Number of sectors per track",
1144 spt
->set_ask_format("Enter number of sectors per track: [%d] ");
1146 bx_param_string_c
*model
= new bx_param_string_c(menu
,
1149 "String returned by the 'identify device' command",
1150 "Generic 1234", 40);
1151 model
->set_ask_format("Enter new model name: [%s]");
1153 bx_param_enum_c
*biosdetect
= new bx_param_enum_c(menu
,
1156 "Type of bios detection",
1157 atadevice_biosdetect_names
,
1158 BX_ATA_BIOSDETECT_AUTO
,
1159 BX_ATA_BIOSDETECT_NONE
);
1160 biosdetect
->set_ask_format("Enter bios detection type: [%s]");
1162 bx_param_enum_c
*translation
= new bx_param_enum_c(menu
,
1165 "How the ata-disk translation is done by the bios",
1166 atadevice_translation_names
,
1167 BX_ATA_TRANSLATION_AUTO
,
1168 BX_ATA_TRANSLATION_NONE
);
1169 translation
->set_ask_format("Enter translation type: [%s]");
1171 // the menu and all items on it depend on the present flag
1172 present
->set_dependent_list(menu
->clone());
1173 // the present flag depends on the ATA channel's enabled flag
1174 enabled
->get_dependent_list()->add(present
);
1175 // the master/slave menu depends on the ATA channel's enabled flag
1176 enabled
->get_dependent_list()->add(menu
);
1178 type
->set_handler(bx_param_handler
);
1179 mode
->set_handler(bx_param_handler
);
1180 status
->set_handler(bx_param_handler
);
1181 path
->set_handler(bx_param_string_handler
);
1183 // Set the enable_hanlders
1184 journal
->set_enable_handler(bx_param_enable_handler
);
1185 status
->set_enable_handler(bx_param_enable_handler
);
1188 // Enable two ATA interfaces by default, disable the others.
1189 // Now that the dependence relationships are established, call set() on
1190 // the ata device present params to set all enables correctly.
1191 enabled
->set_initial_val(channel
<2);
1192 enabled
->set(channel
<2);
1196 bx_param_c
*disk_menu_init_list
[] = {
1197 SIM
->get_param(BXPN_FLOPPYA
),
1198 SIM
->get_param(BXPN_FLOPPYB
),
1199 SIM
->get_param(BXPN_ATA0_RES
),
1200 SIM
->get_param(BXPN_ATA0_MASTER
),
1201 SIM
->get_param(BXPN_ATA0_SLAVE
),
1202 #if BX_MAX_ATA_CHANNEL>1
1203 SIM
->get_param(BXPN_ATA1_RES
),
1204 SIM
->get_param(BXPN_ATA1_MASTER
),
1205 SIM
->get_param(BXPN_ATA1_SLAVE
),
1207 #if BX_MAX_ATA_CHANNEL>2
1208 SIM
->get_param(BXPN_ATA2_RES
),
1209 SIM
->get_param(BXPN_ATA2_MASTER
),
1210 SIM
->get_param(BXPN_ATA2_SLAVE
),
1212 #if BX_MAX_ATA_CHANNEL>3
1213 SIM
->get_param(BXPN_ATA3_RES
),
1214 SIM
->get_param(BXPN_ATA3_MASTER
),
1215 SIM
->get_param(BXPN_ATA3_SLAVE
),
1217 SIM
->get_param("boot_params"),
1220 menu
= new bx_list_c(special_menus
, "disk", "Bochs Disk Options", disk_menu_init_list
);
1221 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1224 bx_list_c
*ports
= new bx_list_c(root_param
, "ports", "Serial and Parallel Port Options");
1225 ports
->get_options()->set(bx_list_c::USE_TAB_WINDOW
| bx_list_c::SHOW_PARENT
);
1228 bx_list_c
*parallel
= new bx_list_c(ports
, "parallel", "Parallel Port Options");
1229 parallel
->get_options()->set(bx_list_c::SHOW_PARENT
);
1230 for (i
=0; i
<BX_N_PARALLEL_PORTS
; i
++) {
1231 sprintf(name
, "%d", i
+1);
1232 sprintf(label
, "Parallel Port %d", i
+1);
1233 menu
= new bx_list_c(parallel
, name
, label
);
1234 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1235 sprintf(label
, "Enable parallel port #%d", i
+1);
1236 sprintf(descr
, "Controls whether parallel port #%d is installed or not", i
+1);
1237 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
,
1238 (i
==0)? 1 : 0); // only enable #1 by default
1239 sprintf(label
, "Parallel port #%d output file", i
+1);
1240 sprintf(descr
, "Data written to parport#%d by the guest OS is written to this file", i
+1);
1241 path
= new bx_param_filename_c(menu
, "outfile", label
, descr
,
1242 "", BX_PATHNAME_LEN
);
1243 deplist
= new bx_list_c(NULL
, 1);
1245 enabled
->set_dependent_list(deplist
);
1248 static char *serial_mode_list
[] = {
1259 bx_list_c
*serial
= new bx_list_c(ports
, "serial", "Serial Port Options");
1260 serial
->get_options()->set(bx_list_c::SHOW_PARENT
);
1261 for (i
=0; i
<BX_N_SERIAL_PORTS
; i
++) {
1262 sprintf(name
, "%d", i
+1);
1263 sprintf(label
, "Serial Port %d", i
+1);
1264 menu
= new bx_list_c(serial
, name
, label
);
1265 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1266 sprintf(label
, "Enable serial port #%d (COM%d)", i
+1, i
+1);
1267 sprintf(descr
, "Controls whether COM%d is installed or not", i
+1);
1268 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
,
1269 (i
==0)?1 : 0); // only enable the first by default
1270 sprintf(label
, "I/O mode of the serial device for COM%d", i
+1);
1271 sprintf(descr
, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse', 'socket'");
1272 mode
= new bx_param_enum_c(menu
, "mode", label
, descr
,
1273 serial_mode_list
, 0, 0);
1274 mode
->set_ask_format("Choose I/O mode of the serial device [%s] ");
1275 sprintf(label
, "Pathname of the serial device for COM%d", i
+1);
1276 sprintf(descr
, "The path can be a real serial device or a pty (X/Unix only)");
1277 path
= new bx_param_filename_c(menu
, "dev", label
, descr
,
1278 "", BX_PATHNAME_LEN
);
1279 deplist
= new bx_list_c(NULL
, 2);
1282 enabled
->set_dependent_list(deplist
);
1285 bx_param_string_c
*port
;
1288 bx_list_c
*usb
= new bx_list_c(ports
, "usb", "USB Hub Options");
1289 usb
->get_options()->set(bx_list_c::SHOW_PARENT
);
1290 for (i
=0; i
<BX_N_USB_HUBS
; i
++) {
1291 sprintf(group
, "USB%d", i
+1);
1292 sprintf(name
, "%d", i
+1);
1293 sprintf(label
, "USB Hub %d", i
+1);
1294 menu
= new bx_list_c(usb
, name
, label
);
1295 menu
->set_enabled(BX_SUPPORT_PCIUSB
);
1296 sprintf(label
, "Enable usb hub #%d", i
+1);
1297 sprintf(descr
, "Controls whether %s is installed or not", group
);
1298 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
, 0);
1299 enabled
->set_enabled(BX_SUPPORT_PCIUSB
);
1300 port
= new bx_param_string_c(menu
,
1303 "Device connected to USB port #1",
1304 "", BX_PATHNAME_LEN
);
1305 port
->set_group(group
);
1306 port
= new bx_param_string_c(menu
,
1309 "Device connected to USB port #2",
1310 "", BX_PATHNAME_LEN
);
1311 port
->set_group(group
);
1312 enabled
->set_dependent_list(menu
->clone());
1316 bx_list_c
*network
= new bx_list_c(root_param
, "network", "Network Configuration");
1317 network
->get_options()->set(bx_list_c::USE_TAB_WINDOW
| bx_list_c::SHOW_PARENT
);
1319 // ne2k & pnic options
1320 static char *eth_module_list
[] = {
1322 #if defined(ETH_LINUX)
1331 #if defined(ETH_WIN32)
1334 #if defined(ETH_FBSD)
1347 menu
= new bx_list_c(network
, "ne2k", "NE2000", 7);
1348 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1349 menu
->set_enabled(BX_SUPPORT_NE2K
);
1350 enabled
= new bx_param_bool_c(menu
,
1352 "Enable NE2K NIC emulation",
1353 "Enables the NE2K NIC emulation",
1355 enabled
->set_enabled(BX_SUPPORT_NE2K
);
1356 ioaddr
= new bx_param_num_c(menu
,
1359 "I/O base address of the emulated NE2K device",
1362 ioaddr
->set_base(16);
1363 irq
= new bx_param_num_c(menu
,
1366 "IRQ used by the NE2K device",
1369 irq
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1370 macaddr
= new bx_param_string_c(menu
,
1373 "MAC address of the NE2K device. Don't use an address of a machine on your net.",
1374 "\xfe\xfd\xde\xad\xbe\xef", 6);
1375 macaddr
->get_options()->set(bx_param_string_c::RAW_BYTES
);
1376 macaddr
->set_separator(':');
1377 ethmod
= new bx_param_enum_c(menu
,
1380 "Module used for the connection to the real net.",
1384 ethmod
->set_by_name("null");
1385 ethmod
->set_ask_format("Choose ethernet module for the NE2K [%s] ");
1386 ethdev
= new bx_param_string_c(menu
,
1389 "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
1390 "xl0", BX_PATHNAME_LEN
);
1391 path
= new bx_param_filename_c(menu
,
1393 "Device configuration script",
1394 "Name of the script that is executed after Bochs initializes the network interface (optional).",
1395 "none", BX_PATHNAME_LEN
);
1396 path
->set_ask_format("Enter new script name, or 'none': [%s] ");
1397 enabled
->set_dependent_list(menu
->clone());
1399 menu
= new bx_list_c(network
, "pnic", "PCI Pseudo NIC");
1400 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1401 menu
->set_enabled(BX_SUPPORT_PCIPNIC
);
1402 enabled
= new bx_param_bool_c(menu
,
1404 "Enable Pseudo NIC emulation",
1405 "Enables the Pseudo NIC emulation",
1407 enabled
->set_enabled(BX_SUPPORT_PCIPNIC
);
1408 macaddr
= new bx_param_string_c(menu
,
1411 "MAC address of the Pseudo NIC device. Don't use an address of a machine on your net.",
1412 "\xfe\xfd\xde\xad\xbe\xef", 6);
1413 macaddr
->get_options()->set(bx_param_string_c::RAW_BYTES
);
1414 macaddr
->set_separator(':');
1415 ethmod
= new bx_param_enum_c(menu
,
1418 "Module used for the connection to the real net.",
1422 ethmod
->set_by_name("null");
1423 ethmod
->set_ask_format("Choose ethernet module for the Pseudo NIC [%s]");
1424 ethdev
= new bx_param_string_c(menu
,
1427 "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
1428 "xl0", BX_PATHNAME_LEN
);
1429 path
= new bx_param_filename_c(menu
,
1431 "Device configuration script",
1432 "Name of the script that is executed after Bochs initializes the network interface (optional).",
1433 "none", BX_PATHNAME_LEN
);
1434 path
->set_ask_format("Enter new script name, or 'none': [%s] ");
1435 enabled
->set_dependent_list(menu
->clone());
1438 bx_list_c
*sound
= new bx_list_c(root_param
, "sound", "Sound Configuration");
1439 sound
->get_options()->set(bx_list_c::SHOW_PARENT
);
1440 menu
= new bx_list_c(sound
, "sb16", "SB16 Configuration", 8);
1441 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1442 menu
->set_enabled(BX_SUPPORT_SB16
);
1445 enabled
= new bx_param_bool_c(menu
,
1447 "Enable SB16 emulation",
1448 "Enables the SB16 emulation",
1450 enabled
->set_enabled(BX_SUPPORT_SB16
);
1451 bx_param_num_c
*midimode
= new bx_param_num_c(menu
,
1454 "Controls the MIDI output format.",
1457 bx_param_filename_c
*midifile
= new bx_param_filename_c(menu
,
1460 "The filename is where the MIDI data is sent. This can be device or just a file.",
1461 "", BX_PATHNAME_LEN
);
1462 bx_param_num_c
*wavemode
= new bx_param_num_c(menu
,
1465 "Controls the wave output format.",
1468 bx_param_filename_c
*wavefile
= new bx_param_filename_c(menu
,
1471 "This is the device/file where the wave output is stored",
1472 "", BX_PATHNAME_LEN
);
1473 bx_param_num_c
*loglevel
= new bx_param_num_c(menu
,
1476 "Controls how verbose the SB16 emulation is (0 = no log, 5 = all errors and infos).",
1479 bx_param_filename_c
*logfile
= new bx_param_filename_c(menu
,
1482 "The file to write the SB16 emulator messages to.",
1483 "", BX_PATHNAME_LEN
);
1484 bx_param_num_c
*dmatimer
= new bx_param_num_c(menu
,
1487 "Microseconds per second for a DMA cycle.",
1492 midimode
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1493 wavemode
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1494 loglevel
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1496 loglevel
->set_group("SB16");
1497 dmatimer
->set_group("SB16");
1498 enabled
->set_dependent_list(menu
->clone());
1499 deplist
= new bx_list_c(NULL
, 1);
1500 deplist
->add(midifile
);
1501 midimode
->set_dependent_list(deplist
);
1502 deplist
= new bx_list_c(NULL
, 1);
1503 deplist
->add(wavefile
);
1504 wavemode
->set_dependent_list(deplist
);
1505 deplist
= new bx_list_c(NULL
, 1);
1506 deplist
->add(logfile
);
1507 loglevel
->set_dependent_list(deplist
);
1509 // misc options subtree
1510 bx_list_c
*misc
= new bx_list_c(root_param
, "misc", "Configure Everything Else");
1511 misc
->get_options()->set(bx_list_c::SHOW_PARENT
);
1512 bx_param_num_c
*gdbstub_opt
;
1514 // text snapshot check panic
1515 new bx_param_bool_c(misc
,
1516 "text_snapshot_check",
1517 "Enable text snapshot check panic",
1518 "Enable panic when text on screen matches snapchk.txt.\nUseful for regression testing.\nIn win32, turns off CR/LF in snapshots and cuts.",
1521 menu
= new bx_list_c(misc
, "gdbstub", "GDB Stub Options");
1522 menu
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
1523 menu
->set_enabled(BX_GDBSTUB
);
1524 enabled
= new bx_param_bool_c(menu
,
1529 enabled
->set_enabled(BX_GDBSTUB
);
1530 gdbstub_opt
= new bx_param_num_c(menu
,
1533 "TCP/IP port for GDB stub",
1536 gdbstub_opt
= new bx_param_num_c(menu
,
1542 gdbstub_opt
= new bx_param_num_c(menu
,
1548 gdbstub_opt
= new bx_param_num_c(menu
,
1554 enabled
->set_dependent_list(menu
->clone());
1556 // log options subtree
1557 menu
= new bx_list_c(root_param
, "log", "Logfile Options");
1560 path
= new bx_param_filename_c(menu
,
1563 "Pathname of bochs log file",
1564 "-", BX_PATHNAME_LEN
);
1565 path
->set_ask_format("Enter log filename: [%s] ");
1567 bx_param_string_c
*prefix
= new bx_param_string_c(menu
,
1569 "Log output prefix",
1570 "Prefix prepended to log output",
1571 "%t%e%d", BX_PATHNAME_LEN
);
1572 prefix
->set_ask_format("Enter log prefix: [%s] ");
1574 path
= new bx_param_filename_c(menu
,
1575 "debugger_filename",
1576 "Debugger Log filename",
1577 "Pathname of debugger log file",
1578 "-", BX_PATHNAME_LEN
);
1579 path
->set_ask_format("Enter debugger log filename: [%s] ");
1580 path
->set_enabled(BX_DEBUGGER
);
1583 bx_param_c
*runtime_init_list
[] = {
1584 SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
),
1585 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
),
1586 SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
),
1587 SIM
->get_param_string(BXPN_USER_SHORTCUT
),
1588 SIM
->get_param_num(BXPN_SB16_DMATIMER
),
1589 SIM
->get_param_num(BXPN_SB16_LOGLEVEL
),
1590 SIM
->get_param_string(BXPN_USB1_PORT1
),
1591 SIM
->get_param_string(BXPN_USB1_PORT2
),
1594 menu
= new bx_list_c(special_menus
, "runtime", "Misc runtime options", runtime_init_list
);
1595 menu
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::SHOW_GROUP_NAME
);
1598 void bx_reset_options()
1601 SIM
->get_param("cpu")->reset();
1603 // memory (ram & rom)
1604 SIM
->get_param("memory")->reset();
1607 SIM
->get_param("clock_cmos")->reset();
1610 SIM
->get_param("pci")->reset();
1612 // display & interface
1613 SIM
->get_param("display")->reset();
1616 SIM
->get_param("keyboard_mouse")->reset();
1619 SIM
->get_param("boot_params")->reset();
1622 SIM
->get_param("floppy")->reset();
1625 SIM
->get_param("ata")->reset();
1628 SIM
->get_param("ports")->reset();
1631 SIM
->get_param("network")->reset();
1634 SIM
->get_param("sound")->reset();
1637 SIM
->get_param("misc")->reset();
1640 SIM
->get_param("log")->reset();
1643 int bx_read_configuration(const char *rcfile
)
1645 // parse rcfile first, then parse arguments in order.
1646 BX_INFO (("reading configuration from %s", rcfile
));
1647 if (parse_bochsrc(rcfile
) < 0) {
1648 BX_PANIC (("reading from %s failed", rcfile
));
1651 // update log actions
1652 for (int level
=0; level
<N_LOGLEV
; level
++) {
1653 int action
= SIM
->get_default_log_action (level
);
1654 io
->set_log_action (level
, action
);
1659 int bx_parse_cmdline (int arg
, int argc
, char *argv
[])
1661 //if (arg < argc) BX_INFO (("parsing command line arguments"));
1663 while (arg
< argc
) {
1664 BX_INFO (("parsing arg %d, %s", arg
, argv
[arg
]));
1665 parse_line_unformatted("cmdline args", argv
[arg
]);
1668 // update log actions
1669 for (int level
=0; level
<N_LOGLEV
; level
++) {
1670 int action
= SIM
->get_default_log_action (level
);
1671 io
->set_log_action (level
, action
);
1677 char *bx_find_bochsrc()
1681 Bit32u retry
= 0, found
= 0;
1682 // try several possibilities for the bochsrc before giving up
1686 case 0: strcpy (rcfile
, ".bochsrc"); break;
1687 case 1: strcpy (rcfile
, "bochsrc"); break;
1688 case 2: strcpy (rcfile
, "bochsrc.txt"); break;
1690 case 3: strcpy (rcfile
, "bochsrc.bxrc"); break;
1691 #elif !BX_WITH_MACOS
1692 // only try this on unix
1695 char *ptr
= getenv("HOME");
1696 if (ptr
) snprintf (rcfile
, sizeof(rcfile
), "%s/.bochsrc", ptr
);
1699 case 4: strcpy (rcfile
, "/etc/bochsrc"); break;
1705 BX_DEBUG (("looking for configuration in %s", rcfile
));
1706 fd
= fopen(rcfile
, "r");
1710 assert (fd
!= NULL
&& rcfile
[0] != 0);
1712 return strdup(rcfile
);
1715 static int parse_bochsrc(const char *rcfile
)
1720 char context
[BX_PATHNAME_LEN
];
1723 // try several possibilities for the bochsrc before giving up
1725 bochsrc_include_count
++;
1727 fd
= fopen (rcfile
, "r");
1728 if (fd
== NULL
) return -1;
1732 ret
= fgets(line
, sizeof(line
)-1, fd
);
1733 line
[sizeof(line
) - 1] = '\0';
1734 int len
= strlen(line
);
1735 if ((len
>0) && (line
[len
-1] < ' '))
1737 if ((ret
!= NULL
) && strlen(line
)) {
1738 sprintf(context
, "%s:%u", rcfile
, linenum
);
1739 if (parse_line_unformatted(context
, line
) < 0) {
1741 break; // quit parsing after first error
1745 } while (!feof(fd
));
1747 bochsrc_include_count
--;
1751 static char *get_builtin_variable(char *varname
)
1759 static char data
[MAX_PATH
];
1762 if (strlen(varname
)<1) return NULL
;
1764 if (!strcmp(varname
, "BXSHARE")) {
1766 wsprintf(keyname
, "Software\\Bochs %s", VER_STRING
);
1767 code
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, keyname
, 0, KEY_READ
, &hkey
);
1768 if (code
== ERROR_SUCCESS
) {
1771 if (RegQueryValueEx(hkey
, "", NULL
, (LPDWORD
)&type
, (LPBYTE
)data
,
1772 (LPDWORD
)&size
) == ERROR_SUCCESS
) {
1783 return BX_SHARE_PATH
;
1790 static Bit32s
parse_line_unformatted(const char *context
, char *line
)
1792 #define MAX_PARAMS_LEN 40
1794 unsigned i
, string_i
= 0;
1796 char *params
[MAX_PARAMS_LEN
];
1798 bx_bool inquotes
= 0;
1799 bx_bool comment
= 0;
1801 memset(params
, 0, sizeof(params
));
1802 if (line
== NULL
) return 0;
1804 // if passed nothing but whitespace, just return
1805 for (i
=0; i
<strlen(line
); i
++) {
1806 if (!isspace(line
[i
])) break;
1808 if (i
>=strlen(line
))
1813 if (!strncmp(line
, "#include", 8))
1814 ptr
= strtok(line
, " ");
1816 ptr
= strtok(line
, ":");
1817 while ((ptr
) && (!comment
)) {
1821 string
[string_i
++] = ',';
1823 for (i
=0; i
<strlen(ptr
); i
++) {
1825 inquotes
= !inquotes
;
1826 else if ((ptr
[i
] == '#') && (strncmp(line
+i
, "#include", 8)) && !inquotes
) {
1831 // substitute environment variables.
1832 if (ptr
[i
] == '$') {
1838 while (isalpha(ptr
[i
]) || ptr
[i
]=='_') {
1839 *pv
= ptr
[i
]; pv
++; i
++;
1842 if (strlen(varname
)<1 || !(value
= getenv(varname
))) {
1843 if ((value
= get_builtin_variable(varname
))) {
1844 // append value to the string
1845 for (pv
=value
; *pv
; pv
++)
1846 string
[string_i
++] = *pv
;
1848 BX_PANIC (("could not look up environment variable '%s'", varname
));
1851 // append value to the string
1852 for (pv
=value
; *pv
; pv
++)
1853 string
[string_i
++] = *pv
;
1857 if (!isspace(ptr
[i
]) || inquotes
) {
1858 string
[string_i
++] = ptr
[i
];
1862 string
[string_i
] = '\0';
1863 if (string_i
== 0) break;
1865 if (params
[num_params
] != NULL
) {
1866 free(params
[num_params
]);
1867 params
[num_params
] = NULL
;
1869 if (num_params
< MAX_PARAMS_LEN
) {
1870 params
[num_params
++] = strdup(string
);
1872 BX_PANIC (("too many parameters, max is %d\n", MAX_PARAMS_LEN
));
1875 ptr
= strtok(NULL
, ",");
1877 Bit32s retval
= parse_line_formatted(context
, num_params
, ¶ms
[0]);
1878 for (i
=0; i
< MAX_PARAMS_LEN
; i
++)
1880 if ( params
[i
] != NULL
)
1889 // These macros are called for all parse errors, so that we can easily
1890 // change the behavior of all occurrences.
1891 #define PARSE_ERR(x) \
1892 do { BX_PANIC(x); return -1; } while (0)
1893 #define PARSE_WARN(x) \
1897 * this supports the "floppyx: image=" option.
1898 * the functions returns the type of the floppy
1899 * image (1.44, 360, etc.), based on the image file size.
1901 int get_floppy_type_from_image(const char *filename
)
1903 struct stat stat_buf
;
1905 if (stat(filename
, &stat_buf
))
1907 return BX_FLOPPY_NONE
;
1910 switch (stat_buf
.st_size
)
1913 return BX_FLOPPY_160K
;
1916 return BX_FLOPPY_180K
;
1919 return BX_FLOPPY_320K
;
1922 return BX_FLOPPY_360K
;
1925 return BX_FLOPPY_720K
;
1928 return BX_FLOPPY_1_2
;
1934 return BX_FLOPPY_1_44
;
1937 return BX_FLOPPY_2_88
;
1940 return BX_FLOPPY_UNKNOWN
;
1944 static Bit32s
parse_log_options(const char *context
, char *loglev
, char *param1
)
1948 if (!strcmp(loglev
, "panic")) {
1949 level
= LOGLEV_PANIC
;
1950 } else if (!strcmp(loglev
, "pass")) {
1951 level
= LOGLEV_PASS
;
1952 } else if (!strcmp(loglev
, "error")) {
1953 level
= LOGLEV_ERROR
;
1954 } else if (!strcmp(loglev
, "info")) {
1955 level
= LOGLEV_INFO
;
1956 } else { /* debug */
1957 level
= LOGLEV_DEBUG
;
1959 if (strncmp(param1
, "action=", 7)) {
1960 PARSE_ERR(("%s: %s directive malformed.", context
, loglev
));
1962 char *action
= param1
+ 7;
1963 if (!strcmp(action
, "fatal"))
1964 SIM
->set_default_log_action (level
, ACT_FATAL
);
1965 else if (!strcmp (action
, "report"))
1966 SIM
->set_default_log_action (level
, ACT_REPORT
);
1967 else if (!strcmp (action
, "ignore"))
1968 SIM
->set_default_log_action (level
, ACT_IGNORE
);
1969 else if (!strcmp (action
, "ask"))
1970 SIM
->set_default_log_action (level
, ACT_ASK
);
1972 PARSE_ERR(("%s: %s directive malformed.", context
, loglev
));
1977 static Bit32s
parse_line_formatted(const char *context
, int num_params
, char *params
[])
1983 if (num_params
< 1) return 0;
1984 if (num_params
< 2) {
1985 PARSE_ERR(("%s: a bochsrc option needs at least one parameter", context
));
1988 if (!strcmp(params
[0], "#include")) {
1989 if (num_params
!= 2) {
1990 PARSE_ERR(("%s: ignoring malformed #include directive.", context
));
1992 if (!strcmp(params
[1], context
)) {
1993 PARSE_ERR(("%s: cannot include this file again.", context
));
1995 if (bochsrc_include_count
== 2) {
1996 PARSE_ERR(("%s: include directive in an included file not supported yet.", context
));
1998 bx_read_configuration(params
[1]);
2000 else if (!strcmp(params
[0], "floppya")) {
2001 for (i
=1; i
<num_params
; i
++) {
2002 if (!strncmp(params
[i
], "2_88=", 5)) {
2003 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2004 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_2_88
);
2006 else if (!strncmp(params
[i
], "1_44=", 5)) {
2007 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2008 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_1_44
);
2010 else if (!strncmp(params
[i
], "1_2=", 4)) {
2011 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][4]);
2012 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_1_2
);
2014 else if (!strncmp(params
[i
], "720k=", 5)) {
2015 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2016 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_720K
);
2018 else if (!strncmp(params
[i
], "360k=", 5)) {
2019 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2020 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_360K
);
2022 // use CMOS reserved types?
2023 else if (!strncmp(params
[i
], "160k=", 5)) {
2024 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2025 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_160K
);
2027 else if (!strncmp(params
[i
], "180k=", 5)) {
2028 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2029 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_180K
);
2031 else if (!strncmp(params
[i
], "320k=", 5)) {
2032 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2033 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_320K
);
2035 else if (!strncmp(params
[i
], "image=", 6)) {
2036 /* "image=" means we should get floppy type from image */
2037 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][6]);
2038 t
= get_floppy_type_from_image(¶ms
[i
][6]);
2039 if (t
!= BX_FLOPPY_UNKNOWN
)
2040 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(t
);
2042 PARSE_ERR(("%s: floppya image size doesn't match one of the supported types.", context
));
2044 else if (!strncmp(params
[i
], "status=", 7)) {
2045 SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->set_by_name(¶ms
[i
][7]);
2048 PARSE_ERR(("%s: floppya attribute '%s' not understood.", context
,
2054 else if (!strcmp(params
[0], "floppyb")) {
2055 for (i
=1; i
<num_params
; i
++) {
2056 if (!strncmp(params
[i
], "2_88=", 5)) {
2057 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2058 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_2_88
);
2060 else if (!strncmp(params
[i
], "1_44=", 5)) {
2061 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2062 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_1_44
);
2064 else if (!strncmp(params
[i
], "1_2=", 4)) {
2065 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][4]);
2066 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_1_2
);
2068 else if (!strncmp(params
[i
], "720k=", 5)) {
2069 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2070 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_720K
);
2072 else if (!strncmp(params
[i
], "360k=", 5)) {
2073 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2074 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_360K
);
2076 // use CMOS reserved types?
2077 else if (!strncmp(params
[i
], "160k=", 5)) {
2078 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2079 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_160K
);
2081 else if (!strncmp(params
[i
], "180k=", 5)) {
2082 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2083 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_180K
);
2085 else if (!strncmp(params
[i
], "320k=", 5)) {
2086 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2087 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_320K
);
2089 else if (!strncmp(params
[i
], "image=", 6)) {
2090 /* "image=" means we should get floppy type from image */
2091 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][6]);
2092 t
= get_floppy_type_from_image(¶ms
[i
][6]);
2093 if (t
!= BX_FLOPPY_UNKNOWN
)
2094 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(t
);
2096 PARSE_ERR(("%s: floppyb image size doesn't match one of the supported types.", context
));
2098 else if (!strncmp(params
[i
], "status=", 7)) {
2099 SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->set_by_name(¶ms
[i
][7]);
2102 PARSE_ERR(("%s: floppyb attribute '%s' not understood.", context
,
2108 else if ((!strncmp(params
[0], "ata", 3)) && (strlen(params
[0]) == 4)) {
2110 Bit8u channel
= params
[0][3];
2112 if ((channel
< '0') || (channel
> '9')) {
2113 PARSE_ERR(("%s: ataX directive malformed.", context
));
2116 if (channel
>= BX_MAX_ATA_CHANNEL
) {
2117 PARSE_ERR(("%s: ataX directive malformed.", context
));
2120 if ((num_params
< 2) || (num_params
> 5)) {
2121 PARSE_ERR(("%s: ataX directive malformed.", context
));
2123 sprintf(tmpname
, "ata.%d.resources", channel
);
2124 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2125 if (strncmp(params
[1], "enabled=", 8)) {
2126 PARSE_ERR(("%s: ataX directive malformed.", context
));
2128 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[1][8]));
2131 if (num_params
> 2) {
2132 if (strncmp(params
[2], "ioaddr1=", 8)) {
2133 PARSE_ERR(("%s: ataX directive malformed.", context
));
2136 if ((params
[2][8] == '0') && (params
[2][9] == 'x'))
2137 SIM
->get_param_num("ioaddr1", base
)->set(strtoul(¶ms
[2][8], NULL
, 16));
2139 SIM
->get_param_num("ioaddr1", base
)->set(strtoul(¶ms
[2][8], NULL
, 10));
2143 if (num_params
> 3) {
2144 if (strncmp(params
[3], "ioaddr2=", 8)) {
2145 PARSE_ERR(("%s: ataX directive malformed.", context
));
2148 if ((params
[3][8] == '0') && (params
[3][9] == 'x'))
2149 SIM
->get_param_num("ioaddr2", base
)->set(strtoul(¶ms
[3][8], NULL
, 16));
2151 SIM
->get_param_num("ioaddr2", base
)->set(strtoul(¶ms
[3][8], NULL
, 10));
2155 if (num_params
> 4) {
2156 if (strncmp(params
[4], "irq=", 4)) {
2157 PARSE_ERR(("%s: ataX directive malformed.", context
));
2160 SIM
->get_param_num("irq", base
)->set(atol(¶ms
[4][4]));
2165 // ataX-master, ataX-slave
2166 else if ((!strncmp(params
[0], "ata", 3)) && (strlen(params
[0]) > 4)) {
2167 Bit8u channel
= params
[0][3];
2168 int type
= 0, mode
= BX_ATA_MODE_FLAT
, biosdetect
= BX_ATA_BIOSDETECT_AUTO
;
2169 Bit32u cylinders
= 0, heads
= 0, sectors
= 0;
2172 if ((channel
< '0') || (channel
> '9')) {
2173 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2176 if (channel
>= BX_MAX_ATA_CHANNEL
) {
2177 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2180 if ((strcmp(¶ms
[0][4], "-slave")) &&
2181 (strcmp(¶ms
[0][4], "-master"))) {
2182 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2185 sprintf(tmpname
, "ata.%d.%s", channel
, ¶ms
[0][5]);
2186 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2187 for (i
=1; i
<num_params
; i
++) {
2188 if (!strncmp(params
[i
], "type=", 5)) {
2189 type
= SIM
->get_param_enum("type", base
)->find_by_name(¶ms
[i
][5]);
2191 PARSE_ERR(("%s: ataX-master/slave: unknown type '%s'", context
, ¶ms
[i
][5]));
2193 } else if (!strcmp(params
[i
], "mode=z-undoable")) {
2194 PARSE_ERR(("%s: ataX-master/slave mode 'z-undoable' not implemented yet", context
));
2195 } else if (!strcmp(params
[i
], "mode=z-volatile")) {
2196 PARSE_ERR(("%s: ataX-master/slave mode 'z-volatile' not implemented yet", context
));
2197 } else if (!strncmp(params
[i
], "mode=", 5)) {
2198 mode
= SIM
->get_param_enum("mode", base
)->find_by_name(¶ms
[i
][5]);
2200 PARSE_ERR(("%s: ataX-master/slave: unknown mode '%s'", context
, ¶ms
[i
][5]));
2202 } else if (!strncmp(params
[i
], "path=", 5)) {
2203 SIM
->get_param_string("path", base
)->set(¶ms
[i
][5]);
2204 } else if (!strncmp(params
[i
], "cylinders=", 10)) {
2205 cylinders
= atol(¶ms
[i
][10]);
2206 } else if (!strncmp(params
[i
], "heads=", 6)) {
2207 heads
= atol(¶ms
[i
][6]);
2208 } else if (!strncmp(params
[i
], "spt=", 4)) {
2209 sectors
= atol(¶ms
[i
][4]);
2210 } else if (!strncmp(params
[i
], "model=", 6)) {
2211 SIM
->get_param_string("model", base
)->set(¶ms
[i
][6]);
2212 } else if (!strncmp(params
[i
], "biosdetect=", 11)) {
2213 biosdetect
= SIM
->get_param_enum("biosdetect", base
)->find_by_name(¶ms
[i
][11]);
2214 if (biosdetect
< 0) {
2215 PARSE_ERR(("%s: ataX-master/slave: unknown biosdetect '%s'", context
, ¶ms
[i
][11]));
2217 } else if (!strcmp(params
[i
], "translation=none")) {
2218 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_NONE
);
2219 } else if (!strcmp(params
[i
], "translation=lba")) {
2220 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LBA
);
2221 } else if (!strcmp(params
[i
], "translation=large")) {
2222 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LARGE
);
2223 } else if (!strcmp(params
[i
], "translation=echs")) { // synonym of large
2224 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LARGE
);
2225 } else if (!strcmp(params
[i
], "translation=rechs")) {
2226 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_RECHS
);
2227 } else if (!strcmp(params
[i
], "translation=auto")) {
2228 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_AUTO
);
2229 } else if (!strcmp(params
[i
], "status=ejected")) {
2230 SIM
->get_param_enum("status", base
)->set(BX_EJECTED
);
2231 } else if (!strcmp(params
[i
], "status=inserted")) {
2232 SIM
->get_param_enum("status", base
)->set(BX_INSERTED
);
2233 } else if (!strncmp(params
[i
], "journal=", 8)) {
2234 SIM
->get_param_string("journal", base
)->set(¶ms
[i
][8]);
2236 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2240 // Enables the ata device
2241 if (strlen(SIM
->get_param_string("path", base
)->getptr()) > 0) {
2242 SIM
->get_param_bool("present", base
)->set(1);
2243 SIM
->get_param_enum("type", base
)->set(type
);
2244 SIM
->get_param_enum("mode", base
)->set(mode
);
2245 SIM
->get_param_num("cylinders", base
)->set(cylinders
);
2246 SIM
->get_param_num("heads", base
)->set(heads
);
2247 SIM
->get_param_num("spt", base
)->set(sectors
);
2248 SIM
->get_param_num("biosdetect", base
)->set(biosdetect
);
2250 SIM
->get_param_bool("present", base
)->set(0);
2253 // if enabled, check if device ok
2254 if (SIM
->get_param_bool("present", base
)->get() == 1) {
2255 if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_DISK
) {
2256 if ((SIM
->get_param_num("cylinders", base
)->get() == 0) &&
2257 (SIM
->get_param_num("heads", base
)->get() ==0 ) &&
2258 (SIM
->get_param_num("spt", base
)->get() == 0)) {
2259 PARSE_WARN(("%s: ataX-master/slave CHS set to 0/0/0 - autodetection enabled", context
));
2260 // using heads = 16 and spt = 63 for autodetection (bximage defaults)
2261 SIM
->get_param_num("heads", base
)->set(16);
2262 SIM
->get_param_num("spt", base
)->set(63);
2264 } else if (SIM
->get_param_enum("type", base
)->get() != BX_ATA_DEVICE_CDROM
) {
2265 PARSE_WARN(("%s: ataX-master/slave: type should be specified", context
));
2268 } else if (!strcmp(params
[0], "boot")) {
2270 if (num_params
< 2) {
2271 PARSE_ERR(("%s: boot directive malformed.", context
));
2273 for (i
=1; i
<num_params
; i
++) {
2274 sprintf(tmppath
, "boot_params.boot_drive%d", i
);
2275 if (!strcmp(params
[i
], "none")) {
2276 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_NONE
);
2277 } else if (!strcmp(params
[i
], "a")) {
2278 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_FLOPPYA
);
2279 } else if (!strcmp(params
[i
], "floppy")) {
2280 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_FLOPPYA
);
2281 } else if (!strcmp(params
[i
], "c")) {
2282 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_DISKC
);
2283 } else if (!strcmp(params
[i
], "disk")) {
2284 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_DISKC
);
2285 } else if (!strcmp(params
[i
], "cdrom")) {
2286 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_CDROM
);
2288 PARSE_ERR(("%s: boot directive with unknown boot drive '%s'. use 'floppy', 'disk' or 'cdrom'.", context
, params
[i
]));
2291 if (SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == BX_BOOT_NONE
) {
2292 PARSE_ERR(("%s: first boot drive must be one of 'floppy', 'disk' or 'cdrom'.", context
));
2294 if ((SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE2
)->get()) ||
2295 (SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get()) ||
2296 ((SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get() != BX_BOOT_NONE
) &&
2297 (SIM
->get_param_enum(BXPN_BOOTDRIVE2
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get()))) {
2298 PARSE_ERR(("%s: a boot drive appears twice in boot sequence.", context
));
2300 } else if (!strcmp(params
[0], "floppy_bootsig_check")) {
2301 if (num_params
!= 2) {
2302 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2304 if (strncmp(params
[1], "disabled=", 9)) {
2305 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2307 if (params
[1][9] == '0')
2308 SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->set(0);
2309 else if (params
[1][9] == '1')
2310 SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->set(1);
2312 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2314 } else if (!strcmp(params
[0], "log")) {
2315 if (num_params
!= 2) {
2316 PARSE_ERR(("%s: log directive has wrong # args.", context
));
2318 SIM
->get_param_string(BXPN_LOG_FILENAME
)->set(params
[1]);
2319 } else if (!strcmp(params
[0], "logprefix")) {
2320 if (num_params
!= 2) {
2321 PARSE_ERR(("%s: logprefix directive has wrong # args.", context
));
2323 SIM
->get_param_string(BXPN_LOG_PREFIX
)->set(params
[1]);
2324 } else if (!strcmp(params
[0], "debugger_log")) {
2325 if (num_params
!= 2) {
2326 PARSE_ERR(("%s: debugger_log directive has wrong # args.", context
));
2328 SIM
->get_param_string(BXPN_DEBUGGER_LOG_FILENAME
)->set(params
[1]);
2329 } else if (!strcmp(params
[0], "panic")) {
2330 if (num_params
!= 2) {
2331 PARSE_ERR(("%s: panic directive malformed.", context
));
2333 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2336 } else if (!strcmp(params
[0], "pass")) {
2337 if (num_params
!= 2) {
2338 PARSE_ERR(("%s: pass directive malformed.", context
));
2340 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2343 } else if (!strcmp(params
[0], "error")) {
2344 if (num_params
!= 2) {
2345 PARSE_ERR(("%s: error directive malformed.", context
));
2347 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2350 } else if (!strcmp(params
[0], "info")) {
2351 if (num_params
!= 2) {
2352 PARSE_ERR(("%s: info directive malformed.", context
));
2354 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2357 } else if (!strcmp(params
[0], "debug")) {
2358 if (num_params
!= 2) {
2359 PARSE_ERR(("%s: debug directive malformed.", context
));
2361 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2364 } else if (!strcmp(params
[0], "cpu")) {
2365 if (num_params
< 2) {
2366 PARSE_ERR(("%s: cpu directive malformed.", context
));
2368 for (i
=1; i
<num_params
; i
++) {
2369 if (!strncmp(params
[i
], "count=", 6)) {
2370 unsigned processors
= 1, cores
= 1, threads
= 1;
2371 sscanf(¶ms
[i
][6], "%u:%u:%u", &processors
, &cores
, &threads
);
2372 unsigned smp_threads
= cores
*threads
*processors
;
2373 if (smp_threads
> BX_MAX_SMP_THREADS_SUPPORTED
) {
2374 PARSE_ERR(("%s: too many SMP threads defined, only %u threads supported",
2375 context
, BX_MAX_SMP_THREADS_SUPPORTED
));
2377 if (smp_threads
< 1) {
2378 PARSE_ERR(("%s: at least one CPU thread should be defined, cpu directive malformed", context
));
2380 SIM
->get_param_num(BXPN_CPU_NPROCESSORS
)->set(processors
);
2381 SIM
->get_param_num(BXPN_CPU_NCORES
)->set(cores
);
2382 SIM
->get_param_num(BXPN_CPU_NTHREADS
)->set(threads
);
2383 } else if (!strncmp(params
[i
], "ips=", 4)) {
2384 SIM
->get_param_num(BXPN_IPS
)->set(atol(¶ms
[i
][4]));
2385 if (SIM
->get_param_num(BXPN_IPS
)->get() < BX_MIN_IPS
) {
2386 PARSE_WARN(("%s: WARNING: ips is AWFULLY low!", context
));
2389 } else if (!strncmp(params
[i
], "quantum=", 8)) {
2390 SIM
->get_param_num(BXPN_SMP_QUANTUM
)->set(atol(¶ms
[i
][8]));
2392 } else if (!strncmp(params
[i
], "reset_on_triple_fault=", 22)) {
2393 if (params
[i
][22] == '0' || params
[i
][22] == '1') {
2394 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->set (params
[i
][22] - '0');
2396 PARSE_ERR(("%s: cpu directive malformed.", context
));
2399 PARSE_ERR(("%s: cpu directive malformed.", context
));
2402 } else if (!strcmp(params
[0], "megs")) {
2403 if (num_params
!= 2) {
2404 PARSE_ERR(("%s: megs directive: wrong # args.", context
));
2406 SIM
->get_param_num(BXPN_MEM_SIZE
)->set(atol(params
[1]));
2407 } else if (!strcmp(params
[0], "romimage")) {
2408 if ((num_params
< 2) || (num_params
> 3)) {
2409 PARSE_ERR(("%s: romimage directive: wrong # args.", context
));
2411 if (!strncmp(params
[1], "file=", 5)) {
2412 SIM
->get_param_string(BXPN_ROM_PATH
)->set(¶ms
[1][5]);
2414 PARSE_ERR(("%s: romimage directive malformed.", context
));
2416 if (num_params
== 3) {
2417 if (!strncmp(params
[2], "address=", 8)) {
2418 if ((params
[2][8] == '0') && (params
[2][9] == 'x'))
2419 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(strtoul(¶ms
[2][8], NULL
, 16));
2421 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(strtoul(¶ms
[2][8], NULL
, 10));
2423 PARSE_ERR(("%s: romimage directive malformed.", context
));
2426 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set (0);
2428 } else if (!strcmp(params
[0], "vgaromimage")) {
2429 if (num_params
!= 2) {
2430 PARSE_ERR(("%s: vgaromimage directive: wrong # args.", context
));
2432 if (!strncmp(params
[1], "file=", 5)) {
2433 SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->set(¶ms
[1][5]);
2435 BX_INFO(("WARNING: syntax has changed, please use 'vgaromimage: file=...' now"));
2436 SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->set(params
[1]);
2438 } else if (!strncmp(params
[0], "optromimage", 11)) {
2439 int num
= atoi(¶ms
[0][11]);
2440 char tmppath
[80], tmpaddr
[80];
2441 if ((num
< 1) || (num
> BX_N_OPTROM_IMAGES
)) {
2442 PARSE_ERR(("%s: optromimage%d: not supported", context
, num
));
2444 if (num_params
!= 3) {
2445 PARSE_ERR(("%s: optromimage%d directive: wrong # args.", context
, num
));
2447 sprintf(tmppath
, "memory.optrom.%d.path", num
);
2448 sprintf(tmpaddr
, "memory.optrom.%d.addr", num
);
2449 for (i
=1; i
<num_params
; i
++) {
2450 if (!strncmp(params
[i
], "file=", 5)) {
2451 SIM
->get_param_string(tmppath
)->set(¶ms
[i
][5]);
2452 } else if (!strncmp(params
[i
], "address=", 8)) {
2453 if ((params
[i
][8] == '0') && (params
[2][9] == 'x'))
2454 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 16));
2456 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 10));
2458 PARSE_ERR(("%s: optromimage%d directive malformed.", context
, num
));
2461 } else if (!strncmp(params
[0], "optramimage", 11)) {
2462 int num
= atoi(¶ms
[0][11]);
2463 char tmppath
[80], tmpaddr
[80];
2464 if ((num
< 1) || (num
> BX_N_OPTRAM_IMAGES
)) {
2465 PARSE_ERR(("%s: optramimage%d: not supported", context
, num
));
2467 if (num_params
!= 3) {
2468 PARSE_ERR(("%s: optramimage%d directive: wrong # args.", context
, num
));
2470 sprintf(tmppath
, "memory.optram.%d.path", num
);
2471 sprintf(tmpaddr
, "memory.optram.%d.addr", num
);
2472 for (i
=1; i
<num_params
; i
++) {
2473 if (!strncmp(params
[i
], "file=", 5)) {
2474 SIM
->get_param_string(tmppath
)->set(¶ms
[i
][5]);
2475 } else if (!strncmp(params
[i
], "address=", 8)) {
2476 if ((params
[i
][8] == '0') && (params
[2][9] == 'x'))
2477 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 16));
2479 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 10));
2481 PARSE_ERR(("%s: optramimage%d directive malformed.", context
, num
));
2484 } else if (!strcmp(params
[0], "vga_update_interval")) {
2485 if (num_params
!= 2) {
2486 PARSE_ERR(("%s: vga_update_interval directive: wrong # args.", context
));
2488 SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->set(atol(params
[1]));
2489 if (SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->get() < 50000) {
2490 BX_INFO(("%s: vga_update_interval seems awfully small!", context
));
2492 } else if (!strcmp(params
[0], "vga")) {
2493 if (num_params
!= 2) {
2494 PARSE_ERR(("%s: vga directive: wrong # args.", context
));
2496 if (!strncmp(params
[1], "extension=", 10)) {
2497 SIM
->get_param_string(BXPN_VGA_EXTENSION
)->set(¶ms
[1][10]);
2499 } else if (!strcmp(params
[0], "keyboard_serial_delay")) {
2500 if (num_params
!= 2) {
2501 PARSE_ERR(("%s: keyboard_serial_delay directive: wrong # args.", context
));
2503 SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->set(atol(params
[1]));
2504 if (SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->get() < 5) {
2505 PARSE_ERR (("%s: keyboard_serial_delay not big enough!", context
));
2507 } else if (!strcmp(params
[0], "keyboard_paste_delay")) {
2508 if (num_params
!= 2) {
2509 PARSE_ERR(("%s: keyboard_paste_delay directive: wrong # args.", context
));
2511 SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->set(atol(params
[1]));
2512 if (SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->get() < 1000) {
2513 PARSE_ERR (("%s: keyboard_paste_delay not big enough!", context
));
2515 } else if (!strcmp(params
[0], "floppy_command_delay")) {
2516 PARSE_WARN(("%s: floppy_command_delay is DEPRECATED (now using hardware timing).", context
));
2517 } else if (!strcmp(params
[0], "ips")) {
2518 PARSE_WARN(("%s: ips directive is DEPRECATED (use cpu directive parameter 'ips').", context
));
2519 if (num_params
!= 2) {
2520 PARSE_ERR(("%s: ips directive: wrong # args.", context
));
2522 SIM
->get_param_num(BXPN_IPS
)->set(atol(params
[1]));
2523 if (SIM
->get_param_num(BXPN_IPS
)->get() < BX_MIN_IPS
) {
2524 PARSE_WARN(("%s: WARNING: ips is AWFULLY low!", context
));
2526 } else if (!strcmp(params
[0], "text_snapshot_check")) {
2527 if (num_params
!= 2) {
2528 PARSE_ERR(("%s: text_snapshot_check directive: wrong # args.", context
));
2530 if (!strncmp(params
[1], "enabled=", 8)) {
2531 if (params
[1][8] == '0' || params
[1][8] == '1')
2532 SIM
->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK
)->set(params
[1][8] - '0');
2534 PARSE_ERR(("%s: text_snapshot_check directive malformed.", context
));
2536 PARSE_ERR(("%s: text_snapshot_check directive malformed.", context
));
2538 } else if (!strcmp(params
[0], "mouse")) {
2539 if (num_params
< 2) {
2540 PARSE_ERR(("%s: mouse directive malformed.", context
));
2542 for (i
=1; i
<num_params
; i
++) {
2543 if (!strncmp(params
[i
], "enabled=", 8)) {
2544 if (params
[i
][8] == '0' || params
[i
][8] == '1')
2545 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
)->set(params
[i
][8] - '0');
2547 PARSE_ERR(("%s: mouse directive malformed.", context
));
2548 } else if (!strncmp(params
[i
], "type=", 5)) {
2549 if (!SIM
->get_param_enum(BXPN_MOUSE_TYPE
)->set_by_name(¶ms
[i
][5]))
2550 PARSE_ERR(("%s: mouse type '%s' not available", context
, ¶ms
[i
][5]));
2552 PARSE_ERR(("%s: mouse directive malformed.", context
));
2555 } else if (!strcmp(params
[0], "private_colormap")) {
2556 if (num_params
!= 2) {
2557 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2559 if (strncmp(params
[1], "enabled=", 8)) {
2560 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2562 if (params
[1][8] == '0' || params
[1][8] == '1')
2563 SIM
->get_param_bool(BXPN_PRIVATE_COLORMAP
)->set(params
[1][8] - '0');
2565 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2567 } else if (!strcmp(params
[0], "fullscreen")) {
2569 if (num_params
!= 2) {
2570 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2572 if (strncmp(params
[1], "enabled=", 8)) {
2573 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2575 if (params
[1][8] == '0' || params
[1][8] == '1') {
2576 SIM
->get_param_bool(BXPN_FULLSCREEN
)->set(params
[1][8] - '0');
2578 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2581 } else if (!strcmp(params
[0], "screenmode")) {
2583 if (num_params
!= 2) {
2584 PARSE_ERR(("%s: screenmode directive malformed.", context
));
2586 if (strncmp(params
[1], "name=", 5)) {
2587 PARSE_ERR(("%s: screenmode directive malformed.", context
));
2589 SIM
->get_param_string(BXPN_SCREENMODE
)->set(¶ms
[1][5]);
2591 } else if (!strcmp(params
[0], "sb16")) {
2593 base
= (bx_list_c
*) SIM
->get_param(BXPN_SB16
);
2594 for (i
=1; i
<num_params
; i
++) {
2595 if (!strncmp(params
[i
], "enabled=", 8)) {
2596 enable
= atol(¶ms
[i
][8]);
2597 } else if (!strncmp(params
[i
], "midi=", 5)) {
2598 SIM
->get_param_string("midifile", base
)->set(¶ms
[i
][5]);
2599 } else if (!strncmp(params
[i
], "midimode=", 9)) {
2600 SIM
->get_param_num("midimode", base
)->set(atol(¶ms
[i
][9]));
2601 } else if (!strncmp(params
[i
], "wave=", 5)) {
2602 SIM
->get_param_string("wavefile", base
)->set(¶ms
[i
][5]);
2603 } else if (!strncmp(params
[i
], "wavemode=", 9)) {
2604 SIM
->get_param_num("wavemode", base
)->set(atol(¶ms
[i
][9]));
2605 } else if (!strncmp(params
[i
], "log=", 4)) {
2606 SIM
->get_param_string("logfile", base
)->set(¶ms
[i
][4]);
2607 } else if (!strncmp(params
[i
], "loglevel=", 9)) {
2608 SIM
->get_param_num("loglevel", base
)->set(atol(¶ms
[i
][9]));
2609 } else if (!strncmp(params
[i
], "dmatimer=", 9)) {
2610 SIM
->get_param_num("dmatimer", base
)->set(atol(¶ms
[i
][9]));
2612 BX_ERROR(("%s: unknown parameter for sb16 ignored.", context
));
2615 if ((enable
!= 0) && (SIM
->get_param_num("dmatimer", base
)->get() > 0))
2616 SIM
->get_param_bool("enabled", base
)->set(1);
2618 SIM
->get_param_bool("enabled", base
)->set(0);
2619 } else if ((!strncmp(params
[0], "com", 3)) && (strlen(params
[0]) == 4)) {
2622 if ((idx
< '1') || (idx
> '9')) {
2623 PARSE_ERR(("%s: comX directive malformed.", context
));
2626 if (idx
> BX_N_SERIAL_PORTS
) {
2627 PARSE_ERR(("%s: comX port number out of range.", context
));
2629 sprintf(tmpname
, "ports.serial.%d", idx
);
2630 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2631 for (i
=1; i
<num_params
; i
++) {
2632 if (!strncmp(params
[i
], "enabled=", 8)) {
2633 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2634 } else if (!strncmp(params
[i
], "mode=", 5)) {
2635 if (!SIM
->get_param_enum("mode", base
)->set_by_name(¶ms
[i
][5]))
2636 PARSE_ERR(("%s: com%d serial port mode '%s' not available", context
, idx
, ¶ms
[i
][5]));
2637 SIM
->get_param_bool("enabled", base
)->set(1);
2638 } else if (!strncmp(params
[i
], "dev=", 4)) {
2639 SIM
->get_param_string("dev", base
)->set(¶ms
[i
][4]);
2640 SIM
->get_param_bool("enabled", base
)->set(1);
2642 PARSE_ERR(("%s: unknown parameter for com%d ignored.", context
, idx
));
2645 } else if ((!strncmp(params
[0], "parport", 7)) && (strlen(params
[0]) == 8)) {
2648 if ((idx
< '1') || (idx
> '9')) {
2649 PARSE_ERR(("%s: parportX directive malformed.", context
));
2652 if (idx
> BX_N_PARALLEL_PORTS
) {
2653 PARSE_ERR(("%s: parportX port number out of range.", context
));
2655 sprintf(tmpname
, "ports.parallel.%d", idx
);
2656 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2657 for (i
=1; i
<num_params
; i
++) {
2658 if (!strncmp(params
[i
], "enabled=", 8)) {
2659 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2660 } else if (!strncmp(params
[i
], "file=", 5)) {
2661 SIM
->get_param_string("outfile", base
)->set(¶ms
[i
][5]);
2662 SIM
->get_param_bool("enabled", base
)->set(1);
2664 BX_ERROR(("%s: unknown parameter for parport%d ignored.", context
, idx
));
2667 } else if ((!strncmp(params
[0], "usb", 3)) && (strlen(params
[0]) == 4)) {
2670 if ((idx
< '1') || (idx
> '9')) {
2671 PARSE_ERR(("%s: usbX directive malformed.", context
));
2674 if (idx
> BX_N_USB_HUBS
) {
2675 PARSE_ERR(("%s: usbX hub number out of range.", context
));
2677 sprintf(tmpname
, "ports.usb.%d", idx
);
2678 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2679 for (i
=1; i
<num_params
; i
++) {
2680 if (!strncmp(params
[i
], "enabled=", 8)) {
2681 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2682 } else if (!strncmp(params
[i
], "port1=", 6)) {
2683 SIM
->get_param_string("port1", base
)->set(¶ms
[i
][6]);
2684 } else if (!strncmp(params
[i
], "option1=", 8)) {
2685 PARSE_WARN(("%s: usb port1 option is now deprecated", context
));
2686 } else if (!strncmp(params
[i
], "port2=", 6)) {
2687 SIM
->get_param_string("port2", base
)->set(¶ms
[i
][6]);
2688 } else if (!strncmp(params
[i
], "option2=", 8)) {
2689 PARSE_WARN(("%s: usb port2 option is now deprecated", context
));
2690 } else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2691 PARSE_WARN(("%s: usb ioaddr is now DEPRECATED (assigned by BIOS).", context
));
2692 } else if (!strncmp(params
[i
], "irq=", 4)) {
2693 PARSE_WARN(("%s: usb irq is now DEPRECATED (assigned by BIOS).", context
));
2695 PARSE_WARN(("%s: unknown parameter '%s' for usb%d ignored.", context
, params
[i
], idx
));
2698 } else if (!strcmp(params
[0], "i440fxsupport")) {
2700 for (i
=1; i
<num_params
; i
++) {
2701 if (!strncmp(params
[i
], "enabled=", 8)) {
2702 SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->set(atol(¶ms
[i
][8]));
2703 } else if ((!strncmp(params
[i
], "slot", 4)) && (params
[i
][5] == '=')) {
2704 slot
= atol(¶ms
[i
][4]);
2705 if ((slot
> 0) && (slot
< 6)) {
2706 sprintf(tmpdev
, "pci.slot.%d", slot
);
2707 SIM
->get_param_string(tmpdev
)->set(¶ms
[i
][6]);
2709 BX_ERROR(("%s: unknown pci slot number ignored.", context
));
2712 PARSE_ERR(("%s: i440fxsupport: unknown parameter '%s'.", context
, params
[i
]));
2715 } else if (!strcmp(params
[0], "pcidev")) {
2716 if (num_params
!= 3) {
2717 PARSE_ERR(("%s: pcidev directive malformed.", context
));
2719 for (i
=1; i
<num_params
; i
++) {
2720 if (!strncmp(params
[i
], "vendor=", 7)) {
2721 if ( (params
[i
][7] == '0') && (toupper(params
[i
][8]) == 'X') )
2722 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2724 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->set(strtoul(¶ms
[i
][7], NULL
, 10));
2726 else if (!strncmp(params
[i
], "device=", 7)) {
2727 if ( (params
[i
][7] == '0') && (toupper(params
[i
][8]) == 'X') )
2728 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2730 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->set(strtoul(¶ms
[i
][7], NULL
, 10));
2733 BX_ERROR(("%s: unknown parameter for pcidev ignored.", context
));
2736 } else if (!strcmp(params
[0], "cmosimage")) {
2737 for (i
=1; i
<num_params
; i
++) {
2738 if (!strncmp(params
[i
], "file=", 5)) {
2739 SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->set(¶ms
[i
][5]);
2740 } else if (!strcmp(params
[i
], "rtc_init=time0")) {
2741 SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->set(0);
2742 } else if (!strcmp(params
[i
], "rtc_init=image")) {
2743 SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->set(1);
2745 // for backward compatiblity
2746 SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->set(params
[i
]);
2749 if (strlen(SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr()) > 0) {
2750 SIM
->get_param_bool(BXPN_CMOSIMAGE_ENABLED
)->set(1);
2752 } else if (!strcmp(params
[0], "clock")) {
2753 for (i
=1; i
<num_params
; i
++) {
2754 if (!strncmp(params
[i
], "sync=", 5)) {
2755 SIM
->get_param_enum(BXPN_CLOCK_SYNC
)->set_by_name(¶ms
[i
][5]);
2757 else if (!strcmp(params
[i
], "time0=local")) {
2758 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(BX_CLOCK_TIME0_LOCAL
);
2760 else if (!strcmp(params
[i
], "time0=utc")) {
2761 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(BX_CLOCK_TIME0_UTC
);
2763 else if (!strncmp(params
[i
], "time0=", 6)) {
2764 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(atoi(¶ms
[i
][6]));
2767 BX_ERROR(("%s: unknown parameter for clock ignored.", context
));
2771 else if (!strcmp(params
[0], "gdbstub")) {
2773 if (num_params
< 2) {
2774 PARSE_ERR(("%s: gdbstub directive: wrong # args.", context
));
2776 base
= (bx_list_c
*) SIM
->get_param(BXPN_GDBSTUB
);
2777 for (i
=1; i
<num_params
; i
++) {
2778 if (!strncmp(params
[i
], "enabled=", 8)) {
2779 if (params
[i
][8] == '0') {
2780 SIM
->get_param_bool("enabled", base
)->set(0);
2781 BX_INFO(("Disabled gdbstub"));
2782 bx_dbg
.gdbstub_enabled
= 0;
2784 else if (params
[i
][8] == '1') {
2785 SIM
->get_param_bool("enabled", base
)->set(1);
2786 BX_INFO(("Enabled gdbstub"));
2787 bx_dbg
.gdbstub_enabled
= 1;
2790 PARSE_ERR(("%s: gdbstub directive malformed.", context
));
2793 else if (!strncmp(params
[i
], "port=", 5)) {
2794 SIM
->get_param_num("port", base
)->set(atoi(¶ms
[i
][5]));
2796 else if (!strncmp(params
[i
], "text_base=", 10)) {
2797 SIM
->get_param_num("text_base", base
)->set(atoi(¶ms
[i
][10]));
2799 else if (!strncmp(params
[i
], "data_base=", 10)) {
2800 SIM
->get_param_num("data_base", base
)->set(atoi(¶ms
[i
][10]));
2802 else if (!strncmp(params
[i
], "bss_base=", 9)) {
2803 SIM
->get_param_num("bss_base", base
)->set(atoi(¶ms
[i
][9]));
2806 PARSE_ERR(("%s: gdbstub directive malformed.", context
));
2810 PARSE_ERR(("%s: Bochs is not compiled with gdbstub support", context
));
2814 #if BX_MAGIC_BREAKPOINT
2815 else if (!strcmp(params
[0], "magic_break")) {
2816 if (num_params
!= 2) {
2817 PARSE_ERR(("%s: magic_break directive: wrong # args.", context
));
2819 if (strncmp(params
[1], "enabled=", 8)) {
2820 PARSE_ERR(("%s: magic_break directive malformed.", context
));
2822 if (params
[1][8] == '0') {
2823 BX_INFO(("Ignoring magic break points"));
2824 bx_dbg
.magic_break_enabled
= 0;
2826 else if (params
[1][8] == '1') {
2827 BX_INFO(("Stopping on magic break points"));
2828 bx_dbg
.magic_break_enabled
= 1;
2831 PARSE_ERR(("%s: magic_break directive malformed.", context
));
2835 else if (!strcmp(params
[0], "ne2k")) {
2840 base
= (bx_list_c
*) SIM
->get_param(BXPN_NE2K
);
2841 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2842 SIM
->get_param_enum("ethmod", base
)->set_by_name("null");
2844 for (i
=1; i
<num_params
; i
++) {
2845 if (!strncmp(params
[i
], "enabled=", 8)) {
2846 if (atol(¶ms
[i
][8]) == 0) valid
|= 0x80;
2848 else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2849 SIM
->get_param_num("ioaddr", base
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2852 else if (!strncmp(params
[i
], "irq=", 4)) {
2853 SIM
->get_param_num("irq", base
)->set(atol(¶ms
[i
][4]));
2856 else if (!strncmp(params
[i
], "mac=", 4)) {
2857 n
= sscanf(¶ms
[i
][4], "%x:%x:%x:%x:%x:%x",
2858 &tmp
[0],&tmp
[1],&tmp
[2],&tmp
[3],&tmp
[4],&tmp
[5]);
2860 PARSE_ERR(("%s: ne2k mac address malformed.", context
));
2863 tmpchar
[n
] = (unsigned char)tmp
[n
];
2864 SIM
->get_param_string("macaddr", base
)->set(tmpchar
);
2867 else if (!strncmp(params
[i
], "ethmod=", 7)) {
2868 if (!SIM
->get_param_enum("ethmod", base
)->set_by_name(¶ms
[i
][7]))
2869 PARSE_ERR(("%s: ethernet module '%s' not available", context
, ¶ms
[i
][7]));
2871 else if (!strncmp(params
[i
], "ethdev=", 7)) {
2872 SIM
->get_param_string("ethdev", base
)->set(¶ms
[i
][7]);
2874 else if (!strncmp(params
[i
], "script=", 7)) {
2875 SIM
->get_param_string("script", base
)->set(¶ms
[i
][7]);
2878 PARSE_WARN(("%s: unknown parameter '%s' for ne2k ignored.", context
, params
[i
]));
2881 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2882 if (valid
== 0x07) {
2883 SIM
->get_param_bool("enabled", base
)->set(1);
2884 } else if (valid
< 0x80) {
2885 PARSE_ERR(("%s: ne2k directive incomplete (ioaddr, irq and mac are required)", context
));
2889 SIM
->get_param_bool("enabled", base
)->set(0);
2892 } else if (!strcmp(params
[0], "pnic")) {
2897 base
= (bx_list_c
*) SIM
->get_param(BXPN_PNIC
);
2898 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2899 SIM
->get_param_enum("ethmod", base
)->set_by_name("null");
2901 for (i
=1; i
<num_params
; i
++) {
2902 if (!strncmp(params
[i
], "enabled=", 8)) {
2903 if (atol(¶ms
[i
][8]) == 0) valid
|= 0x80;
2904 } else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2905 PARSE_WARN(("%s: pnic ioaddr is now DEPRECATED (assigned by BIOS).", context
));
2906 } else if (!strncmp(params
[i
], "irq=", 4)) {
2907 PARSE_WARN(("%s: pnic irq is now DEPRECATED (assigned by BIOS).", context
));
2908 } else if (!strncmp(params
[i
], "mac=", 4)) {
2909 n
= sscanf(¶ms
[i
][4], "%x:%x:%x:%x:%x:%x",
2910 &tmp
[0],&tmp
[1],&tmp
[2],&tmp
[3],&tmp
[4],&tmp
[5]);
2912 PARSE_ERR(("%s: pnic mac address malformed.", context
));
2915 tmpchar
[n
] = (unsigned char)tmp
[n
];
2916 SIM
->get_param_string("macaddr", base
)->set(tmpchar
);
2918 } else if (!strncmp(params
[i
], "ethmod=", 7)) {
2919 if (!SIM
->get_param_enum("ethmod", base
)->set_by_name(¶ms
[i
][7]))
2920 PARSE_ERR(("%s: ethernet module '%s' not available", context
, ¶ms
[i
][7]));
2921 } else if (!strncmp(params
[i
], "ethdev=", 7)) {
2922 SIM
->get_param_string("ethdev", base
)->set(¶ms
[i
][7]);
2923 } else if (!strncmp(params
[i
], "script=", 7)) {
2924 SIM
->get_param_string("script", base
)->set(¶ms
[i
][7]);
2926 PARSE_WARN(("%s: unknown parameter '%s' for pnic ignored.", context
, params
[i
]));
2929 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2930 if (valid
== 0x07) {
2931 SIM
->get_param_bool("enabled", base
)->set(1);
2932 } else if (valid
< 0x80) {
2933 PARSE_ERR(("%s: pnic directive incomplete (mac is required)", context
));
2937 SIM
->get_param_bool("enabled", base
)->set(0);
2940 } else if (!strcmp(params
[0], "load32bitOSImage")) {
2941 if ( (num_params
!=4) && (num_params
!=5) ) {
2942 PARSE_ERR(("%s: load32bitOSImage directive: wrong # args.", context
));
2944 if (strncmp(params
[1], "os=", 3)) {
2945 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2947 if (!strcmp(¶ms
[1][3], "nullkernel")) {
2948 SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->set(Load32bitOSNullKernel
);
2950 else if (!strcmp(¶ms
[1][3], "linux")) {
2951 SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->set(Load32bitOSLinux
);
2954 PARSE_ERR(("%s: load32bitOSImage: unsupported OS.", context
));
2956 if (strncmp(params
[2], "path=", 5)) {
2957 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2959 if (strncmp(params
[3], "iolog=", 6)) {
2960 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2962 SIM
->get_param_string(BXPN_LOAD32BITOS_PATH
)->set(¶ms
[2][5]);
2963 SIM
->get_param_string(BXPN_LOAD32BITOS_IOLOG
)->set(¶ms
[3][6]);
2964 if (num_params
== 5) {
2965 if (strncmp(params
[4], "initrd=", 7)) {
2966 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2968 SIM
->get_param_string(BXPN_LOAD32BITOS_INITRD
)->set(¶ms
[4][7]);
2971 else if (!strcmp(params
[0], "keyboard_type")) {
2972 if (num_params
!= 2) {
2973 PARSE_ERR(("%s: keyboard_type directive: wrong # args.", context
));
2975 if (!SIM
->get_param_enum(BXPN_KBD_TYPE
)->set_by_name(params
[1])) {
2976 PARSE_ERR(("%s: keyboard_type directive: wrong arg '%s'.", context
,params
[1]));
2979 else if (!strcmp(params
[0], "keyboard_mapping")
2980 ||!strcmp(params
[0], "keyboardmapping")) {
2981 for (i
=1; i
<num_params
; i
++) {
2982 if (!strncmp(params
[i
], "enabled=", 8)) {
2983 SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->set(atol(¶ms
[i
][8]));
2985 else if (!strncmp(params
[i
], "map=", 4)) {
2986 SIM
->get_param_string(BXPN_KBD_KEYMAP
)->set(¶ms
[i
][4]);
2990 else if (!strcmp(params
[0], "user_shortcut"))
2992 if (num_params
!= 2) {
2993 PARSE_ERR(("%s: user_shortcut directive: wrong # args.", context
));
2995 if(!strncmp(params
[1], "keys=", 4)) {
2996 SIM
->get_param_string(BXPN_USER_SHORTCUT
)->set(¶ms
[1][5]);
2997 if ((strchr(¶ms
[1][5], '-') == NULL
) && (strlen(¶ms
[1][5]) > 5))
2998 PARSE_WARN(("user_shortcut: old-style syntax detected"));
3000 PARSE_ERR(("%s: user_shortcut directive malformed.", context
));
3003 else if (!strcmp(params
[0], "config_interface"))
3005 if (num_params
!= 2) {
3006 PARSE_ERR(("%s: config_interface directive: wrong # args.", context
));
3008 if (!SIM
->get_param_enum(BXPN_SEL_CONFIG_INTERFACE
)->set_by_name(params
[1]))
3009 PARSE_ERR(("%s: config_interface '%s' not available", context
, params
[1]));
3011 else if (!strcmp(params
[0], "display_library")) {
3012 if ((num_params
< 2) || (num_params
> 3)) {
3013 PARSE_ERR(("%s: display_library directive: wrong # args.", context
));
3015 if (!SIM
->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY
)->set_by_name(params
[1]))
3016 PARSE_ERR(("%s: display library '%s' not available", context
, params
[1]));
3017 if (num_params
== 3) {
3018 if (!strncmp(params
[2], "options=", 8)) {
3019 SIM
->get_param_string(BXPN_DISPLAYLIB_OPTIONS
)->set(¶ms
[2][8]);
3023 // Old timing options have been replaced by the 'clock' option
3024 else if (!strcmp(params
[0], "pit")) // Deprecated
3026 PARSE_ERR(("ERROR: pit directive is DEPRECATED, use clock: instead"));
3028 else if (!strcmp(params
[0], "time0")) // Deprectated
3030 PARSE_ERR(("ERROR: time0 directive is DEPRECATED, use clock: instead"));
3032 // user-defined options handled by registered functions
3033 else if ((i
= SIM
->find_user_option(params
[0])) >= 0)
3035 return SIM
->parse_user_option(i
, context
, num_params
, ¶ms
[0]);
3039 PARSE_ERR(( "%s: directive '%s' not understood", context
, params
[0]));
3045 static char *fdtypes
[] = {
3046 "none", "1_2", "1_44", "2_88", "720k", "360k", "160k", "180k", "320k"
3049 int bx_write_floppy_options(FILE *fp
, int drive
)
3051 char path
[80], type
[80], status
[80];
3053 BX_ASSERT(drive
==0 || drive
==1);
3054 sprintf(path
, "floppy.%d.path", drive
);
3055 sprintf(type
, "floppy.%d.type", drive
);
3056 sprintf(status
, "floppy.%d.status", drive
);
3057 if (SIM
->get_param_enum(type
)->get() == BX_FLOPPY_NONE
) {
3058 fprintf(fp
, "# no floppy%c\n", (char)'a'+drive
);
3061 BX_ASSERT(SIM
->get_param_enum(type
)->get() > BX_FLOPPY_NONE
&&
3062 SIM
->get_param_enum(type
)->get() <= BX_FLOPPY_LAST
);
3063 fprintf(fp
, "floppy%c: %s=\"%s\", status=%s\n",
3065 fdtypes
[SIM
->get_param_enum(type
)->get() - BX_FLOPPY_NONE
],
3066 SIM
->get_param_string(path
)->getptr(),
3067 SIM
->get_param_enum(status
)->get_selected());
3071 int bx_write_ata_options(FILE *fp
, Bit8u channel
, bx_list_c
*base
)
3073 fprintf(fp
, "ata%d: enabled=%d", channel
, SIM
->get_param_bool("enabled", base
)->get());
3075 if (SIM
->get_param_bool("enabled", base
)->get()) {
3076 fprintf(fp
, ", ioaddr1=0x%x, ioaddr2=0x%x, irq=%d", SIM
->get_param_num("ioaddr1", base
)->get(),
3077 SIM
->get_param_num("ioaddr2", base
)->get(), SIM
->get_param_num("irq", base
)->get());
3084 int bx_write_atadevice_options(FILE *fp
, Bit8u channel
, Bit8u drive
, bx_list_c
*base
)
3086 if (SIM
->get_param_bool("present", base
)->get()) {
3087 fprintf(fp
, "ata%d-%s: ", channel
, drive
==0?"master":"slave");
3089 if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_DISK
) {
3090 fprintf(fp
, "type=disk");
3092 fprintf(fp
, ", mode=%s", SIM
->get_param_enum("mode", base
)->get_selected());
3093 fprintf(fp
, ", translation=%s", SIM
->get_param_enum("translation", base
)->get_selected());
3094 fprintf(fp
, ", path=\"%s\", cylinders=%d, heads=%d, spt=%d",
3095 SIM
->get_param_string("path", base
)->getptr(),
3096 SIM
->get_param_num("cylinders", base
)->get(),
3097 SIM
->get_param_num("heads", base
)->get(),
3098 SIM
->get_param_num("spt", base
)->get());
3100 if (SIM
->get_param_string("journal", base
)->getptr() != NULL
)
3101 if (strcmp(SIM
->get_param_string("journal", base
)->getptr(), "") != 0)
3102 fprintf(fp
, ", journal=\"%s\"", SIM
->get_param_string("journal", base
)->getptr());
3104 } else if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_CDROM
) {
3105 fprintf(fp
, "type=cdrom, path=\"%s\", status=%s",
3106 SIM
->get_param_string("path", base
)->getptr(),
3107 SIM
->get_param_enum("status", base
)->get_selected());
3110 fprintf(fp
, ", biosdetect=%s", SIM
->get_param_enum("biosdetect", base
)->get_selected());
3112 if (SIM
->get_param_string("model", base
)->getptr()>0) {
3113 fprintf(fp
, ", model=\"%s\"", SIM
->get_param_string("model", base
)->getptr());
3121 int bx_write_parport_options(FILE *fp
, bx_list_c
*base
, int n
)
3123 fprintf(fp
, "parport%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3124 if (SIM
->get_param_bool("enabled", base
)->get()) {
3125 fprintf(fp
, ", file=\"%s\"", SIM
->get_param_string("outfile", base
)->getptr());
3131 int bx_write_serial_options(FILE *fp
, bx_list_c
*base
, int n
)
3133 fprintf(fp
, "com%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3134 if (SIM
->get_param_bool("enabled", base
)->get()) {
3135 fprintf(fp
, ", mode=%s", SIM
->get_param_enum("mode", base
)->get_selected());
3136 fprintf(fp
, ", dev=\"%s\"", SIM
->get_param_string("dev", base
)->getptr());
3142 int bx_write_usb_options(FILE *fp
, bx_list_c
*base
, int n
)
3144 fprintf(fp
, "usb%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3145 if (SIM
->get_param_bool("enabled", base
)->get()) {
3146 fprintf(fp
, ", port1=%s", SIM
->get_param_string("port1", base
)->getptr());
3147 fprintf(fp
, ", port2=%s", SIM
->get_param_string("port2", base
)->getptr());
3153 int bx_write_pnic_options(FILE *fp
, bx_list_c
*base
)
3155 fprintf (fp
, "pnic: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3156 if (SIM
->get_param_bool("enabled", base
)->get()) {
3157 char *ptr
= SIM
->get_param_string("macaddr", base
)->getptr();
3158 fprintf (fp
, ", mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s",
3159 (unsigned int)(0xff & ptr
[0]),
3160 (unsigned int)(0xff & ptr
[1]),
3161 (unsigned int)(0xff & ptr
[2]),
3162 (unsigned int)(0xff & ptr
[3]),
3163 (unsigned int)(0xff & ptr
[4]),
3164 (unsigned int)(0xff & ptr
[5]),
3165 SIM
->get_param_enum("ethmod", base
)->get_selected(),
3166 SIM
->get_param_string("ethdev", base
)->getptr(),
3167 SIM
->get_param_string("script", base
)->getptr());
3173 int bx_write_ne2k_options (FILE *fp
, bx_list_c
*base
)
3175 fprintf(fp
, "ne2k: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3176 if (SIM
->get_param_bool("enabled", base
)->get()) {
3177 char *ptr
= SIM
->get_param_string("macaddr", base
)->getptr();
3178 fprintf(fp
, ", ioaddr=0x%x, irq=%d, mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s",
3179 SIM
->get_param_num("ioaddr", base
)->get(),
3180 SIM
->get_param_num("irq", base
)->get(),
3181 (unsigned int)(0xff & ptr
[0]),
3182 (unsigned int)(0xff & ptr
[1]),
3183 (unsigned int)(0xff & ptr
[2]),
3184 (unsigned int)(0xff & ptr
[3]),
3185 (unsigned int)(0xff & ptr
[4]),
3186 (unsigned int)(0xff & ptr
[5]),
3187 SIM
->get_param_enum("ethmod", base
)->get_selected(),
3188 SIM
->get_param_string("ethdev", base
)->getptr(),
3189 SIM
->get_param_string("script", base
)->getptr());
3195 int bx_write_sb16_options (FILE *fp
, bx_list_c
*base
)
3197 fprintf(fp
, "sb16: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3198 if (SIM
->get_param_bool("enabled", base
)->get()) {
3199 fprintf(fp
, ", midimode=%d, midi=%s, wavemode=%d, wave=%s, loglevel=%d, log=%s, dmatimer=%d",
3200 SIM
->get_param_num("midimode", base
)->get(),
3201 SIM
->get_param_string("midifile", base
)->getptr(),
3202 SIM
->get_param_num("wavemode", base
)->get(),
3203 SIM
->get_param_string("wavefile", base
)->getptr(),
3204 SIM
->get_param_num("loglevel", base
)->get(),
3205 SIM
->get_param_string("logfile", base
)->getptr(),
3206 SIM
->get_param_num("dmatimer", base
)->get());
3212 int bx_write_loader_options(FILE *fp
)
3214 if (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSNone
) {
3215 fprintf(fp
, "# no loader\n");
3218 BX_ASSERT((SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSLinux
) ||
3219 (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSNullKernel
));
3220 fprintf (fp
, "load32bitOSImage: os=%s, path=%s, iolog=%s, initrd=%s\n",
3221 (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSLinux
) ? "linux" : "nullkernel",
3222 SIM
->get_param_string(BXPN_LOAD32BITOS_PATH
)->getptr(),
3223 SIM
->get_param_string(BXPN_LOAD32BITOS_IOLOG
)->getptr(),
3224 SIM
->get_param_string(BXPN_LOAD32BITOS_INITRD
)->getptr());
3228 int bx_write_clock_cmos_options(FILE *fp
)
3230 fprintf(fp
, "clock: ");
3232 switch (SIM
->get_param_enum(BXPN_CLOCK_SYNC
)->get()) {
3233 case BX_CLOCK_SYNC_NONE
:
3234 fprintf(fp
, "sync=none");
3236 case BX_CLOCK_SYNC_REALTIME
:
3237 fprintf(fp
, "sync=realtime");
3239 case BX_CLOCK_SYNC_SLOWDOWN
:
3240 fprintf(fp
, "sync=slowdown");
3242 case BX_CLOCK_SYNC_BOTH
:
3243 fprintf(fp
, "sync=both");
3246 BX_PANIC(("Unknown value for sync method"));
3249 switch (SIM
->get_param_num(BXPN_CLOCK_TIME0
)->get()) {
3251 case BX_CLOCK_TIME0_LOCAL
:
3252 fprintf(fp
, ", time0=local");
3254 case BX_CLOCK_TIME0_UTC
:
3255 fprintf(fp
, ", time0=utc");
3258 fprintf(fp
, ", time0=%u", SIM
->get_param_num(BXPN_CLOCK_TIME0
)->get());
3263 if (strlen(SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr()) > 0) {
3264 fprintf(fp
, "cmosimage: file=%s, ", SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr());
3265 fprintf(fp
, "rtc_init=%s", SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->get()?"image":"time0");
3267 fprintf(fp
, "# no cmosimage\n");
3272 int bx_write_log_options(FILE *fp
, bx_list_c
*base
)
3274 fprintf(fp
, "log: %s\n", SIM
->get_param_string("filename", base
)->getptr());
3275 fprintf(fp
, "logprefix: %s\n", SIM
->get_param_string("prefix", base
)->getptr());
3276 fprintf(fp
, "debugger_log: %s\n", SIM
->get_param_string("debugger_filename", base
)->getptr());
3277 fprintf(fp
, "panic: action=%s\n",
3278 io
->getaction(logfunctions::get_default_action (LOGLEV_PANIC
)));
3279 fprintf(fp
, "error: action=%s\n",
3280 io
->getaction(logfunctions::get_default_action (LOGLEV_ERROR
)));
3281 fprintf(fp
, "info: action=%s\n",
3282 io
->getaction(logfunctions::get_default_action (LOGLEV_INFO
)));
3283 fprintf(fp
, "debug: action=%s\n",
3284 io
->getaction(logfunctions::get_default_action (LOGLEV_DEBUG
)));
3285 fprintf(fp
, "pass: action=%s\n",
3286 io
->getaction(logfunctions::get_default_action (LOGLEV_PASS
)));
3290 int bx_write_keyboard_options(FILE *fp
)
3292 fprintf(fp
, "keyboard_type: %s\n", SIM
->get_param_enum(BXPN_KBD_TYPE
)->get_selected());
3293 fprintf(fp
, "keyboard_serial_delay: %u\n", SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->get());
3294 fprintf(fp
, "keyboard_paste_delay: %u\n", SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->get());
3295 fprintf(fp
, "keyboard_mapping: enabled=%d, map=%s\n",
3296 SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->get(),
3297 SIM
->get_param_string(BXPN_KBD_KEYMAP
)->getptr());
3298 fprintf(fp
, "user_shortcut: keys=%s\n", SIM
->get_param_string(BXPN_USER_SHORTCUT
)->getptr());
3305 // -2: already exists, and overwrite was off
3306 int bx_write_configuration(const char *rc
, int overwrite
)
3309 char *strptr
, tmppath
[80], tmpaddr
[80], tmpdev
[80];
3311 BX_INFO(("write current configuration to %s", rc
));
3312 // check if it exists. If so, only proceed if overwrite is set.
3313 FILE *fp
= fopen(rc
, "r");
3316 if (!overwrite
) return -2;
3318 fp
= fopen(rc
, "w");
3319 if (fp
== NULL
) return -1;
3320 // finally it's open and we can start writing.
3321 fprintf(fp
, "# configuration file generated by Bochs\n");
3322 fprintf(fp
, "config_interface: %s\n", SIM
->get_param_enum(BXPN_SEL_CONFIG_INTERFACE
)->get_selected());
3323 fprintf(fp
, "display_library: %s", SIM
->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY
)->get_selected());
3324 strptr
= SIM
->get_param_string(BXPN_DISPLAYLIB_OPTIONS
)->getptr();
3325 if (strlen(strptr
) > 0)
3326 fprintf(fp
, ", options=\"%s\"\n", strptr
);
3329 fprintf(fp
, "megs: %d\n", SIM
->get_param_num(BXPN_MEM_SIZE
)->get());
3330 strptr
= SIM
->get_param_string(BXPN_ROM_PATH
)->getptr();
3331 if (strlen(strptr
) > 0) {
3332 fprintf(fp
, "romimage: file=\"%s\"", strptr
);
3333 if (SIM
->get_param_num(BXPN_ROM_ADDRESS
)->get() != 0)
3334 fprintf(fp
, ", address=0x%08x\n", (unsigned int) SIM
->get_param_num(BXPN_ROM_ADDRESS
)->get());
3339 fprintf(fp
, "# no romimage\n");
3341 strptr
= SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->getptr();
3342 if (strlen(strptr
) > 0)
3343 fprintf(fp
, "vgaromimage: file=\"%s\"\n", strptr
);
3345 fprintf(fp
, "# no vgaromimage\n");
3346 fprintf(fp
, "boot: %s", SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get_selected());
3347 for (i
=1; i
<3; i
++) {
3348 sprintf(tmppath
, "boot_params.boot_drive%d", i
+1);
3349 if (SIM
->get_param_enum(tmppath
)->get() != BX_BOOT_NONE
) {
3350 fprintf(fp
, ", %s", SIM
->get_param_enum(tmppath
)->get_selected());
3354 fprintf(fp
, "floppy_bootsig_check: disabled=%d\n", SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->get());
3355 // it would be nice to put this type of function as methods on
3356 // the structs like bx_floppy_options::print or something.
3357 bx_write_floppy_options(fp
, 0);
3358 bx_write_floppy_options(fp
, 1);
3359 for (Bit8u channel
=0; channel
<BX_MAX_ATA_CHANNEL
; channel
++) {
3360 sprintf(tmppath
, "ata.%d", channel
);
3361 base
= (bx_list_c
*) SIM
->get_param(tmppath
);
3362 bx_write_ata_options(fp
, channel
, (bx_list_c
*) SIM
->get_param("resources", base
));
3363 bx_write_atadevice_options(fp
, channel
, 0, (bx_list_c
*) SIM
->get_param("master", base
));
3364 bx_write_atadevice_options(fp
, channel
, 1, (bx_list_c
*) SIM
->get_param("slave", base
));
3366 for (i
=0; i
<BX_N_OPTROM_IMAGES
; i
++) {
3367 sprintf(tmppath
, "memory.optrom.%d.path", i
+1);
3368 sprintf(tmpaddr
, "memory.optrom.%d.addr", i
+1);
3369 strptr
= SIM
->get_param_string(tmppath
)->getptr();
3370 if (strlen(strptr
) > 0)
3371 fprintf(fp
, "optromimage%d: file=\"%s\", address=0x%05x\n", i
+1, strptr
,
3372 (unsigned int)SIM
->get_param_num(tmpaddr
)->get());
3374 for (i
=0; i
<BX_N_OPTRAM_IMAGES
; i
++) {
3375 sprintf(tmppath
, "memory.optram.%d.path", i
+1);
3376 sprintf(tmpaddr
, "memory.optram.%d.addr", i
+1);
3377 strptr
= SIM
->get_param_string(tmppath
)->getptr();
3378 if (strlen(strptr
) > 0)
3379 fprintf(fp
, "optramimage%d: file=\"%s\", address=0x%05x\n", i
+1, strptr
,
3380 (unsigned int)SIM
->get_param_num(tmpaddr
)->get());
3383 for (i
=0; i
<BX_N_PARALLEL_PORTS
; i
++) {
3384 sprintf(tmpdev
, "ports.parallel.%d", i
+1);
3385 base
= (bx_list_c
*) SIM
->get_param(tmpdev
);
3386 bx_write_parport_options(fp
, base
, i
+1);
3389 for (i
=0; i
<BX_N_SERIAL_PORTS
; i
++) {
3390 sprintf(tmpdev
, "ports.serial.%d", i
+1);
3391 base
= (bx_list_c
*) SIM
->get_param(tmpdev
);
3392 bx_write_serial_options(fp
, base
, i
+1);
3394 base
= (bx_list_c
*) SIM
->get_param("ports.usb.1");
3395 bx_write_usb_options(fp
, base
, 1);
3397 fprintf(fp
, "i440fxsupport: enabled=%d",
3398 SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get());
3399 if (SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get()) {
3400 for (i
=0; i
<BX_N_PCI_SLOTS
; i
++) {
3401 sprintf(tmpdev
, "pci.slot.%d", i
+1);
3402 strptr
= SIM
->get_param_string(tmpdev
)->getptr();
3403 if (strlen(strptr
) > 0) {
3404 fprintf(fp
, ", slot%d=%s", i
+1, strptr
);
3409 if (SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->get() != 0xffff) {
3410 fprintf(fp
, "pcidev: vendor=0x%04x, device=0x%04x\n",
3411 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->get(),
3412 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->get());
3414 fprintf(fp
, "vga_update_interval: %u\n", SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->get());
3415 fprintf(fp
, "vga: extension=%s\n", SIM
->get_param_string(BXPN_VGA_EXTENSION
)->getptr());
3417 fprintf(fp
, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, reset_on_triple_fault=%d\n",
3418 SIM
->get_param_num(BXPN_CPU_NPROCESSORS
)->get(), SIM
->get_param_num(BXPN_CPU_NCORES
)->get(),
3419 SIM
->get_param_num(BXPN_CPU_NTHREADS
)->get(), SIM
->get_param_num(BXPN_IPS
)->get(),
3420 SIM
->get_param_num(BXPN_SMP_QUANTUM
)->get(),
3421 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->get());
3423 fprintf(fp
, "cpu: count=1, ips=%u, reset_on_triple_fault=%d\n",
3424 SIM
->get_param_num(BXPN_IPS
)->get(), SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->get());
3426 fprintf(fp
, "text_snapshot_check: enabled=%d\n", SIM
->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK
)->get());
3427 fprintf(fp
, "private_colormap: enabled=%d\n", SIM
->get_param_bool(BXPN_PRIVATE_COLORMAP
)->get());
3429 fprintf(fp
, "fullscreen: enabled=%d\n", SIM
->get_param_bool(BXPN_FULLSCREEN
)->get());
3430 fprintf(fp
, "screenmode: name=\"%s\"\n", SIM
->get_param_string(BXPN_SCREENMODE
)->getptr());
3432 bx_write_clock_cmos_options(fp
);
3433 bx_write_ne2k_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_NE2K
));
3434 bx_write_pnic_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_PNIC
));
3435 bx_write_sb16_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_SB16
));
3436 bx_write_loader_options(fp
);
3437 bx_write_log_options(fp
, (bx_list_c
*) SIM
->get_param("log"));
3438 bx_write_keyboard_options(fp
);
3439 fprintf(fp
, "mouse: enabled=%d, type=%s\n",
3440 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
)->get(),
3441 SIM
->get_param_enum(BXPN_MOUSE_TYPE
)->get_selected());
3442 SIM
->save_user_options(fp
);
3447 #endif // #if BX_PROVIDE_MAIN