1 /////////////////////////////////////////////////////////////////////////
2 // $Id: config.cc,v 1.125 2007/12/06 22:21:40 sshwarts 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 const char *get_builtin_variable(const 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 const 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 new bx_param_bool_c(menu
,
366 "Restore Bochs session",
367 "Restore Bochs session",
369 new bx_param_string_c(menu
,
371 "Path to data for restore",
372 "Path to data for restore",
376 // benchmarking mode, set by command line arg
377 new bx_param_num_c(menu
,
380 "set benchmark mode",
381 0, BX_MAX_BIT32U
, 0);
383 // subtree for special menus
384 bx_list_c
*special_menus
= new bx_list_c(root_param
, "menu", "");
387 #define BX_CPU_PROCESSORS_LIMIT 8
388 #define BX_CPU_CORES_LIMIT 4
389 #define BX_CPU_HT_THREADS_LIMIT 4
391 #define BX_CPU_PROCESSORS_LIMIT 1
392 #define BX_CPU_CORES_LIMIT 1
393 #define BX_CPU_HT_THREADS_LIMIT 1
397 bx_list_c
*cpu_param
= new bx_list_c(root_param
, "cpu", "CPU Options");
400 bx_param_num_c
*nprocessors
= new bx_param_num_c(cpu_param
,
401 "n_processors", "Number of CPUs in SMP mode",
402 "Sets the number of CPUs for multiprocessor emulation",
403 1, BX_CPU_PROCESSORS_LIMIT
,
405 nprocessors
->set_enabled(BX_CPU_PROCESSORS_LIMIT
> 1);
406 bx_param_num_c
*ncores
= new bx_param_num_c(cpu_param
,
407 "n_cores", "Number of processor cores in each CPU in SMP mode",
408 "Sets the number of processor cores per CPU for multiprocessor emulation",
409 1, BX_CPU_CORES_LIMIT
,
411 ncores
->set_enabled(BX_CPU_CORES_LIMIT
> 1);
412 bx_param_num_c
*nthreads
= new bx_param_num_c(cpu_param
,
413 "n_threads", "Number of HT threads per each process core in SMP mode",
414 "Sets the number of HT (Intel(R) HyperThreading Technology) threads per core for multiprocessor emulation",
415 1, BX_CPU_HT_THREADS_LIMIT
,
417 nthreads
->set_enabled(BX_CPU_HT_THREADS_LIMIT
> 1);
418 new bx_param_num_c(cpu_param
,
419 "ips", "Emulated instructions per second (IPS)",
420 "Emulated instructions per second, used to calibrate bochs emulated time with wall clock time.",
424 new bx_param_num_c(cpu_param
,
425 "quantum", "Quantum ticks in SMP simulation",
426 "Maximum amount of instructions allowed to execute before returning control to another CPU.",
427 BX_SMP_QUANTUM_MIN
, BX_SMP_QUANTUM_MAX
,
430 new bx_param_bool_c(cpu_param
,
431 "reset_on_triple_fault", "Enable CPU reset on triple fault",
432 "Enable CPU reset if triple fault occured (highly recommended)",
434 cpu_param
->get_options()->set(menu
->SHOW_PARENT
);
437 bx_list_c
*memory
= new bx_list_c(root_param
, "memory", "Memory Options");
438 bx_list_c
*stdmem
= new bx_list_c(memory
, "standard", "Standard Options");
439 bx_list_c
*optrom
= new bx_list_c(memory
, "optrom", "Optional ROM Images");
440 bx_list_c
*optram
= new bx_list_c(memory
, "optram", "Optional RAM Images");
441 bx_list_c
*ram
= new bx_list_c(stdmem
, "ram", "");
442 bx_list_c
*rom
= new bx_list_c(stdmem
, "rom", "");
443 bx_list_c
*vgarom
= new bx_list_c(stdmem
, "vgarom", "");
445 // memory options (ram & rom)
446 bx_param_num_c
*ramsize
= new bx_param_num_c(ram
,
448 "Memory size (megabytes)",
449 "Amount of RAM in megabytes",
451 BX_DEFAULT_MEM_MEGS
);
452 ramsize
->set_ask_format("Enter memory size (MB): [%d] ");
454 ramsize
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
457 path
= new bx_param_filename_c(rom
,
460 "Pathname of ROM image to load",
461 "", BX_PATHNAME_LEN
);
462 path
->set_format("Name of ROM BIOS image: %s");
463 sprintf(name
, "%s/BIOS-bochs-latest", (char *)get_builtin_variable("BXSHARE"));
464 path
->set_initial_val(name
);
465 bx_param_num_c
*romaddr
= new bx_param_num_c(rom
,
468 "The address at which the ROM image should be loaded",
471 romaddr
->set_base(16);
472 romaddr
->set_format("0x%05x");
473 romaddr
->set_long_format("ROM BIOS address: 0x%05x");
475 path
= new bx_param_filename_c(vgarom
,
478 "Pathname of VGA ROM image to load",
479 "", BX_PATHNAME_LEN
);
480 path
->set_format("Name of VGA BIOS image: %s");
481 sprintf(name
, "%s/VGABIOS-lgpl-latest", get_builtin_variable("BXSHARE"));
482 path
->set_initial_val(name
);
484 bx_param_num_c
*optaddr
;
486 for (i
=0; i
<BX_N_OPTROM_IMAGES
; i
++) {
487 sprintf(name
, "%d", i
+1);
488 sprintf(descr
, "Pathname of optional ROM image #%d to load", i
+1);
489 sprintf(label
, "Optional ROM image #%d", i
+1);
490 bx_list_c
*optnum1
= new bx_list_c(optrom
, name
, label
);
491 path
= new bx_param_filename_c(optnum1
,
495 "", BX_PATHNAME_LEN
);
496 sprintf(label
, "Name of optional ROM image #%d", i
+1);
497 strcat(label
, " : %s");
498 path
->set_format(strdup(label
));
499 sprintf(descr
, "The address at which the optional ROM image #%d should be loaded", i
+1);
500 optaddr
= new bx_param_num_c(optnum1
,
506 optaddr
->set_base(16);
507 optaddr
->set_format("0x%05x");
508 sprintf(label
, "Optional ROM #%d address:", i
+1);
509 strcat(label
, " 0x%05x");
510 optaddr
->set_long_format(strdup(label
));
511 optnum1
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
513 optrom
->get_options()->set(bx_list_c::SHOW_PARENT
);
515 for (i
=0; i
<BX_N_OPTRAM_IMAGES
; i
++) {
516 sprintf(name
, "%d", i
+1);
517 sprintf(descr
, "Pathname of optional RAM image #%d to load", i
+1);
518 sprintf(label
, "Optional RAM image #%d", i
+1);
519 bx_list_c
*optnum2
= new bx_list_c(optram
, name
, label
);
520 path
= new bx_param_filename_c(optnum2
,
524 "", BX_PATHNAME_LEN
);
525 sprintf(label
, "Name of optional RAM image #%d", i
+1);
526 strcat(label
, " : %s");
527 path
->set_format(strdup(label
));
528 sprintf(descr
, "The address at which the optional RAM image #%d should be loaded", i
+1);
529 optaddr
= new bx_param_num_c(optnum2
,
535 optaddr
->set_base(16);
536 optaddr
->set_format("0x%05x");
537 sprintf(label
, "Optional RAM #%d address:", i
+1);
538 strcat(label
, " 0x%05x");
539 optaddr
->set_long_format(strdup(label
));
540 optnum2
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
542 optrom
->get_options()->set(bx_list_c::SHOW_PARENT
);
543 memory
->get_options()->set(bx_list_c::USE_TAB_WINDOW
);
545 bx_param_c
*memory_init_list
[] = {
546 SIM
->get_param(BXPN_MEM_SIZE
),
547 SIM
->get_param(BXPN_ROM_PATH
),
548 SIM
->get_param(BXPN_ROM_ADDRESS
),
549 SIM
->get_param(BXPN_VGA_ROM_PATH
),
550 SIM
->get_param("memory.optrom"),
551 SIM
->get_param("memory.optram"),
554 menu
= new bx_list_c(special_menus
, "memory", "Bochs Memory Options", memory_init_list
);
555 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
557 // clock & cmos subtree
558 bx_list_c
*clock_cmos
= new bx_list_c(root_param
, "clock_cmos", "Clock & CMOS Options");
560 // clock & cmos options
561 bx_param_enum_c
*clock_sync
= new bx_param_enum_c(clock_cmos
,
562 "clock_sync", "Synchronisation method",
563 "Host to guest time synchronization method",
567 bx_param_num_c
*time0
= new bx_param_num_c(clock_cmos
,
569 "Initial CMOS time for Bochs\n(1:localtime, 2:utc, other:time in seconds)",
570 "Initial time for Bochs CMOS clock, used if you really want two runs to be identical",
572 BX_CLOCK_TIME0_LOCAL
);
574 bx_list_c
*cmosimage
= new bx_list_c(clock_cmos
, "cmosimage", "CMOS Image Options");
575 bx_param_bool_c
*use_cmosimage
= new bx_param_bool_c(cmosimage
,
576 "enabled", "Use a CMOS image",
577 "Controls the usage of a CMOS image",
579 path
= new bx_param_filename_c(cmosimage
,
580 "path", "Pathname of CMOS image",
581 "Pathname of CMOS image",
582 "", BX_PATHNAME_LEN
);
583 bx_param_bool_c
*rtc_init
= new bx_param_bool_c(cmosimage
,
584 "rtc_init", "Initialize RTC from image",
585 "Controls whether to initialize the RTC with values stored in the image",
587 deplist
= new bx_list_c(NULL
, 2);
589 deplist
->add(rtc_init
);
590 use_cmosimage
->set_dependent_list(deplist
);
592 time0
->set_ask_format("Enter Initial CMOS time (1:localtime, 2:utc, other:time in seconds): [%d] ");
593 clock_sync
->set_ask_format("Enter Synchronisation method: [%s] ");
594 clock_cmos
->get_options()->set(bx_list_c::SHOW_PARENT
);
595 cmosimage
->get_options()->set(bx_list_c::SHOW_PARENT
);
598 bx_list_c
*pci
= new bx_list_c(root_param
, "pci", "PCI Options");
601 bx_param_c
*pci_deps_list
[1+BX_N_PCI_SLOTS
];
602 bx_param_c
**pci_deps_ptr
= &pci_deps_list
[0];
604 bx_param_bool_c
*i440fx_support
= new bx_param_bool_c(pci
,
606 "Enable i440FX PCI Support",
607 "Controls whether to emulate the i440FX PCI chipset",
610 bx_list_c
*slot
= new bx_list_c(pci
, "slot", "PCI Slots");
611 *pci_deps_ptr
++ = slot
;
612 for (i
=0; i
<BX_N_PCI_SLOTS
; i
++) {
613 sprintf(name
, "%d", i
+1);
614 sprintf (descr
, "Name of the device connected to PCI slot #%d", i
+1);
615 sprintf (label
, "PCI slot #%d device", i
+1);
616 bx_param_string_c
*devname
= new bx_param_string_c(slot
,
620 "", BX_PATHNAME_LEN
);
622 *pci_deps_ptr
++ = devname
;
625 bx_list_c
*pcidev
= new bx_list_c(pci
, "pcidev", "Host PCI Device Mapping");
626 *pci_deps_ptr
++ = pcidev
;
627 bx_param_num_c
*pcivid
= new bx_param_num_c(pcidev
,
630 "The vendor ID of the host PCI device to map",
632 0xffff); // vendor id 0xffff = no pci device present
633 pcivid
->set_base(16);
634 pcivid
->set_format("0x%04x");
635 pcivid
->set_long_format("PCI Vendor ID: 0x%04x");
636 #if BX_SUPPORT_PCIDEV
637 *pci_deps_ptr
++ = pcivid
;
639 pcivid
->set_enabled(0);
641 bx_param_num_c
*pcidid
= new bx_param_num_c(pcidev
,
644 "The device ID of the host PCI device to map",
647 pcidid
->set_base(16);
648 pcidid
->set_format("0x%04x");
649 pcidid
->set_long_format("PCI Device ID: 0x%04x");
650 #if BX_SUPPORT_PCIDEV
651 *pci_deps_ptr
++ = pcidid
;
653 pcidid
->set_enabled(0);
655 // add final NULL at the end, and build the menu
656 *pci_deps_ptr
= NULL
;
657 i440fx_support
->set_dependent_list(new bx_list_c(NULL
, "", "", pci_deps_list
));
658 pci
->get_options()->set(bx_list_c::SHOW_PARENT
);
659 slot
->get_options()->set(bx_list_c::SHOW_PARENT
);
660 pcidev
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
663 bx_list_c
*display
= new bx_list_c(root_param
, "display", "Bochs Display & Interface Options", 7);
665 // this is a list of gui libraries that are known to be available at
666 // compile time. The one that is listed first will be the default,
667 // which is used unless the user overrides it on the command line or
668 // in a configuration file.
669 static const char *display_library_list
[] = {
708 bx_param_enum_c
*sel_displaylib
= new bx_param_enum_c(display
,
709 "display_library", "VGA Display Library",
710 "Select VGA Display Library",
711 display_library_list
,
714 sel_displaylib
->set_by_name(BX_DEFAULT_DISPLAY_LIBRARY
);
715 sel_displaylib
->set_ask_format("Choose which library to use for the Bochs display: [%s] ");
717 new bx_param_string_c(display
,
718 "displaylib_options", "Display Library options",
719 "Options passed to Display Library",
723 new bx_param_bool_c(display
,
724 "private_colormap", "Use a private colormap",
725 "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.",
728 bx_param_bool_c
*fullscreen
= new bx_param_bool_c(display
,
729 "fullscreen", "Use full screen mode",
730 "When enabled, bochs occupies the whole screen instead of just a window.",
732 bx_param_string_c
*screenmode
= new bx_param_string_c(display
,
736 "", BX_PATHNAME_LEN
);
737 screenmode
->set_handler(bx_param_string_handler
);
739 fullscreen
->set_enabled(0);
740 screenmode
->set_enabled(0);
743 bx_param_num_c
*vga_update_interval
= new bx_param_num_c(display
,
744 "vga_update_interval",
745 "VGA Update Interval",
746 "Number of microseconds between VGA updates",
749 vga_update_interval
->set_ask_format ("Type a new value for VGA update interval: [%d] ");
751 bx_param_string_c
*vga_extension
= new bx_param_string_c(display
,
754 "Name of the VGA extension",
755 "none", BX_PATHNAME_LEN
);
757 vga_extension
->set_initial_val("vbe");
758 #elif BX_SUPPORT_CLGD54XX
759 vga_extension
->set_initial_val("cirrus");
761 display
->get_options()->set(bx_list_c::SHOW_PARENT
);
763 // keyboard & mouse subtree
764 bx_list_c
*kbd_mouse
= new bx_list_c(root_param
, "keyboard_mouse", "Keyboard & Mouse Options");
765 bx_list_c
*keyboard
= new bx_list_c(kbd_mouse
, "keyboard", "Keyboard Options");
766 bx_list_c
*mouse
= new bx_list_c(kbd_mouse
, "mouse", "Mouse Options");
768 // keyboard & mouse options
769 type
= new bx_param_enum_c(keyboard
,
770 "type", "Keyboard type",
771 "Keyboard type reported by the 'identify keyboard' command",
775 type
->set_ask_format ("Enter keyboard type: [%s] ");
777 new bx_param_num_c(keyboard
,
778 "serial_delay", "Keyboard serial delay",
779 "Approximate time in microseconds that it takes one character to be transfered from the keyboard to controller over the serial path.",
782 new bx_param_num_c(keyboard
,
783 "paste_delay", "Keyboard paste delay",
784 "Approximate time in microseconds between attemps to paste characters to the keyboard controller.",
787 bx_param_bool_c
*use_kbd_mapping
= new bx_param_bool_c(keyboard
,
788 "use_mapping", "Use keyboard mapping",
789 "Controls whether to use the keyboard mapping feature",
791 bx_param_filename_c
*keymap
= new bx_param_filename_c(keyboard
,
792 "keymap", "Keymap filename",
793 "Pathname of the keymap file used",
794 "", BX_PATHNAME_LEN
);
795 deplist
= new bx_list_c(NULL
, 1);
796 deplist
->add(keymap
);
797 use_kbd_mapping
->set_dependent_list(deplist
);
799 bx_param_string_c
*user_shortcut
= new bx_param_string_c(keyboard
,
801 "Userbutton shortcut",
802 "Defines the keyboard shortcut to be sent when you press the 'user' button in the headerbar.",
804 user_shortcut
->set_runtime_param(1);
806 static const char *mouse_type_list
[] = {
810 #if BX_SUPPORT_BUSMOUSE
818 type
= new bx_param_enum_c(mouse
,
819 "type", "Mouse type",
820 "The mouse type can be one of these: 'none', 'ps2', 'imps2', 'serial', 'serial_wheel'"
821 #if BX_SUPPORT_BUSMOUSE
828 type
->set_ask_format("Choose the type of mouse [%s] ");
830 new bx_param_bool_c(mouse
,
831 "enabled", "Enable the mouse capture",
832 "Controls whether the mouse sends events to the guest. The hardware emulation is always enabled.",
834 kbd_mouse
->get_options()->set(bx_list_c::SHOW_PARENT
);
835 keyboard
->get_options()->set(bx_list_c::SHOW_PARENT
);
836 mouse
->get_options()->set(bx_list_c::SHOW_PARENT
);
838 // boot parameter subtree
839 bx_list_c
*boot_params
= new bx_list_c(root_param
, "boot_params", "Boot Options");
841 for (i
=0; i
<3; i
++) {
842 sprintf(name
, "boot_drive%d", i
+1);
843 sprintf(label
, "Boot drive #%d", i
+1);
844 sprintf(descr
, "Name of drive #%d in boot sequence (A, C or CD)", i
+1);
845 bx_param_enum_c
*bootdrive
= new bx_param_enum_c(boot_params
,
849 &bochs_bootdisk_names
[(i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
],
850 (i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
,
851 (i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
);
852 bootdrive
->set_ask_format("Boot from floppy drive, hard drive or cdrom ? [%s] ");
855 new bx_param_bool_c(boot_params
,
857 "Skip Floppy Boot Signature Check",
858 "Skips check for the 0xaa55 signature on floppy boot device.",
862 bx_list_c
*load32bitos
= new bx_list_c(boot_params
, "load32bitos", "32-bit OS Loader Hack");
863 bx_param_enum_c
*whichOS
= new bx_param_enum_c(load32bitos
,
865 "Which operating system?",
870 path
= new bx_param_filename_c(load32bitos
,
872 "Pathname of OS to load",
873 "Pathname of the 32-bit OS to load",
874 "", BX_PATHNAME_LEN
);
875 bx_param_filename_c
*iolog
= new bx_param_filename_c(load32bitos
,
877 "Pathname of I/O log file",
878 "I/O logfile used for initializing the hardware",
879 "", BX_PATHNAME_LEN
);
880 bx_param_filename_c
*initrd
= new bx_param_filename_c(load32bitos
,
882 "Pathname of initrd",
883 "Pathname of the initial ramdisk",
884 "", BX_PATHNAME_LEN
);
885 whichOS
->set_ask_format("Enter OS to load: [%s] ");
886 path
->set_ask_format("Enter pathname of OS: [%s]");
887 iolog
->set_ask_format("Enter pathname of I/O log: [%s] ");
888 initrd
->set_ask_format("Enter pathname of initrd: [%s] ");
889 load32bitos
->get_options()->set(menu
->SERIES_ASK
);
890 whichOS
->set_handler(bx_param_handler
);
891 whichOS
->set(Load32bitOSNone
);
892 boot_params
->get_options()->set(bx_list_c::SHOW_PARENT
);
895 bx_list_c
*floppy
= new bx_list_c(root_param
, "floppy", "Floppy Options");
896 bx_list_c
*floppya
= new bx_list_c(floppy
, "0", "Floppy Disk 0");
897 bx_list_c
*floppyb
= new bx_list_c(floppy
, "1", "Floppy Disk 1");
899 bx_param_enum_c
*devtype
;
901 path
= new bx_param_filename_c(floppya
,
903 "First floppy image/device",
904 "Pathname of first floppy image file or device. If you're booting from floppy, this should be a bootable floppy.",
905 "", BX_PATHNAME_LEN
);
906 path
->set_ask_format("Enter new filename, or 'none' for no disk: [%s] ");
907 path
->set_runtime_param(1);
909 devtype
= new bx_param_enum_c(floppya
,
911 "Type of floppy drive",
912 "Type of floppy drive",
916 devtype
->set_enabled(0); // hide devtype parameter
917 type
= new bx_param_enum_c(floppya
,
919 "Type of floppy disk",
920 "Type of floppy disk",
924 type
->set_ask_format("What type of floppy disk? (auto=detect) [%s] ");
925 type
->set_runtime_param(1);
927 status
= new bx_param_enum_c(floppya
,
929 "Is floppya inserted",
930 "Inserted or ejected",
934 status
->set_ask_format("Is the floppy inserted or ejected? [%s] ");
935 status
->set_runtime_param(1);
937 path
->set_handler(bx_param_string_handler
);
938 type
->set_handler(bx_param_handler
);
939 status
->set_handler(bx_param_handler
);
940 path
->set_initial_val("none");
941 floppya
->get_options()->set(bx_list_c::SERIES_ASK
);
943 path
= new bx_param_filename_c(floppyb
,
945 "Second floppy image/device",
946 "Pathname of second floppy image file or device.",
947 "", BX_PATHNAME_LEN
);
948 path
->set_ask_format("Enter new filename, or 'none' for no disk: [%s] ");
949 path
->set_runtime_param(1);
951 devtype
= new bx_param_enum_c(floppyb
,
953 "Type of floppy drive",
954 "Type of floppy drive",
958 devtype
->set_enabled(0); // hide devtype parameter
959 type
= new bx_param_enum_c(floppyb
,
961 "Type of floppy disk",
962 "Type of floppy disk",
966 type
->set_ask_format("What type of floppy disk? (auto=detect) [%s] ");
967 type
->set_runtime_param(1);
969 status
= new bx_param_enum_c(floppyb
,
971 "Is floppyb inserted",
972 "Inserted or ejected",
976 status
->set_ask_format("Is the floppy inserted or ejected? [%s] ");
977 status
->set_runtime_param(1);
979 path
->set_handler(bx_param_string_handler
);
980 type
->set_handler(bx_param_handler
);
981 status
->set_handler(bx_param_handler
);
982 path
->set_initial_val("none");
983 floppyb
->get_options()->set(bx_list_c::SERIES_ASK
);
984 floppy
->get_options()->set(bx_list_c::SHOW_PARENT
);
987 bx_list_c
*ata
= new bx_list_c(root_param
, "ata", "ATA/ATAPI Options");
990 const char *s_atachannel
[] = {
996 const char *s_atadevname
[2] = {
1000 const char *s_atadevice
[4][2] = {
1001 { "First HD/CD on channel 0",
1002 "Second HD/CD on channel 0" },
1003 { "First HD/CD on channel 1",
1004 "Second HD/CD on channel 1" },
1005 { "First HD/CD on channel 2",
1006 "Second HD/CD on channel 2" },
1007 { "First HD/CD on channel 3",
1008 "Second HD/CD on channel 3" }
1010 Bit16u ata_default_ioaddr1
[4] = {
1011 0x1f0, 0x170, 0x1e8, 0x168
1013 Bit16u ata_default_ioaddr2
[4] = {
1014 0x3f0, 0x370, 0x3e0, 0x360
1016 Bit8u ata_default_irq
[4] = {
1020 #define BXP_PARAMS_PER_ATA_DEVICE 12
1022 bx_list_c
*ata_menu
[BX_MAX_ATA_CHANNEL
];
1023 bx_list_c
*ata_res
[BX_MAX_ATA_CHANNEL
];
1026 for (channel
=0; channel
<BX_MAX_ATA_CHANNEL
; channel
++) {
1028 sprintf(name
, "%d", channel
);
1029 ata_menu
[channel
] = new bx_list_c(ata
, name
, s_atachannel
[channel
]);
1030 ata_menu
[channel
]->get_options()->set(bx_list_c::USE_TAB_WINDOW
);
1031 ata_res
[channel
] = new bx_list_c(ata_menu
[channel
], "resources", s_atachannel
[channel
], 8);
1032 ata_res
[channel
]->get_options()->set(bx_list_c::SERIES_ASK
);
1034 enabled
= new bx_param_bool_c(ata_res
[channel
],
1036 "Enable ATA channel",
1037 "Controls whether ata channel is installed or not",
1039 enabled
->set_ask_format("Channel is enabled: [%s] ");
1041 ioaddr
= new bx_param_num_c(ata_res
[channel
],
1044 "IO adress of ata command block",
1046 ata_default_ioaddr1
[channel
]);
1047 ioaddr
->set_base(16);
1048 ioaddr
->set_ask_format("Enter new ioaddr1: [0x%x] ");
1050 ioaddr2
= new bx_param_num_c(ata_res
[channel
],
1053 "IO adress of ata control block",
1055 ata_default_ioaddr2
[channel
]);
1056 ioaddr2
->set_base(16);
1057 ioaddr2
->set_ask_format("Enter new ioaddr2: [0x%x] ");
1059 irq
= new bx_param_num_c(ata_res
[channel
],
1062 "IRQ used by this ata channel",
1064 ata_default_irq
[channel
]);
1065 irq
->set_ask_format("Enter new IRQ: [%d] ");
1066 irq
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1068 // all items in the ata[channel] menu depend on the enabled flag.
1069 // The menu list is complete, but a few dependent_list items will
1070 // be added later. Use clone() to make a copy of the dependent_list
1071 // so that it can be changed without affecting the menu.
1072 enabled
->set_dependent_list(ata_res
[channel
]->clone());
1074 for (Bit8u slave
=0; slave
<2; slave
++) {
1075 menu
= new bx_list_c(ata_menu
[channel
],
1076 s_atadevname
[slave
],
1077 s_atadevice
[channel
][slave
],
1078 BXP_PARAMS_PER_ATA_DEVICE
+ 1);
1079 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1081 bx_param_bool_c
*present
= new bx_param_bool_c(menu
,
1083 "Enable this device",
1084 "Controls whether ata device is installed or not",
1086 present
->set_ask_format("Device is enabled: [%s] ");
1088 type
= new bx_param_enum_c(menu
,
1090 "Type of ATA device",
1091 "Type of ATA device (disk or cdrom)",
1092 atadevice_type_names
,
1094 BX_ATA_DEVICE_DISK
);
1095 type
->set_ask_format("Enter type of ATA device, disk or cdrom: [%s] ");
1097 path
= new bx_param_filename_c(menu
,
1099 "Path or physical device name",
1100 "Pathname of the image or physical device (cdrom only)",
1101 "", BX_PATHNAME_LEN
);
1102 path
->set_ask_format("Enter new filename: [%s] ");
1104 mode
= new bx_param_enum_c(menu
,
1106 "Type of disk image",
1107 "Mode of the ATA harddisk",
1108 atadevice_mode_names
,
1111 mode
->set_ask_format("Enter mode of ATA device, (flat, concat, etc.): [%s] ");
1113 status
= new bx_param_enum_c(menu
,
1116 "CD-ROM media status (inserted / ejected)",
1117 atadevice_status_names
,
1120 status
->set_ask_format("Is the device inserted or ejected? [%s] ");
1122 bx_param_filename_c
*journal
= new bx_param_filename_c(menu
,
1124 "Path of journal file",
1125 "Pathname of the journal file",
1126 "", BX_PATHNAME_LEN
);
1127 journal
->set_ask_format("Enter path of journal file: [%s]");
1129 bx_param_num_c
*cylinders
= new bx_param_num_c(menu
,
1132 "Number of cylinders",
1135 cylinders
->set_ask_format("Enter number of cylinders: [%d] ");
1136 bx_param_num_c
*heads
= new bx_param_num_c(menu
,
1142 heads
->set_ask_format("Enter number of heads: [%d] ");
1143 bx_param_num_c
*spt
= new bx_param_num_c(menu
,
1145 "Sectors per track",
1146 "Number of sectors per track",
1149 spt
->set_ask_format("Enter number of sectors per track: [%d] ");
1151 bx_param_string_c
*model
= new bx_param_string_c(menu
,
1154 "String returned by the 'identify device' command",
1155 "Generic 1234", 40);
1156 model
->set_ask_format("Enter new model name: [%s]");
1158 bx_param_enum_c
*biosdetect
= new bx_param_enum_c(menu
,
1161 "Type of bios detection",
1162 atadevice_biosdetect_names
,
1163 BX_ATA_BIOSDETECT_AUTO
,
1164 BX_ATA_BIOSDETECT_NONE
);
1165 biosdetect
->set_ask_format("Enter bios detection type: [%s]");
1167 bx_param_enum_c
*translation
= new bx_param_enum_c(menu
,
1170 "How the ata-disk translation is done by the bios",
1171 atadevice_translation_names
,
1172 BX_ATA_TRANSLATION_AUTO
,
1173 BX_ATA_TRANSLATION_NONE
);
1174 translation
->set_ask_format("Enter translation type: [%s]");
1176 // the menu and all items on it depend on the present flag
1177 present
->set_dependent_list(menu
->clone());
1178 // the present flag depends on the ATA channel's enabled flag
1179 enabled
->get_dependent_list()->add(present
);
1180 // the master/slave menu depends on the ATA channel's enabled flag
1181 enabled
->get_dependent_list()->add(menu
);
1183 type
->set_handler(bx_param_handler
);
1184 mode
->set_handler(bx_param_handler
);
1185 status
->set_handler(bx_param_handler
);
1186 path
->set_handler(bx_param_string_handler
);
1188 // Set the enable_hanlders
1189 journal
->set_enable_handler(bx_param_enable_handler
);
1190 status
->set_enable_handler(bx_param_enable_handler
);
1193 // Enable two ATA interfaces by default, disable the others.
1194 // Now that the dependence relationships are established, call set() on
1195 // the ata device present params to set all enables correctly.
1196 enabled
->set_initial_val(channel
<2);
1197 enabled
->set(channel
<2);
1201 bx_param_c
*disk_menu_init_list
[] = {
1202 SIM
->get_param(BXPN_FLOPPYA
),
1203 SIM
->get_param(BXPN_FLOPPYB
),
1204 SIM
->get_param(BXPN_ATA0_RES
),
1205 SIM
->get_param(BXPN_ATA0_MASTER
),
1206 SIM
->get_param(BXPN_ATA0_SLAVE
),
1207 #if BX_MAX_ATA_CHANNEL>1
1208 SIM
->get_param(BXPN_ATA1_RES
),
1209 SIM
->get_param(BXPN_ATA1_MASTER
),
1210 SIM
->get_param(BXPN_ATA1_SLAVE
),
1212 #if BX_MAX_ATA_CHANNEL>2
1213 SIM
->get_param(BXPN_ATA2_RES
),
1214 SIM
->get_param(BXPN_ATA2_MASTER
),
1215 SIM
->get_param(BXPN_ATA2_SLAVE
),
1217 #if BX_MAX_ATA_CHANNEL>3
1218 SIM
->get_param(BXPN_ATA3_RES
),
1219 SIM
->get_param(BXPN_ATA3_MASTER
),
1220 SIM
->get_param(BXPN_ATA3_SLAVE
),
1222 SIM
->get_param("boot_params"),
1225 menu
= new bx_list_c(special_menus
, "disk", "Bochs Disk Options", disk_menu_init_list
);
1226 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1229 bx_list_c
*ports
= new bx_list_c(root_param
, "ports", "Serial and Parallel Port Options");
1230 ports
->get_options()->set(bx_list_c::USE_TAB_WINDOW
| bx_list_c::SHOW_PARENT
);
1233 bx_list_c
*parallel
= new bx_list_c(ports
, "parallel", "Parallel Port Options");
1234 parallel
->get_options()->set(bx_list_c::SHOW_PARENT
);
1235 for (i
=0; i
<BX_N_PARALLEL_PORTS
; i
++) {
1236 sprintf(name
, "%d", i
+1);
1237 sprintf(label
, "Parallel Port %d", i
+1);
1238 menu
= new bx_list_c(parallel
, name
, label
);
1239 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1240 sprintf(label
, "Enable parallel port #%d", i
+1);
1241 sprintf(descr
, "Controls whether parallel port #%d is installed or not", i
+1);
1242 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
,
1243 (i
==0)? 1 : 0); // only enable #1 by default
1244 sprintf(label
, "Parallel port #%d output file", i
+1);
1245 sprintf(descr
, "Data written to parport#%d by the guest OS is written to this file", i
+1);
1246 path
= new bx_param_filename_c(menu
, "outfile", label
, descr
,
1247 "", BX_PATHNAME_LEN
);
1248 deplist
= new bx_list_c(NULL
, 1);
1250 enabled
->set_dependent_list(deplist
);
1253 static const char *serial_mode_list
[] = {
1264 bx_list_c
*serial
= new bx_list_c(ports
, "serial", "Serial Port Options");
1265 serial
->get_options()->set(bx_list_c::SHOW_PARENT
);
1266 for (i
=0; i
<BX_N_SERIAL_PORTS
; i
++) {
1267 sprintf(name
, "%d", i
+1);
1268 sprintf(label
, "Serial Port %d", i
+1);
1269 menu
= new bx_list_c(serial
, name
, label
);
1270 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1271 sprintf(label
, "Enable serial port #%d (COM%d)", i
+1, i
+1);
1272 sprintf(descr
, "Controls whether COM%d is installed or not", i
+1);
1273 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
,
1274 (i
==0)?1 : 0); // only enable the first by default
1275 sprintf(label
, "I/O mode of the serial device for COM%d", i
+1);
1276 sprintf(descr
, "The mode can be one these: 'null', 'file', 'term', 'raw', 'mouse', 'socket'");
1277 mode
= new bx_param_enum_c(menu
, "mode", label
, descr
,
1278 serial_mode_list
, 0, 0);
1279 mode
->set_ask_format("Choose I/O mode of the serial device [%s] ");
1280 sprintf(label
, "Pathname of the serial device for COM%d", i
+1);
1281 sprintf(descr
, "The path can be a real serial device or a pty (X/Unix only)");
1282 path
= new bx_param_filename_c(menu
, "dev", label
, descr
,
1283 "", BX_PATHNAME_LEN
);
1284 deplist
= new bx_list_c(NULL
, 2);
1287 enabled
->set_dependent_list(deplist
);
1290 bx_param_string_c
*port
;
1293 bx_list_c
*usb
= new bx_list_c(ports
, "usb", "USB Hub Options");
1294 usb
->get_options()->set(bx_list_c::SHOW_PARENT
);
1295 for (i
=0; i
<BX_N_USB_HUBS
; i
++) {
1296 sprintf(group
, "USB%d", i
+1);
1297 sprintf(name
, "%d", i
+1);
1298 sprintf(label
, "USB Hub %d", i
+1);
1299 menu
= new bx_list_c(usb
, name
, label
);
1300 menu
->set_enabled(BX_SUPPORT_PCIUSB
);
1301 sprintf(label
, "Enable usb hub #%d", i
+1);
1302 sprintf(descr
, "Controls whether %s is installed or not", group
);
1303 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
, 0);
1304 enabled
->set_enabled(BX_SUPPORT_PCIUSB
);
1305 port
= new bx_param_string_c(menu
,
1308 "Device connected to USB port #1",
1309 "", BX_PATHNAME_LEN
);
1310 port
->set_group(group
);
1311 port
= new bx_param_string_c(menu
,
1314 "Device connected to USB port #2",
1315 "", BX_PATHNAME_LEN
);
1316 port
->set_group(group
);
1317 enabled
->set_dependent_list(menu
->clone());
1321 bx_list_c
*network
= new bx_list_c(root_param
, "network", "Network Configuration");
1322 network
->get_options()->set(bx_list_c::USE_TAB_WINDOW
| bx_list_c::SHOW_PARENT
);
1324 // ne2k & pnic options
1325 static const char *eth_module_list
[] = {
1327 #if defined(ETH_LINUX)
1336 #if defined(ETH_WIN32)
1339 #if defined(ETH_FBSD)
1352 menu
= new bx_list_c(network
, "ne2k", "NE2000", 7);
1353 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1354 menu
->set_enabled(BX_SUPPORT_NE2K
);
1355 enabled
= new bx_param_bool_c(menu
,
1357 "Enable NE2K NIC emulation",
1358 "Enables the NE2K NIC emulation",
1360 enabled
->set_enabled(BX_SUPPORT_NE2K
);
1361 ioaddr
= new bx_param_num_c(menu
,
1364 "I/O base address of the emulated NE2K device",
1367 ioaddr
->set_base(16);
1368 irq
= new bx_param_num_c(menu
,
1371 "IRQ used by the NE2K device",
1374 irq
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1375 macaddr
= new bx_param_string_c(menu
,
1378 "MAC address of the NE2K device. Don't use an address of a machine on your net.",
1379 "\xfe\xfd\xde\xad\xbe\xef", 6);
1380 macaddr
->get_options()->set(bx_param_string_c::RAW_BYTES
);
1381 macaddr
->set_separator(':');
1382 ethmod
= new bx_param_enum_c(menu
,
1385 "Module used for the connection to the real net.",
1389 ethmod
->set_by_name("null");
1390 ethmod
->set_ask_format("Choose ethernet module for the NE2K [%s] ");
1391 ethdev
= new bx_param_string_c(menu
,
1394 "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
1395 "xl0", BX_PATHNAME_LEN
);
1396 path
= new bx_param_filename_c(menu
,
1398 "Device configuration script",
1399 "Name of the script that is executed after Bochs initializes the network interface (optional).",
1400 "none", BX_PATHNAME_LEN
);
1401 path
->set_ask_format("Enter new script name, or 'none': [%s] ");
1402 enabled
->set_dependent_list(menu
->clone());
1404 menu
= new bx_list_c(network
, "pnic", "PCI Pseudo NIC");
1405 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1406 menu
->set_enabled(BX_SUPPORT_PCIPNIC
);
1407 enabled
= new bx_param_bool_c(menu
,
1409 "Enable Pseudo NIC emulation",
1410 "Enables the Pseudo NIC emulation",
1412 enabled
->set_enabled(BX_SUPPORT_PCIPNIC
);
1413 macaddr
= new bx_param_string_c(menu
,
1416 "MAC address of the Pseudo NIC device. Don't use an address of a machine on your net.",
1417 "\xfe\xfd\xde\xad\xbe\xef", 6);
1418 macaddr
->get_options()->set(bx_param_string_c::RAW_BYTES
);
1419 macaddr
->set_separator(':');
1420 ethmod
= new bx_param_enum_c(menu
,
1423 "Module used for the connection to the real net.",
1427 ethmod
->set_by_name("null");
1428 ethmod
->set_ask_format("Choose ethernet module for the Pseudo NIC [%s]");
1429 ethdev
= new bx_param_string_c(menu
,
1432 "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
1433 "xl0", BX_PATHNAME_LEN
);
1434 path
= new bx_param_filename_c(menu
,
1436 "Device configuration script",
1437 "Name of the script that is executed after Bochs initializes the network interface (optional).",
1438 "none", BX_PATHNAME_LEN
);
1439 path
->set_ask_format("Enter new script name, or 'none': [%s] ");
1440 enabled
->set_dependent_list(menu
->clone());
1443 bx_list_c
*sound
= new bx_list_c(root_param
, "sound", "Sound Configuration");
1444 sound
->get_options()->set(bx_list_c::SHOW_PARENT
);
1445 menu
= new bx_list_c(sound
, "sb16", "SB16 Configuration", 8);
1446 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1447 menu
->set_enabled(BX_SUPPORT_SB16
);
1450 enabled
= new bx_param_bool_c(menu
,
1452 "Enable SB16 emulation",
1453 "Enables the SB16 emulation",
1455 enabled
->set_enabled(BX_SUPPORT_SB16
);
1456 bx_param_num_c
*midimode
= new bx_param_num_c(menu
,
1459 "Controls the MIDI output format.",
1462 bx_param_filename_c
*midifile
= new bx_param_filename_c(menu
,
1465 "The filename is where the MIDI data is sent. This can be device or just a file.",
1466 "", BX_PATHNAME_LEN
);
1467 bx_param_num_c
*wavemode
= new bx_param_num_c(menu
,
1470 "Controls the wave output format.",
1473 bx_param_filename_c
*wavefile
= new bx_param_filename_c(menu
,
1476 "This is the device/file where the wave output is stored",
1477 "", BX_PATHNAME_LEN
);
1478 bx_param_num_c
*loglevel
= new bx_param_num_c(menu
,
1481 "Controls how verbose the SB16 emulation is (0 = no log, 5 = all errors and infos).",
1484 bx_param_filename_c
*logfile
= new bx_param_filename_c(menu
,
1487 "The file to write the SB16 emulator messages to.",
1488 "", BX_PATHNAME_LEN
);
1489 bx_param_num_c
*dmatimer
= new bx_param_num_c(menu
,
1492 "Microseconds per second for a DMA cycle.",
1497 midimode
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1498 wavemode
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1499 loglevel
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1501 loglevel
->set_group("SB16");
1502 dmatimer
->set_group("SB16");
1503 enabled
->set_dependent_list(menu
->clone());
1504 deplist
= new bx_list_c(NULL
, 1);
1505 deplist
->add(midifile
);
1506 midimode
->set_dependent_list(deplist
);
1507 deplist
= new bx_list_c(NULL
, 1);
1508 deplist
->add(wavefile
);
1509 wavemode
->set_dependent_list(deplist
);
1510 deplist
= new bx_list_c(NULL
, 1);
1511 deplist
->add(logfile
);
1512 loglevel
->set_dependent_list(deplist
);
1514 // misc options subtree
1515 bx_list_c
*misc
= new bx_list_c(root_param
, "misc", "Configure Everything Else");
1516 misc
->get_options()->set(bx_list_c::SHOW_PARENT
);
1517 bx_param_num_c
*gdbstub_opt
;
1519 // text snapshot check panic
1520 new bx_param_bool_c(misc
,
1521 "text_snapshot_check",
1522 "Enable text snapshot check panic",
1523 "Enable panic when text on screen matches snapchk.txt.\nUseful for regression testing.\nIn win32, turns off CR/LF in snapshots and cuts.",
1526 menu
= new bx_list_c(misc
, "gdbstub", "GDB Stub Options");
1527 menu
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
1528 menu
->set_enabled(BX_GDBSTUB
);
1529 enabled
= new bx_param_bool_c(menu
,
1534 enabled
->set_enabled(BX_GDBSTUB
);
1535 gdbstub_opt
= new bx_param_num_c(menu
,
1538 "TCP/IP port for GDB stub",
1541 gdbstub_opt
= new bx_param_num_c(menu
,
1547 gdbstub_opt
= new bx_param_num_c(menu
,
1553 gdbstub_opt
= new bx_param_num_c(menu
,
1559 enabled
->set_dependent_list(menu
->clone());
1561 // log options subtree
1562 menu
= new bx_list_c(root_param
, "log", "Logfile Options");
1565 path
= new bx_param_filename_c(menu
,
1568 "Pathname of bochs log file",
1569 "-", BX_PATHNAME_LEN
);
1570 path
->set_ask_format("Enter log filename: [%s] ");
1572 bx_param_string_c
*prefix
= new bx_param_string_c(menu
,
1574 "Log output prefix",
1575 "Prefix prepended to log output",
1576 "%t%e%d", BX_PATHNAME_LEN
);
1577 prefix
->set_ask_format("Enter log prefix: [%s] ");
1579 path
= new bx_param_filename_c(menu
,
1580 "debugger_filename",
1581 "Debugger Log filename",
1582 "Pathname of debugger log file",
1583 "-", BX_PATHNAME_LEN
);
1584 path
->set_ask_format("Enter debugger log filename: [%s] ");
1585 path
->set_enabled(BX_DEBUGGER
);
1588 bx_param_c
*runtime_init_list
[] = {
1589 SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
),
1590 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
),
1591 SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
),
1592 SIM
->get_param_string(BXPN_USER_SHORTCUT
),
1593 SIM
->get_param_num(BXPN_SB16_DMATIMER
),
1594 SIM
->get_param_num(BXPN_SB16_LOGLEVEL
),
1595 SIM
->get_param_string(BXPN_USB1_PORT1
),
1596 SIM
->get_param_string(BXPN_USB1_PORT2
),
1599 menu
= new bx_list_c(special_menus
, "runtime", "Misc runtime options", runtime_init_list
);
1600 menu
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::SHOW_GROUP_NAME
);
1603 void bx_reset_options()
1606 SIM
->get_param("cpu")->reset();
1608 // memory (ram & rom)
1609 SIM
->get_param("memory")->reset();
1612 SIM
->get_param("clock_cmos")->reset();
1615 SIM
->get_param("pci")->reset();
1617 // display & interface
1618 SIM
->get_param("display")->reset();
1621 SIM
->get_param("keyboard_mouse")->reset();
1624 SIM
->get_param("boot_params")->reset();
1627 SIM
->get_param("floppy")->reset();
1630 SIM
->get_param("ata")->reset();
1633 SIM
->get_param("ports")->reset();
1636 SIM
->get_param("network")->reset();
1639 SIM
->get_param("sound")->reset();
1642 SIM
->get_param("misc")->reset();
1645 SIM
->get_param("log")->reset();
1648 int bx_read_configuration(const char *rcfile
)
1650 // parse rcfile first, then parse arguments in order.
1651 BX_INFO (("reading configuration from %s", rcfile
));
1652 if (parse_bochsrc(rcfile
) < 0) {
1653 BX_PANIC (("reading from %s failed", rcfile
));
1656 // update log actions
1657 for (int level
=0; level
<N_LOGLEV
; level
++) {
1658 int action
= SIM
->get_default_log_action (level
);
1659 io
->set_log_action (level
, action
);
1664 int bx_parse_cmdline (int arg
, int argc
, char *argv
[])
1666 //if (arg < argc) BX_INFO (("parsing command line arguments"));
1668 while (arg
< argc
) {
1669 BX_INFO (("parsing arg %d, %s", arg
, argv
[arg
]));
1670 parse_line_unformatted("cmdline args", argv
[arg
]);
1673 // update log actions
1674 for (int level
=0; level
<N_LOGLEV
; level
++) {
1675 int action
= SIM
->get_default_log_action (level
);
1676 io
->set_log_action (level
, action
);
1682 char *bx_find_bochsrc()
1686 Bit32u retry
= 0, found
= 0;
1687 // try several possibilities for the bochsrc before giving up
1691 case 0: strcpy (rcfile
, ".bochsrc"); break;
1692 case 1: strcpy (rcfile
, "bochsrc"); break;
1693 case 2: strcpy (rcfile
, "bochsrc.txt"); break;
1695 case 3: strcpy (rcfile
, "bochsrc.bxrc"); break;
1696 #elif !BX_WITH_MACOS
1697 // only try this on unix
1700 char *ptr
= getenv("HOME");
1701 if (ptr
) snprintf (rcfile
, sizeof(rcfile
), "%s/.bochsrc", ptr
);
1704 case 4: strcpy (rcfile
, "/etc/bochsrc"); break;
1710 BX_DEBUG (("looking for configuration in %s", rcfile
));
1711 fd
= fopen(rcfile
, "r");
1715 assert (fd
!= NULL
&& rcfile
[0] != 0);
1717 return strdup(rcfile
);
1720 static int parse_bochsrc(const char *rcfile
)
1725 char context
[BX_PATHNAME_LEN
];
1728 // try several possibilities for the bochsrc before giving up
1730 bochsrc_include_count
++;
1732 fd
= fopen (rcfile
, "r");
1733 if (fd
== NULL
) return -1;
1737 ret
= fgets(line
, sizeof(line
)-1, fd
);
1738 line
[sizeof(line
) - 1] = '\0';
1739 int len
= strlen(line
);
1740 if ((len
>0) && (line
[len
-1] < ' '))
1742 if ((ret
!= NULL
) && strlen(line
)) {
1743 sprintf(context
, "%s:%u", rcfile
, linenum
);
1744 if (parse_line_unformatted(context
, line
) < 0) {
1746 break; // quit parsing after first error
1750 } while (!feof(fd
));
1752 bochsrc_include_count
--;
1756 static const char *get_builtin_variable(const char *varname
)
1764 static char data
[MAX_PATH
];
1767 if (strlen(varname
)<1) return NULL
;
1769 if (!strcmp(varname
, "BXSHARE")) {
1771 wsprintf(keyname
, "Software\\Bochs %s", VER_STRING
);
1772 code
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, keyname
, 0, KEY_READ
, &hkey
);
1773 if (code
== ERROR_SUCCESS
) {
1776 if (RegQueryValueEx(hkey
, "", NULL
, (LPDWORD
)&type
, (LPBYTE
)data
,
1777 (LPDWORD
)&size
) == ERROR_SUCCESS
) {
1788 return BX_SHARE_PATH
;
1795 static Bit32s
parse_line_unformatted(const char *context
, char *line
)
1797 #define MAX_PARAMS_LEN 40
1799 unsigned i
, string_i
= 0;
1801 char *params
[MAX_PARAMS_LEN
];
1803 bx_bool inquotes
= 0;
1804 bx_bool comment
= 0;
1806 memset(params
, 0, sizeof(params
));
1807 if (line
== NULL
) return 0;
1809 // if passed nothing but whitespace, just return
1810 for (i
=0; i
<strlen(line
); i
++) {
1811 if (!isspace(line
[i
])) break;
1813 if (i
>=strlen(line
))
1818 if (!strncmp(line
, "#include", 8))
1819 ptr
= strtok(line
, " ");
1821 ptr
= strtok(line
, ":");
1822 while ((ptr
) && (!comment
)) {
1826 string
[string_i
++] = ',';
1828 for (i
=0; i
<strlen(ptr
); i
++) {
1830 inquotes
= !inquotes
;
1831 else if ((ptr
[i
] == '#') && (strncmp(line
+i
, "#include", 8)) && !inquotes
) {
1836 // substitute environment variables.
1837 if (ptr
[i
] == '$') {
1843 while (isalpha(ptr
[i
]) || ptr
[i
]=='_') {
1844 *pv
= ptr
[i
]; pv
++; i
++;
1847 if (strlen(varname
)<1 || !(value
= getenv(varname
))) {
1848 if ((value
= get_builtin_variable(varname
))) {
1849 // append value to the string
1850 for (pv
=(char *)value
; *pv
; pv
++)
1851 string
[string_i
++] = *pv
;
1853 BX_PANIC (("could not look up environment variable '%s'", varname
));
1856 // append value to the string
1857 for (pv
=(char *)value
; *pv
; pv
++)
1858 string
[string_i
++] = *pv
;
1862 if (!isspace(ptr
[i
]) || inquotes
) {
1863 string
[string_i
++] = ptr
[i
];
1867 string
[string_i
] = '\0';
1868 if (string_i
== 0) break;
1870 if (params
[num_params
] != NULL
) {
1871 free(params
[num_params
]);
1872 params
[num_params
] = NULL
;
1874 if (num_params
< MAX_PARAMS_LEN
) {
1875 params
[num_params
++] = strdup(string
);
1877 BX_PANIC (("too many parameters, max is %d\n", MAX_PARAMS_LEN
));
1880 ptr
= strtok(NULL
, ",");
1882 Bit32s retval
= parse_line_formatted(context
, num_params
, ¶ms
[0]);
1883 for (i
=0; i
< MAX_PARAMS_LEN
; i
++)
1885 if ( params
[i
] != NULL
)
1894 // These macros are called for all parse errors, so that we can easily
1895 // change the behavior of all occurrences.
1896 #define PARSE_ERR(x) \
1897 do { BX_PANIC(x); return -1; } while (0)
1898 #define PARSE_WARN(x) \
1902 * this supports the "floppyx: image=" option.
1903 * the functions returns the type of the floppy
1904 * image (1.44, 360, etc.), based on the image file size.
1906 int get_floppy_type_from_image(const char *filename
)
1908 struct stat stat_buf
;
1910 if (stat(filename
, &stat_buf
))
1912 return BX_FLOPPY_NONE
;
1915 switch (stat_buf
.st_size
)
1918 return BX_FLOPPY_160K
;
1921 return BX_FLOPPY_180K
;
1924 return BX_FLOPPY_320K
;
1927 return BX_FLOPPY_360K
;
1930 return BX_FLOPPY_720K
;
1933 return BX_FLOPPY_1_2
;
1939 return BX_FLOPPY_1_44
;
1942 return BX_FLOPPY_2_88
;
1945 return BX_FLOPPY_UNKNOWN
;
1949 static Bit32s
parse_log_options(const char *context
, char *loglev
, char *param1
)
1953 if (!strcmp(loglev
, "panic")) {
1954 level
= LOGLEV_PANIC
;
1955 } else if (!strcmp(loglev
, "pass")) {
1956 level
= LOGLEV_PASS
;
1957 } else if (!strcmp(loglev
, "error")) {
1958 level
= LOGLEV_ERROR
;
1959 } else if (!strcmp(loglev
, "info")) {
1960 level
= LOGLEV_INFO
;
1961 } else { /* debug */
1962 level
= LOGLEV_DEBUG
;
1964 if (strncmp(param1
, "action=", 7)) {
1965 PARSE_ERR(("%s: %s directive malformed.", context
, loglev
));
1967 char *action
= param1
+ 7;
1968 if (!strcmp(action
, "fatal"))
1969 SIM
->set_default_log_action (level
, ACT_FATAL
);
1970 else if (!strcmp (action
, "report"))
1971 SIM
->set_default_log_action (level
, ACT_REPORT
);
1972 else if (!strcmp (action
, "ignore"))
1973 SIM
->set_default_log_action (level
, ACT_IGNORE
);
1974 else if (!strcmp (action
, "ask"))
1975 SIM
->set_default_log_action (level
, ACT_ASK
);
1977 PARSE_ERR(("%s: %s directive malformed.", context
, loglev
));
1982 static Bit32s
parse_line_formatted(const char *context
, int num_params
, char *params
[])
1988 if (num_params
< 1) return 0;
1989 if (num_params
< 2) {
1990 PARSE_ERR(("%s: a bochsrc option needs at least one parameter", context
));
1993 if (!strcmp(params
[0], "#include")) {
1994 if (num_params
!= 2) {
1995 PARSE_ERR(("%s: ignoring malformed #include directive.", context
));
1997 if (!strcmp(params
[1], context
)) {
1998 PARSE_ERR(("%s: cannot include this file again.", context
));
2000 if (bochsrc_include_count
== 2) {
2001 PARSE_ERR(("%s: include directive in an included file not supported yet.", context
));
2003 bx_read_configuration(params
[1]);
2005 else if (!strcmp(params
[0], "floppya")) {
2006 for (i
=1; i
<num_params
; i
++) {
2007 if (!strncmp(params
[i
], "2_88=", 5)) {
2008 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2009 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_2_88
);
2011 else if (!strncmp(params
[i
], "1_44=", 5)) {
2012 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2013 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_1_44
);
2015 else if (!strncmp(params
[i
], "1_2=", 4)) {
2016 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][4]);
2017 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_1_2
);
2019 else if (!strncmp(params
[i
], "720k=", 5)) {
2020 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2021 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_720K
);
2023 else if (!strncmp(params
[i
], "360k=", 5)) {
2024 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2025 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_360K
);
2027 // use CMOS reserved types?
2028 else if (!strncmp(params
[i
], "160k=", 5)) {
2029 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2030 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_160K
);
2032 else if (!strncmp(params
[i
], "180k=", 5)) {
2033 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2034 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_180K
);
2036 else if (!strncmp(params
[i
], "320k=", 5)) {
2037 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2038 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_320K
);
2040 else if (!strncmp(params
[i
], "image=", 6)) {
2041 /* "image=" means we should get floppy type from image */
2042 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][6]);
2043 t
= get_floppy_type_from_image(¶ms
[i
][6]);
2044 if (t
!= BX_FLOPPY_UNKNOWN
)
2045 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(t
);
2047 PARSE_ERR(("%s: floppya image size doesn't match one of the supported types.", context
));
2049 else if (!strncmp(params
[i
], "status=", 7)) {
2050 SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->set_by_name(¶ms
[i
][7]);
2053 PARSE_ERR(("%s: floppya attribute '%s' not understood.", context
,
2059 else if (!strcmp(params
[0], "floppyb")) {
2060 for (i
=1; i
<num_params
; i
++) {
2061 if (!strncmp(params
[i
], "2_88=", 5)) {
2062 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2063 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_2_88
);
2065 else if (!strncmp(params
[i
], "1_44=", 5)) {
2066 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2067 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_1_44
);
2069 else if (!strncmp(params
[i
], "1_2=", 4)) {
2070 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][4]);
2071 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_1_2
);
2073 else if (!strncmp(params
[i
], "720k=", 5)) {
2074 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2075 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_720K
);
2077 else if (!strncmp(params
[i
], "360k=", 5)) {
2078 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2079 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_360K
);
2081 // use CMOS reserved types?
2082 else if (!strncmp(params
[i
], "160k=", 5)) {
2083 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2084 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_160K
);
2086 else if (!strncmp(params
[i
], "180k=", 5)) {
2087 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2088 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_180K
);
2090 else if (!strncmp(params
[i
], "320k=", 5)) {
2091 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2092 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_320K
);
2094 else if (!strncmp(params
[i
], "image=", 6)) {
2095 /* "image=" means we should get floppy type from image */
2096 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][6]);
2097 t
= get_floppy_type_from_image(¶ms
[i
][6]);
2098 if (t
!= BX_FLOPPY_UNKNOWN
)
2099 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(t
);
2101 PARSE_ERR(("%s: floppyb image size doesn't match one of the supported types.", context
));
2103 else if (!strncmp(params
[i
], "status=", 7)) {
2104 SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->set_by_name(¶ms
[i
][7]);
2107 PARSE_ERR(("%s: floppyb attribute '%s' not understood.", context
,
2113 else if ((!strncmp(params
[0], "ata", 3)) && (strlen(params
[0]) == 4)) {
2115 Bit8u channel
= params
[0][3];
2117 if ((channel
< '0') || (channel
> '9')) {
2118 PARSE_ERR(("%s: ataX directive malformed.", context
));
2121 if (channel
>= BX_MAX_ATA_CHANNEL
) {
2122 PARSE_ERR(("%s: ataX directive malformed.", context
));
2125 if ((num_params
< 2) || (num_params
> 5)) {
2126 PARSE_ERR(("%s: ataX directive malformed.", context
));
2128 sprintf(tmpname
, "ata.%d.resources", channel
);
2129 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2130 if (strncmp(params
[1], "enabled=", 8)) {
2131 PARSE_ERR(("%s: ataX directive malformed.", context
));
2133 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[1][8]));
2136 if (num_params
> 2) {
2137 if (strncmp(params
[2], "ioaddr1=", 8)) {
2138 PARSE_ERR(("%s: ataX directive malformed.", context
));
2141 if ((params
[2][8] == '0') && (params
[2][9] == 'x'))
2142 SIM
->get_param_num("ioaddr1", base
)->set(strtoul(¶ms
[2][8], NULL
, 16));
2144 SIM
->get_param_num("ioaddr1", base
)->set(strtoul(¶ms
[2][8], NULL
, 10));
2148 if (num_params
> 3) {
2149 if (strncmp(params
[3], "ioaddr2=", 8)) {
2150 PARSE_ERR(("%s: ataX directive malformed.", context
));
2153 if ((params
[3][8] == '0') && (params
[3][9] == 'x'))
2154 SIM
->get_param_num("ioaddr2", base
)->set(strtoul(¶ms
[3][8], NULL
, 16));
2156 SIM
->get_param_num("ioaddr2", base
)->set(strtoul(¶ms
[3][8], NULL
, 10));
2160 if (num_params
> 4) {
2161 if (strncmp(params
[4], "irq=", 4)) {
2162 PARSE_ERR(("%s: ataX directive malformed.", context
));
2165 SIM
->get_param_num("irq", base
)->set(atol(¶ms
[4][4]));
2170 // ataX-master, ataX-slave
2171 else if ((!strncmp(params
[0], "ata", 3)) && (strlen(params
[0]) > 4)) {
2172 Bit8u channel
= params
[0][3];
2173 int type
= 0, mode
= BX_ATA_MODE_FLAT
, biosdetect
= BX_ATA_BIOSDETECT_AUTO
;
2174 Bit32u cylinders
= 0, heads
= 0, sectors
= 0;
2177 if ((channel
< '0') || (channel
> '9')) {
2178 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2181 if (channel
>= BX_MAX_ATA_CHANNEL
) {
2182 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2185 if ((strcmp(¶ms
[0][4], "-slave")) &&
2186 (strcmp(¶ms
[0][4], "-master"))) {
2187 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2190 sprintf(tmpname
, "ata.%d.%s", channel
, ¶ms
[0][5]);
2191 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2192 for (i
=1; i
<num_params
; i
++) {
2193 if (!strncmp(params
[i
], "type=", 5)) {
2194 type
= SIM
->get_param_enum("type", base
)->find_by_name(¶ms
[i
][5]);
2196 PARSE_ERR(("%s: ataX-master/slave: unknown type '%s'", context
, ¶ms
[i
][5]));
2198 } else if (!strcmp(params
[i
], "mode=z-undoable")) {
2199 PARSE_ERR(("%s: ataX-master/slave mode 'z-undoable' not implemented yet", context
));
2200 } else if (!strcmp(params
[i
], "mode=z-volatile")) {
2201 PARSE_ERR(("%s: ataX-master/slave mode 'z-volatile' not implemented yet", context
));
2202 } else if (!strncmp(params
[i
], "mode=", 5)) {
2203 mode
= SIM
->get_param_enum("mode", base
)->find_by_name(¶ms
[i
][5]);
2205 PARSE_ERR(("%s: ataX-master/slave: unknown mode '%s'", context
, ¶ms
[i
][5]));
2207 } else if (!strncmp(params
[i
], "path=", 5)) {
2208 SIM
->get_param_string("path", base
)->set(¶ms
[i
][5]);
2209 } else if (!strncmp(params
[i
], "cylinders=", 10)) {
2210 cylinders
= atol(¶ms
[i
][10]);
2211 } else if (!strncmp(params
[i
], "heads=", 6)) {
2212 heads
= atol(¶ms
[i
][6]);
2213 } else if (!strncmp(params
[i
], "spt=", 4)) {
2214 sectors
= atol(¶ms
[i
][4]);
2215 } else if (!strncmp(params
[i
], "model=", 6)) {
2216 SIM
->get_param_string("model", base
)->set(¶ms
[i
][6]);
2217 } else if (!strncmp(params
[i
], "biosdetect=", 11)) {
2218 biosdetect
= SIM
->get_param_enum("biosdetect", base
)->find_by_name(¶ms
[i
][11]);
2219 if (biosdetect
< 0) {
2220 PARSE_ERR(("%s: ataX-master/slave: unknown biosdetect '%s'", context
, ¶ms
[i
][11]));
2222 } else if (!strcmp(params
[i
], "translation=none")) {
2223 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_NONE
);
2224 } else if (!strcmp(params
[i
], "translation=lba")) {
2225 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LBA
);
2226 } else if (!strcmp(params
[i
], "translation=large")) {
2227 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LARGE
);
2228 } else if (!strcmp(params
[i
], "translation=echs")) { // synonym of large
2229 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LARGE
);
2230 } else if (!strcmp(params
[i
], "translation=rechs")) {
2231 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_RECHS
);
2232 } else if (!strcmp(params
[i
], "translation=auto")) {
2233 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_AUTO
);
2234 } else if (!strcmp(params
[i
], "status=ejected")) {
2235 SIM
->get_param_enum("status", base
)->set(BX_EJECTED
);
2236 } else if (!strcmp(params
[i
], "status=inserted")) {
2237 SIM
->get_param_enum("status", base
)->set(BX_INSERTED
);
2238 } else if (!strncmp(params
[i
], "journal=", 8)) {
2239 SIM
->get_param_string("journal", base
)->set(¶ms
[i
][8]);
2241 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2245 // Enables the ata device
2246 if (strlen(SIM
->get_param_string("path", base
)->getptr()) > 0) {
2247 SIM
->get_param_bool("present", base
)->set(1);
2248 SIM
->get_param_enum("type", base
)->set(type
);
2249 SIM
->get_param_enum("mode", base
)->set(mode
);
2250 SIM
->get_param_num("cylinders", base
)->set(cylinders
);
2251 SIM
->get_param_num("heads", base
)->set(heads
);
2252 SIM
->get_param_num("spt", base
)->set(sectors
);
2253 SIM
->get_param_num("biosdetect", base
)->set(biosdetect
);
2255 SIM
->get_param_bool("present", base
)->set(0);
2258 // if enabled, check if device ok
2259 if (SIM
->get_param_bool("present", base
)->get() == 1) {
2260 if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_DISK
) {
2261 if ((SIM
->get_param_num("cylinders", base
)->get() == 0) &&
2262 (SIM
->get_param_num("heads", base
)->get() ==0 ) &&
2263 (SIM
->get_param_num("spt", base
)->get() == 0)) {
2264 PARSE_WARN(("%s: ataX-master/slave CHS set to 0/0/0 - autodetection enabled", context
));
2265 // using heads = 16 and spt = 63 for autodetection (bximage defaults)
2266 SIM
->get_param_num("heads", base
)->set(16);
2267 SIM
->get_param_num("spt", base
)->set(63);
2269 } else if (SIM
->get_param_enum("type", base
)->get() != BX_ATA_DEVICE_CDROM
) {
2270 PARSE_WARN(("%s: ataX-master/slave: type should be specified", context
));
2273 } else if (!strcmp(params
[0], "boot")) {
2275 if (num_params
< 2) {
2276 PARSE_ERR(("%s: boot directive malformed.", context
));
2278 for (i
=1; i
<num_params
; i
++) {
2279 sprintf(tmppath
, "boot_params.boot_drive%d", i
);
2280 if (!strcmp(params
[i
], "none")) {
2281 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_NONE
);
2282 } else if (!strcmp(params
[i
], "a")) {
2283 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_FLOPPYA
);
2284 } else if (!strcmp(params
[i
], "floppy")) {
2285 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_FLOPPYA
);
2286 } else if (!strcmp(params
[i
], "c")) {
2287 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_DISKC
);
2288 } else if (!strcmp(params
[i
], "disk")) {
2289 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_DISKC
);
2290 } else if (!strcmp(params
[i
], "cdrom")) {
2291 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_CDROM
);
2293 PARSE_ERR(("%s: boot directive with unknown boot drive '%s'. use 'floppy', 'disk' or 'cdrom'.", context
, params
[i
]));
2296 if (SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == BX_BOOT_NONE
) {
2297 PARSE_ERR(("%s: first boot drive must be one of 'floppy', 'disk' or 'cdrom'.", context
));
2299 if ((SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE2
)->get()) ||
2300 (SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get()) ||
2301 ((SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get() != BX_BOOT_NONE
) &&
2302 (SIM
->get_param_enum(BXPN_BOOTDRIVE2
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get()))) {
2303 PARSE_ERR(("%s: a boot drive appears twice in boot sequence.", context
));
2305 } else if (!strcmp(params
[0], "floppy_bootsig_check")) {
2306 if (num_params
!= 2) {
2307 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2309 if (strncmp(params
[1], "disabled=", 9)) {
2310 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2312 if (params
[1][9] == '0')
2313 SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->set(0);
2314 else if (params
[1][9] == '1')
2315 SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->set(1);
2317 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2319 } else if (!strcmp(params
[0], "log")) {
2320 if (num_params
!= 2) {
2321 PARSE_ERR(("%s: log directive has wrong # args.", context
));
2323 SIM
->get_param_string(BXPN_LOG_FILENAME
)->set(params
[1]);
2324 } else if (!strcmp(params
[0], "logprefix")) {
2325 if (num_params
!= 2) {
2326 PARSE_ERR(("%s: logprefix directive has wrong # args.", context
));
2328 SIM
->get_param_string(BXPN_LOG_PREFIX
)->set(params
[1]);
2329 } else if (!strcmp(params
[0], "debugger_log")) {
2330 if (num_params
!= 2) {
2331 PARSE_ERR(("%s: debugger_log directive has wrong # args.", context
));
2333 SIM
->get_param_string(BXPN_DEBUGGER_LOG_FILENAME
)->set(params
[1]);
2334 } else if (!strcmp(params
[0], "panic")) {
2335 if (num_params
!= 2) {
2336 PARSE_ERR(("%s: panic directive malformed.", context
));
2338 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2341 } else if (!strcmp(params
[0], "pass")) {
2342 if (num_params
!= 2) {
2343 PARSE_ERR(("%s: pass directive malformed.", context
));
2345 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2348 } else if (!strcmp(params
[0], "error")) {
2349 if (num_params
!= 2) {
2350 PARSE_ERR(("%s: error directive malformed.", context
));
2352 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2355 } else if (!strcmp(params
[0], "info")) {
2356 if (num_params
!= 2) {
2357 PARSE_ERR(("%s: info directive malformed.", context
));
2359 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2362 } else if (!strcmp(params
[0], "debug")) {
2363 if (num_params
!= 2) {
2364 PARSE_ERR(("%s: debug directive malformed.", context
));
2366 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2369 } else if (!strcmp(params
[0], "cpu")) {
2370 if (num_params
< 2) {
2371 PARSE_ERR(("%s: cpu directive malformed.", context
));
2373 for (i
=1; i
<num_params
; i
++) {
2374 if (!strncmp(params
[i
], "count=", 6)) {
2375 unsigned processors
= 1, cores
= 1, threads
= 1;
2376 sscanf(¶ms
[i
][6], "%u:%u:%u", &processors
, &cores
, &threads
);
2377 unsigned smp_threads
= cores
*threads
*processors
;
2378 if (smp_threads
> BX_MAX_SMP_THREADS_SUPPORTED
) {
2379 PARSE_ERR(("%s: too many SMP threads defined, only %u threads supported",
2380 context
, BX_MAX_SMP_THREADS_SUPPORTED
));
2382 if (smp_threads
< 1) {
2383 PARSE_ERR(("%s: at least one CPU thread should be defined, cpu directive malformed", context
));
2385 SIM
->get_param_num(BXPN_CPU_NPROCESSORS
)->set(processors
);
2386 SIM
->get_param_num(BXPN_CPU_NCORES
)->set(cores
);
2387 SIM
->get_param_num(BXPN_CPU_NTHREADS
)->set(threads
);
2388 } else if (!strncmp(params
[i
], "ips=", 4)) {
2389 SIM
->get_param_num(BXPN_IPS
)->set(atol(¶ms
[i
][4]));
2390 if (SIM
->get_param_num(BXPN_IPS
)->get() < BX_MIN_IPS
) {
2391 PARSE_WARN(("%s: WARNING: ips is AWFULLY low!", context
));
2394 } else if (!strncmp(params
[i
], "quantum=", 8)) {
2395 SIM
->get_param_num(BXPN_SMP_QUANTUM
)->set(atol(¶ms
[i
][8]));
2397 } else if (!strncmp(params
[i
], "reset_on_triple_fault=", 22)) {
2398 if (params
[i
][22] == '0' || params
[i
][22] == '1') {
2399 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->set (params
[i
][22] - '0');
2401 PARSE_ERR(("%s: cpu directive malformed.", context
));
2404 PARSE_ERR(("%s: cpu directive malformed.", context
));
2407 } else if (!strcmp(params
[0], "megs")) {
2408 if (num_params
!= 2) {
2409 PARSE_ERR(("%s: megs directive: wrong # args.", context
));
2411 SIM
->get_param_num(BXPN_MEM_SIZE
)->set(atol(params
[1]));
2412 } else if (!strcmp(params
[0], "romimage")) {
2413 if ((num_params
< 2) || (num_params
> 3)) {
2414 PARSE_ERR(("%s: romimage directive: wrong # args.", context
));
2416 if (!strncmp(params
[1], "file=", 5)) {
2417 SIM
->get_param_string(BXPN_ROM_PATH
)->set(¶ms
[1][5]);
2419 PARSE_ERR(("%s: romimage directive malformed.", context
));
2421 if (num_params
== 3) {
2422 if (!strncmp(params
[2], "address=", 8)) {
2423 if ((params
[2][8] == '0') && (params
[2][9] == 'x'))
2424 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(strtoul(¶ms
[2][8], NULL
, 16));
2426 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(strtoul(¶ms
[2][8], NULL
, 10));
2428 PARSE_ERR(("%s: romimage directive malformed.", context
));
2431 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set (0);
2433 } else if (!strcmp(params
[0], "vgaromimage")) {
2434 if (num_params
!= 2) {
2435 PARSE_ERR(("%s: vgaromimage directive: wrong # args.", context
));
2437 if (!strncmp(params
[1], "file=", 5)) {
2438 SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->set(¶ms
[1][5]);
2440 BX_INFO(("WARNING: syntax has changed, please use 'vgaromimage: file=...' now"));
2441 SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->set(params
[1]);
2443 } else if (!strncmp(params
[0], "optromimage", 11)) {
2444 int num
= atoi(¶ms
[0][11]);
2445 char tmppath
[80], tmpaddr
[80];
2446 if ((num
< 1) || (num
> BX_N_OPTROM_IMAGES
)) {
2447 PARSE_ERR(("%s: optromimage%d: not supported", context
, num
));
2449 if (num_params
!= 3) {
2450 PARSE_ERR(("%s: optromimage%d directive: wrong # args.", context
, num
));
2452 sprintf(tmppath
, "memory.optrom.%d.path", num
);
2453 sprintf(tmpaddr
, "memory.optrom.%d.addr", num
);
2454 for (i
=1; i
<num_params
; i
++) {
2455 if (!strncmp(params
[i
], "file=", 5)) {
2456 SIM
->get_param_string(tmppath
)->set(¶ms
[i
][5]);
2457 } else if (!strncmp(params
[i
], "address=", 8)) {
2458 if ((params
[i
][8] == '0') && (params
[2][9] == 'x'))
2459 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 16));
2461 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 10));
2463 PARSE_ERR(("%s: optromimage%d directive malformed.", context
, num
));
2466 } else if (!strncmp(params
[0], "optramimage", 11)) {
2467 int num
= atoi(¶ms
[0][11]);
2468 char tmppath
[80], tmpaddr
[80];
2469 if ((num
< 1) || (num
> BX_N_OPTRAM_IMAGES
)) {
2470 PARSE_ERR(("%s: optramimage%d: not supported", context
, num
));
2472 if (num_params
!= 3) {
2473 PARSE_ERR(("%s: optramimage%d directive: wrong # args.", context
, num
));
2475 sprintf(tmppath
, "memory.optram.%d.path", num
);
2476 sprintf(tmpaddr
, "memory.optram.%d.addr", num
);
2477 for (i
=1; i
<num_params
; i
++) {
2478 if (!strncmp(params
[i
], "file=", 5)) {
2479 SIM
->get_param_string(tmppath
)->set(¶ms
[i
][5]);
2480 } else if (!strncmp(params
[i
], "address=", 8)) {
2481 if ((params
[i
][8] == '0') && (params
[2][9] == 'x'))
2482 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 16));
2484 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 10));
2486 PARSE_ERR(("%s: optramimage%d directive malformed.", context
, num
));
2489 } else if (!strcmp(params
[0], "vga_update_interval")) {
2490 if (num_params
!= 2) {
2491 PARSE_ERR(("%s: vga_update_interval directive: wrong # args.", context
));
2493 SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->set(atol(params
[1]));
2494 if (SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->get() < 50000) {
2495 BX_INFO(("%s: vga_update_interval seems awfully small!", context
));
2497 } else if (!strcmp(params
[0], "vga")) {
2498 if (num_params
!= 2) {
2499 PARSE_ERR(("%s: vga directive: wrong # args.", context
));
2501 if (!strncmp(params
[1], "extension=", 10)) {
2502 SIM
->get_param_string(BXPN_VGA_EXTENSION
)->set(¶ms
[1][10]);
2504 } else if (!strcmp(params
[0], "keyboard_serial_delay")) {
2505 if (num_params
!= 2) {
2506 PARSE_ERR(("%s: keyboard_serial_delay directive: wrong # args.", context
));
2508 SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->set(atol(params
[1]));
2509 if (SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->get() < 5) {
2510 PARSE_ERR (("%s: keyboard_serial_delay not big enough!", context
));
2512 } else if (!strcmp(params
[0], "keyboard_paste_delay")) {
2513 if (num_params
!= 2) {
2514 PARSE_ERR(("%s: keyboard_paste_delay directive: wrong # args.", context
));
2516 SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->set(atol(params
[1]));
2517 if (SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->get() < 1000) {
2518 PARSE_ERR (("%s: keyboard_paste_delay not big enough!", context
));
2520 } else if (!strcmp(params
[0], "floppy_command_delay")) {
2521 PARSE_WARN(("%s: floppy_command_delay is DEPRECATED (now using hardware timing).", context
));
2522 } else if (!strcmp(params
[0], "ips")) {
2523 PARSE_WARN(("%s: ips directive is DEPRECATED (use cpu directive parameter 'ips').", context
));
2524 if (num_params
!= 2) {
2525 PARSE_ERR(("%s: ips directive: wrong # args.", context
));
2527 SIM
->get_param_num(BXPN_IPS
)->set(atol(params
[1]));
2528 if (SIM
->get_param_num(BXPN_IPS
)->get() < BX_MIN_IPS
) {
2529 PARSE_WARN(("%s: WARNING: ips is AWFULLY low!", context
));
2531 } else if (!strcmp(params
[0], "text_snapshot_check")) {
2532 if (num_params
!= 2) {
2533 PARSE_ERR(("%s: text_snapshot_check directive: wrong # args.", context
));
2535 if (!strncmp(params
[1], "enabled=", 8)) {
2536 if (params
[1][8] == '0' || params
[1][8] == '1')
2537 SIM
->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK
)->set(params
[1][8] - '0');
2539 PARSE_ERR(("%s: text_snapshot_check directive malformed.", context
));
2541 PARSE_ERR(("%s: text_snapshot_check directive malformed.", context
));
2543 } else if (!strcmp(params
[0], "mouse")) {
2544 if (num_params
< 2) {
2545 PARSE_ERR(("%s: mouse directive malformed.", context
));
2547 for (i
=1; i
<num_params
; i
++) {
2548 if (!strncmp(params
[i
], "enabled=", 8)) {
2549 if (params
[i
][8] == '0' || params
[i
][8] == '1')
2550 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
)->set(params
[i
][8] - '0');
2552 PARSE_ERR(("%s: mouse directive malformed.", context
));
2553 } else if (!strncmp(params
[i
], "type=", 5)) {
2554 if (!SIM
->get_param_enum(BXPN_MOUSE_TYPE
)->set_by_name(¶ms
[i
][5]))
2555 PARSE_ERR(("%s: mouse type '%s' not available", context
, ¶ms
[i
][5]));
2557 PARSE_ERR(("%s: mouse directive malformed.", context
));
2560 } else if (!strcmp(params
[0], "private_colormap")) {
2561 if (num_params
!= 2) {
2562 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2564 if (strncmp(params
[1], "enabled=", 8)) {
2565 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2567 if (params
[1][8] == '0' || params
[1][8] == '1')
2568 SIM
->get_param_bool(BXPN_PRIVATE_COLORMAP
)->set(params
[1][8] - '0');
2570 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2572 } else if (!strcmp(params
[0], "fullscreen")) {
2574 if (num_params
!= 2) {
2575 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2577 if (strncmp(params
[1], "enabled=", 8)) {
2578 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2580 if (params
[1][8] == '0' || params
[1][8] == '1') {
2581 SIM
->get_param_bool(BXPN_FULLSCREEN
)->set(params
[1][8] - '0');
2583 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2586 } else if (!strcmp(params
[0], "screenmode")) {
2588 if (num_params
!= 2) {
2589 PARSE_ERR(("%s: screenmode directive malformed.", context
));
2591 if (strncmp(params
[1], "name=", 5)) {
2592 PARSE_ERR(("%s: screenmode directive malformed.", context
));
2594 SIM
->get_param_string(BXPN_SCREENMODE
)->set(¶ms
[1][5]);
2596 } else if (!strcmp(params
[0], "sb16")) {
2598 base
= (bx_list_c
*) SIM
->get_param(BXPN_SB16
);
2599 for (i
=1; i
<num_params
; i
++) {
2600 if (!strncmp(params
[i
], "enabled=", 8)) {
2601 enable
= atol(¶ms
[i
][8]);
2602 } else if (!strncmp(params
[i
], "midi=", 5)) {
2603 SIM
->get_param_string("midifile", base
)->set(¶ms
[i
][5]);
2604 } else if (!strncmp(params
[i
], "midimode=", 9)) {
2605 SIM
->get_param_num("midimode", base
)->set(atol(¶ms
[i
][9]));
2606 } else if (!strncmp(params
[i
], "wave=", 5)) {
2607 SIM
->get_param_string("wavefile", base
)->set(¶ms
[i
][5]);
2608 } else if (!strncmp(params
[i
], "wavemode=", 9)) {
2609 SIM
->get_param_num("wavemode", base
)->set(atol(¶ms
[i
][9]));
2610 } else if (!strncmp(params
[i
], "log=", 4)) {
2611 SIM
->get_param_string("logfile", base
)->set(¶ms
[i
][4]);
2612 } else if (!strncmp(params
[i
], "loglevel=", 9)) {
2613 SIM
->get_param_num("loglevel", base
)->set(atol(¶ms
[i
][9]));
2614 } else if (!strncmp(params
[i
], "dmatimer=", 9)) {
2615 SIM
->get_param_num("dmatimer", base
)->set(atol(¶ms
[i
][9]));
2617 BX_ERROR(("%s: unknown parameter for sb16 ignored.", context
));
2620 if ((enable
!= 0) && (SIM
->get_param_num("dmatimer", base
)->get() > 0))
2621 SIM
->get_param_bool("enabled", base
)->set(1);
2623 SIM
->get_param_bool("enabled", base
)->set(0);
2624 } else if ((!strncmp(params
[0], "com", 3)) && (strlen(params
[0]) == 4)) {
2627 if ((idx
< '1') || (idx
> '9')) {
2628 PARSE_ERR(("%s: comX directive malformed.", context
));
2631 if (idx
> BX_N_SERIAL_PORTS
) {
2632 PARSE_ERR(("%s: comX port number out of range.", context
));
2634 sprintf(tmpname
, "ports.serial.%d", idx
);
2635 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2636 for (i
=1; i
<num_params
; i
++) {
2637 if (!strncmp(params
[i
], "enabled=", 8)) {
2638 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2639 } else if (!strncmp(params
[i
], "mode=", 5)) {
2640 if (!SIM
->get_param_enum("mode", base
)->set_by_name(¶ms
[i
][5]))
2641 PARSE_ERR(("%s: com%d serial port mode '%s' not available", context
, idx
, ¶ms
[i
][5]));
2642 SIM
->get_param_bool("enabled", base
)->set(1);
2643 } else if (!strncmp(params
[i
], "dev=", 4)) {
2644 SIM
->get_param_string("dev", base
)->set(¶ms
[i
][4]);
2645 SIM
->get_param_bool("enabled", base
)->set(1);
2647 PARSE_ERR(("%s: unknown parameter for com%d ignored.", context
, idx
));
2650 } else if ((!strncmp(params
[0], "parport", 7)) && (strlen(params
[0]) == 8)) {
2653 if ((idx
< '1') || (idx
> '9')) {
2654 PARSE_ERR(("%s: parportX directive malformed.", context
));
2657 if (idx
> BX_N_PARALLEL_PORTS
) {
2658 PARSE_ERR(("%s: parportX port number out of range.", context
));
2660 sprintf(tmpname
, "ports.parallel.%d", idx
);
2661 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2662 for (i
=1; i
<num_params
; i
++) {
2663 if (!strncmp(params
[i
], "enabled=", 8)) {
2664 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2665 } else if (!strncmp(params
[i
], "file=", 5)) {
2666 SIM
->get_param_string("outfile", base
)->set(¶ms
[i
][5]);
2667 SIM
->get_param_bool("enabled", base
)->set(1);
2669 BX_ERROR(("%s: unknown parameter for parport%d ignored.", context
, idx
));
2672 } else if ((!strncmp(params
[0], "usb", 3)) && (strlen(params
[0]) == 4)) {
2675 if ((idx
< '1') || (idx
> '9')) {
2676 PARSE_ERR(("%s: usbX directive malformed.", context
));
2679 if (idx
> BX_N_USB_HUBS
) {
2680 PARSE_ERR(("%s: usbX hub number out of range.", context
));
2682 sprintf(tmpname
, "ports.usb.%d", idx
);
2683 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2684 for (i
=1; i
<num_params
; i
++) {
2685 if (!strncmp(params
[i
], "enabled=", 8)) {
2686 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2687 } else if (!strncmp(params
[i
], "port1=", 6)) {
2688 SIM
->get_param_string("port1", base
)->set(¶ms
[i
][6]);
2689 } else if (!strncmp(params
[i
], "option1=", 8)) {
2690 PARSE_WARN(("%s: usb port1 option is now deprecated", context
));
2691 } else if (!strncmp(params
[i
], "port2=", 6)) {
2692 SIM
->get_param_string("port2", base
)->set(¶ms
[i
][6]);
2693 } else if (!strncmp(params
[i
], "option2=", 8)) {
2694 PARSE_WARN(("%s: usb port2 option is now deprecated", context
));
2695 } else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2696 PARSE_WARN(("%s: usb ioaddr is now DEPRECATED (assigned by BIOS).", context
));
2697 } else if (!strncmp(params
[i
], "irq=", 4)) {
2698 PARSE_WARN(("%s: usb irq is now DEPRECATED (assigned by BIOS).", context
));
2700 PARSE_WARN(("%s: unknown parameter '%s' for usb%d ignored.", context
, params
[i
], idx
));
2703 } else if (!strcmp(params
[0], "i440fxsupport")) {
2705 for (i
=1; i
<num_params
; i
++) {
2706 if (!strncmp(params
[i
], "enabled=", 8)) {
2707 SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->set(atol(¶ms
[i
][8]));
2708 } else if ((!strncmp(params
[i
], "slot", 4)) && (params
[i
][5] == '=')) {
2709 slot
= atol(¶ms
[i
][4]);
2710 if ((slot
> 0) && (slot
< 6)) {
2711 sprintf(tmpdev
, "pci.slot.%d", slot
);
2712 SIM
->get_param_string(tmpdev
)->set(¶ms
[i
][6]);
2714 BX_ERROR(("%s: unknown pci slot number ignored.", context
));
2717 PARSE_ERR(("%s: i440fxsupport: unknown parameter '%s'.", context
, params
[i
]));
2720 } else if (!strcmp(params
[0], "pcidev")) {
2721 if (num_params
!= 3) {
2722 PARSE_ERR(("%s: pcidev directive malformed.", context
));
2724 for (i
=1; i
<num_params
; i
++) {
2725 if (!strncmp(params
[i
], "vendor=", 7)) {
2726 if ( (params
[i
][7] == '0') && (toupper(params
[i
][8]) == 'X') )
2727 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2729 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->set(strtoul(¶ms
[i
][7], NULL
, 10));
2731 else if (!strncmp(params
[i
], "device=", 7)) {
2732 if ( (params
[i
][7] == '0') && (toupper(params
[i
][8]) == 'X') )
2733 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2735 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->set(strtoul(¶ms
[i
][7], NULL
, 10));
2738 BX_ERROR(("%s: unknown parameter for pcidev ignored.", context
));
2741 } else if (!strcmp(params
[0], "cmosimage")) {
2742 for (i
=1; i
<num_params
; i
++) {
2743 if (!strncmp(params
[i
], "file=", 5)) {
2744 SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->set(¶ms
[i
][5]);
2745 } else if (!strcmp(params
[i
], "rtc_init=time0")) {
2746 SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->set(0);
2747 } else if (!strcmp(params
[i
], "rtc_init=image")) {
2748 SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->set(1);
2750 // for backward compatiblity
2751 SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->set(params
[i
]);
2754 if (strlen(SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr()) > 0) {
2755 SIM
->get_param_bool(BXPN_CMOSIMAGE_ENABLED
)->set(1);
2757 } else if (!strcmp(params
[0], "clock")) {
2758 for (i
=1; i
<num_params
; i
++) {
2759 if (!strncmp(params
[i
], "sync=", 5)) {
2760 SIM
->get_param_enum(BXPN_CLOCK_SYNC
)->set_by_name(¶ms
[i
][5]);
2762 else if (!strcmp(params
[i
], "time0=local")) {
2763 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(BX_CLOCK_TIME0_LOCAL
);
2765 else if (!strcmp(params
[i
], "time0=utc")) {
2766 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(BX_CLOCK_TIME0_UTC
);
2768 else if (!strncmp(params
[i
], "time0=", 6)) {
2769 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(atoi(¶ms
[i
][6]));
2772 BX_ERROR(("%s: unknown parameter for clock ignored.", context
));
2776 else if (!strcmp(params
[0], "gdbstub")) {
2778 if (num_params
< 2) {
2779 PARSE_ERR(("%s: gdbstub directive: wrong # args.", context
));
2781 base
= (bx_list_c
*) SIM
->get_param(BXPN_GDBSTUB
);
2782 for (i
=1; i
<num_params
; i
++) {
2783 if (!strncmp(params
[i
], "enabled=", 8)) {
2784 if (params
[i
][8] == '0') {
2785 SIM
->get_param_bool("enabled", base
)->set(0);
2786 BX_INFO(("Disabled gdbstub"));
2787 bx_dbg
.gdbstub_enabled
= 0;
2789 else if (params
[i
][8] == '1') {
2790 SIM
->get_param_bool("enabled", base
)->set(1);
2791 BX_INFO(("Enabled gdbstub"));
2792 bx_dbg
.gdbstub_enabled
= 1;
2795 PARSE_ERR(("%s: gdbstub directive malformed.", context
));
2798 else if (!strncmp(params
[i
], "port=", 5)) {
2799 SIM
->get_param_num("port", base
)->set(atoi(¶ms
[i
][5]));
2801 else if (!strncmp(params
[i
], "text_base=", 10)) {
2802 SIM
->get_param_num("text_base", base
)->set(atoi(¶ms
[i
][10]));
2804 else if (!strncmp(params
[i
], "data_base=", 10)) {
2805 SIM
->get_param_num("data_base", base
)->set(atoi(¶ms
[i
][10]));
2807 else if (!strncmp(params
[i
], "bss_base=", 9)) {
2808 SIM
->get_param_num("bss_base", base
)->set(atoi(¶ms
[i
][9]));
2811 PARSE_ERR(("%s: gdbstub directive malformed.", context
));
2815 PARSE_ERR(("%s: Bochs is not compiled with gdbstub support", context
));
2819 #if BX_MAGIC_BREAKPOINT
2820 else if (!strcmp(params
[0], "magic_break")) {
2821 if (num_params
!= 2) {
2822 PARSE_ERR(("%s: magic_break directive: wrong # args.", context
));
2824 if (strncmp(params
[1], "enabled=", 8)) {
2825 PARSE_ERR(("%s: magic_break directive malformed.", context
));
2827 if (params
[1][8] == '0') {
2828 BX_INFO(("Ignoring magic break points"));
2829 bx_dbg
.magic_break_enabled
= 0;
2831 else if (params
[1][8] == '1') {
2832 BX_INFO(("Stopping on magic break points"));
2833 bx_dbg
.magic_break_enabled
= 1;
2836 PARSE_ERR(("%s: magic_break directive malformed.", context
));
2840 else if (!strcmp(params
[0], "print_timestamps")) {
2841 if (num_params
!= 2) {
2842 PARSE_ERR(("%s: print_timestamps directive: wrong # args.", context
));
2844 if (strncmp(params
[1], "enabled=", 8)) {
2845 PARSE_ERR(("%s: print_timestamps directive malformed.", context
));
2847 if (params
[1][8] == '0' || params
[1][8] == '1') {
2848 bx_dbg
.print_timestamps
= params
[1][8] - '0';
2851 PARSE_ERR(("%s: print_timestamps directive malformed.", context
));
2854 else if (!strcmp(params
[0], "ne2k")) {
2859 base
= (bx_list_c
*) SIM
->get_param(BXPN_NE2K
);
2860 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2861 SIM
->get_param_enum("ethmod", base
)->set_by_name("null");
2863 for (i
=1; i
<num_params
; i
++) {
2864 if (!strncmp(params
[i
], "enabled=", 8)) {
2865 if (atol(¶ms
[i
][8]) == 0) valid
|= 0x80;
2867 else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2868 SIM
->get_param_num("ioaddr", base
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2871 else if (!strncmp(params
[i
], "irq=", 4)) {
2872 SIM
->get_param_num("irq", base
)->set(atol(¶ms
[i
][4]));
2875 else if (!strncmp(params
[i
], "mac=", 4)) {
2876 n
= sscanf(¶ms
[i
][4], "%x:%x:%x:%x:%x:%x",
2877 &tmp
[0],&tmp
[1],&tmp
[2],&tmp
[3],&tmp
[4],&tmp
[5]);
2879 PARSE_ERR(("%s: ne2k mac address malformed.", context
));
2882 tmpchar
[n
] = (unsigned char)tmp
[n
];
2883 SIM
->get_param_string("macaddr", base
)->set(tmpchar
);
2886 else if (!strncmp(params
[i
], "ethmod=", 7)) {
2887 if (!SIM
->get_param_enum("ethmod", base
)->set_by_name(¶ms
[i
][7]))
2888 PARSE_ERR(("%s: ethernet module '%s' not available", context
, ¶ms
[i
][7]));
2890 else if (!strncmp(params
[i
], "ethdev=", 7)) {
2891 SIM
->get_param_string("ethdev", base
)->set(¶ms
[i
][7]);
2893 else if (!strncmp(params
[i
], "script=", 7)) {
2894 SIM
->get_param_string("script", base
)->set(¶ms
[i
][7]);
2897 PARSE_WARN(("%s: unknown parameter '%s' for ne2k ignored.", context
, params
[i
]));
2900 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2901 if (valid
== 0x07) {
2902 SIM
->get_param_bool("enabled", base
)->set(1);
2903 } else if (valid
< 0x80) {
2904 PARSE_ERR(("%s: ne2k directive incomplete (ioaddr, irq and mac are required)", context
));
2908 SIM
->get_param_bool("enabled", base
)->set(0);
2911 } else if (!strcmp(params
[0], "pnic")) {
2916 base
= (bx_list_c
*) SIM
->get_param(BXPN_PNIC
);
2917 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2918 SIM
->get_param_enum("ethmod", base
)->set_by_name("null");
2920 for (i
=1; i
<num_params
; i
++) {
2921 if (!strncmp(params
[i
], "enabled=", 8)) {
2922 if (atol(¶ms
[i
][8]) == 0) valid
|= 0x80;
2923 } else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2924 PARSE_WARN(("%s: pnic ioaddr is now DEPRECATED (assigned by BIOS).", context
));
2925 } else if (!strncmp(params
[i
], "irq=", 4)) {
2926 PARSE_WARN(("%s: pnic irq is now DEPRECATED (assigned by BIOS).", context
));
2927 } else if (!strncmp(params
[i
], "mac=", 4)) {
2928 n
= sscanf(¶ms
[i
][4], "%x:%x:%x:%x:%x:%x",
2929 &tmp
[0],&tmp
[1],&tmp
[2],&tmp
[3],&tmp
[4],&tmp
[5]);
2931 PARSE_ERR(("%s: pnic mac address malformed.", context
));
2934 tmpchar
[n
] = (unsigned char)tmp
[n
];
2935 SIM
->get_param_string("macaddr", base
)->set(tmpchar
);
2937 } else if (!strncmp(params
[i
], "ethmod=", 7)) {
2938 if (!SIM
->get_param_enum("ethmod", base
)->set_by_name(¶ms
[i
][7]))
2939 PARSE_ERR(("%s: ethernet module '%s' not available", context
, ¶ms
[i
][7]));
2940 } else if (!strncmp(params
[i
], "ethdev=", 7)) {
2941 SIM
->get_param_string("ethdev", base
)->set(¶ms
[i
][7]);
2942 } else if (!strncmp(params
[i
], "script=", 7)) {
2943 SIM
->get_param_string("script", base
)->set(¶ms
[i
][7]);
2945 PARSE_WARN(("%s: unknown parameter '%s' for pnic ignored.", context
, params
[i
]));
2948 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2949 if (valid
== 0x07) {
2950 SIM
->get_param_bool("enabled", base
)->set(1);
2951 } else if (valid
< 0x80) {
2952 PARSE_ERR(("%s: pnic directive incomplete (mac is required)", context
));
2956 SIM
->get_param_bool("enabled", base
)->set(0);
2959 } else if (!strcmp(params
[0], "load32bitOSImage")) {
2960 if ( (num_params
!=4) && (num_params
!=5) ) {
2961 PARSE_ERR(("%s: load32bitOSImage directive: wrong # args.", context
));
2963 if (strncmp(params
[1], "os=", 3)) {
2964 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2966 if (!strcmp(¶ms
[1][3], "nullkernel")) {
2967 SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->set(Load32bitOSNullKernel
);
2969 else if (!strcmp(¶ms
[1][3], "linux")) {
2970 SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->set(Load32bitOSLinux
);
2973 PARSE_ERR(("%s: load32bitOSImage: unsupported OS.", context
));
2975 if (strncmp(params
[2], "path=", 5)) {
2976 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2978 if (strncmp(params
[3], "iolog=", 6)) {
2979 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2981 SIM
->get_param_string(BXPN_LOAD32BITOS_PATH
)->set(¶ms
[2][5]);
2982 SIM
->get_param_string(BXPN_LOAD32BITOS_IOLOG
)->set(¶ms
[3][6]);
2983 if (num_params
== 5) {
2984 if (strncmp(params
[4], "initrd=", 7)) {
2985 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
2987 SIM
->get_param_string(BXPN_LOAD32BITOS_INITRD
)->set(¶ms
[4][7]);
2990 else if (!strcmp(params
[0], "keyboard_type")) {
2991 if (num_params
!= 2) {
2992 PARSE_ERR(("%s: keyboard_type directive: wrong # args.", context
));
2994 if (!SIM
->get_param_enum(BXPN_KBD_TYPE
)->set_by_name(params
[1])) {
2995 PARSE_ERR(("%s: keyboard_type directive: wrong arg '%s'.", context
,params
[1]));
2998 else if (!strcmp(params
[0], "keyboard_mapping")
2999 ||!strcmp(params
[0], "keyboardmapping")) {
3000 for (i
=1; i
<num_params
; i
++) {
3001 if (!strncmp(params
[i
], "enabled=", 8)) {
3002 SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->set(atol(¶ms
[i
][8]));
3004 else if (!strncmp(params
[i
], "map=", 4)) {
3005 SIM
->get_param_string(BXPN_KBD_KEYMAP
)->set(¶ms
[i
][4]);
3009 else if (!strcmp(params
[0], "user_shortcut"))
3011 if (num_params
!= 2) {
3012 PARSE_ERR(("%s: user_shortcut directive: wrong # args.", context
));
3014 if(!strncmp(params
[1], "keys=", 4)) {
3015 SIM
->get_param_string(BXPN_USER_SHORTCUT
)->set(¶ms
[1][5]);
3016 if ((strchr(¶ms
[1][5], '-') == NULL
) && (strlen(¶ms
[1][5]) > 5))
3017 PARSE_WARN(("user_shortcut: old-style syntax detected"));
3019 PARSE_ERR(("%s: user_shortcut directive malformed.", context
));
3022 else if (!strcmp(params
[0], "config_interface"))
3024 if (num_params
!= 2) {
3025 PARSE_ERR(("%s: config_interface directive: wrong # args.", context
));
3027 if (!SIM
->get_param_enum(BXPN_SEL_CONFIG_INTERFACE
)->set_by_name(params
[1]))
3028 PARSE_ERR(("%s: config_interface '%s' not available", context
, params
[1]));
3030 else if (!strcmp(params
[0], "display_library")) {
3031 if ((num_params
< 2) || (num_params
> 3)) {
3032 PARSE_ERR(("%s: display_library directive: wrong # args.", context
));
3034 if (!SIM
->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY
)->set_by_name(params
[1]))
3035 PARSE_ERR(("%s: display library '%s' not available", context
, params
[1]));
3036 if (num_params
== 3) {
3037 if (!strncmp(params
[2], "options=", 8)) {
3038 SIM
->get_param_string(BXPN_DISPLAYLIB_OPTIONS
)->set(¶ms
[2][8]);
3042 // Old timing options have been replaced by the 'clock' option
3043 else if (!strcmp(params
[0], "pit")) // Deprecated
3045 PARSE_ERR(("ERROR: pit directive is DEPRECATED, use clock: instead"));
3047 else if (!strcmp(params
[0], "time0")) // Deprectated
3049 PARSE_ERR(("ERROR: time0 directive is DEPRECATED, use clock: instead"));
3051 // user-defined options handled by registered functions
3052 else if ((i
= SIM
->find_user_option(params
[0])) >= 0)
3054 return SIM
->parse_user_option(i
, context
, num_params
, ¶ms
[0]);
3058 PARSE_ERR(( "%s: directive '%s' not understood", context
, params
[0]));
3064 static const char *fdtypes
[] = {
3065 "none", "1_2", "1_44", "2_88", "720k", "360k", "160k", "180k", "320k"
3068 int bx_write_floppy_options(FILE *fp
, int drive
)
3070 char path
[80], type
[80], status
[80];
3072 BX_ASSERT(drive
==0 || drive
==1);
3073 sprintf(path
, "floppy.%d.path", drive
);
3074 sprintf(type
, "floppy.%d.type", drive
);
3075 sprintf(status
, "floppy.%d.status", drive
);
3076 if (SIM
->get_param_enum(type
)->get() == BX_FLOPPY_NONE
) {
3077 fprintf(fp
, "# no floppy%c\n", (char)'a'+drive
);
3080 BX_ASSERT(SIM
->get_param_enum(type
)->get() > BX_FLOPPY_NONE
&&
3081 SIM
->get_param_enum(type
)->get() <= BX_FLOPPY_LAST
);
3082 fprintf(fp
, "floppy%c: %s=\"%s\", status=%s\n",
3084 fdtypes
[SIM
->get_param_enum(type
)->get() - BX_FLOPPY_NONE
],
3085 SIM
->get_param_string(path
)->getptr(),
3086 SIM
->get_param_enum(status
)->get_selected());
3090 int bx_write_ata_options(FILE *fp
, Bit8u channel
, bx_list_c
*base
)
3092 fprintf(fp
, "ata%d: enabled=%d", channel
, SIM
->get_param_bool("enabled", base
)->get());
3094 if (SIM
->get_param_bool("enabled", base
)->get()) {
3095 fprintf(fp
, ", ioaddr1=0x%x, ioaddr2=0x%x, irq=%d", SIM
->get_param_num("ioaddr1", base
)->get(),
3096 SIM
->get_param_num("ioaddr2", base
)->get(), SIM
->get_param_num("irq", base
)->get());
3103 int bx_write_atadevice_options(FILE *fp
, Bit8u channel
, Bit8u drive
, bx_list_c
*base
)
3105 if (SIM
->get_param_bool("present", base
)->get()) {
3106 fprintf(fp
, "ata%d-%s: ", channel
, drive
==0?"master":"slave");
3108 if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_DISK
) {
3109 fprintf(fp
, "type=disk");
3111 fprintf(fp
, ", mode=%s", SIM
->get_param_enum("mode", base
)->get_selected());
3112 fprintf(fp
, ", translation=%s", SIM
->get_param_enum("translation", base
)->get_selected());
3113 fprintf(fp
, ", path=\"%s\", cylinders=%d, heads=%d, spt=%d",
3114 SIM
->get_param_string("path", base
)->getptr(),
3115 SIM
->get_param_num("cylinders", base
)->get(),
3116 SIM
->get_param_num("heads", base
)->get(),
3117 SIM
->get_param_num("spt", base
)->get());
3119 if (SIM
->get_param_string("journal", base
)->getptr() != NULL
)
3120 if (strcmp(SIM
->get_param_string("journal", base
)->getptr(), "") != 0)
3121 fprintf(fp
, ", journal=\"%s\"", SIM
->get_param_string("journal", base
)->getptr());
3123 } else if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_CDROM
) {
3124 fprintf(fp
, "type=cdrom, path=\"%s\", status=%s",
3125 SIM
->get_param_string("path", base
)->getptr(),
3126 SIM
->get_param_enum("status", base
)->get_selected());
3129 fprintf(fp
, ", biosdetect=%s", SIM
->get_param_enum("biosdetect", base
)->get_selected());
3131 if (SIM
->get_param_string("model", base
)->getptr()>0) {
3132 fprintf(fp
, ", model=\"%s\"", SIM
->get_param_string("model", base
)->getptr());
3140 int bx_write_parport_options(FILE *fp
, bx_list_c
*base
, int n
)
3142 fprintf(fp
, "parport%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3143 if (SIM
->get_param_bool("enabled", base
)->get()) {
3144 fprintf(fp
, ", file=\"%s\"", SIM
->get_param_string("outfile", base
)->getptr());
3150 int bx_write_serial_options(FILE *fp
, bx_list_c
*base
, int n
)
3152 fprintf(fp
, "com%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3153 if (SIM
->get_param_bool("enabled", base
)->get()) {
3154 fprintf(fp
, ", mode=%s", SIM
->get_param_enum("mode", base
)->get_selected());
3155 fprintf(fp
, ", dev=\"%s\"", SIM
->get_param_string("dev", base
)->getptr());
3161 int bx_write_usb_options(FILE *fp
, bx_list_c
*base
, int n
)
3163 fprintf(fp
, "usb%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3164 if (SIM
->get_param_bool("enabled", base
)->get()) {
3165 fprintf(fp
, ", port1=%s", SIM
->get_param_string("port1", base
)->getptr());
3166 fprintf(fp
, ", port2=%s", SIM
->get_param_string("port2", base
)->getptr());
3172 int bx_write_pnic_options(FILE *fp
, bx_list_c
*base
)
3174 fprintf (fp
, "pnic: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3175 if (SIM
->get_param_bool("enabled", base
)->get()) {
3176 char *ptr
= SIM
->get_param_string("macaddr", base
)->getptr();
3177 fprintf (fp
, ", mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s",
3178 (unsigned int)(0xff & ptr
[0]),
3179 (unsigned int)(0xff & ptr
[1]),
3180 (unsigned int)(0xff & ptr
[2]),
3181 (unsigned int)(0xff & ptr
[3]),
3182 (unsigned int)(0xff & ptr
[4]),
3183 (unsigned int)(0xff & ptr
[5]),
3184 SIM
->get_param_enum("ethmod", base
)->get_selected(),
3185 SIM
->get_param_string("ethdev", base
)->getptr(),
3186 SIM
->get_param_string("script", base
)->getptr());
3192 int bx_write_ne2k_options (FILE *fp
, bx_list_c
*base
)
3194 fprintf(fp
, "ne2k: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3195 if (SIM
->get_param_bool("enabled", base
)->get()) {
3196 char *ptr
= SIM
->get_param_string("macaddr", base
)->getptr();
3197 fprintf(fp
, ", ioaddr=0x%x, irq=%d, mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s",
3198 SIM
->get_param_num("ioaddr", base
)->get(),
3199 SIM
->get_param_num("irq", base
)->get(),
3200 (unsigned int)(0xff & ptr
[0]),
3201 (unsigned int)(0xff & ptr
[1]),
3202 (unsigned int)(0xff & ptr
[2]),
3203 (unsigned int)(0xff & ptr
[3]),
3204 (unsigned int)(0xff & ptr
[4]),
3205 (unsigned int)(0xff & ptr
[5]),
3206 SIM
->get_param_enum("ethmod", base
)->get_selected(),
3207 SIM
->get_param_string("ethdev", base
)->getptr(),
3208 SIM
->get_param_string("script", base
)->getptr());
3214 int bx_write_sb16_options (FILE *fp
, bx_list_c
*base
)
3216 fprintf(fp
, "sb16: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3217 if (SIM
->get_param_bool("enabled", base
)->get()) {
3218 fprintf(fp
, ", midimode=%d, midi=%s, wavemode=%d, wave=%s, loglevel=%d, log=%s, dmatimer=%d",
3219 SIM
->get_param_num("midimode", base
)->get(),
3220 SIM
->get_param_string("midifile", base
)->getptr(),
3221 SIM
->get_param_num("wavemode", base
)->get(),
3222 SIM
->get_param_string("wavefile", base
)->getptr(),
3223 SIM
->get_param_num("loglevel", base
)->get(),
3224 SIM
->get_param_string("logfile", base
)->getptr(),
3225 SIM
->get_param_num("dmatimer", base
)->get());
3231 int bx_write_loader_options(FILE *fp
)
3233 if (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSNone
) {
3234 fprintf(fp
, "# no loader\n");
3237 BX_ASSERT((SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSLinux
) ||
3238 (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSNullKernel
));
3239 fprintf (fp
, "load32bitOSImage: os=%s, path=%s, iolog=%s, initrd=%s\n",
3240 (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSLinux
) ? "linux" : "nullkernel",
3241 SIM
->get_param_string(BXPN_LOAD32BITOS_PATH
)->getptr(),
3242 SIM
->get_param_string(BXPN_LOAD32BITOS_IOLOG
)->getptr(),
3243 SIM
->get_param_string(BXPN_LOAD32BITOS_INITRD
)->getptr());
3247 int bx_write_clock_cmos_options(FILE *fp
)
3249 fprintf(fp
, "clock: ");
3251 switch (SIM
->get_param_enum(BXPN_CLOCK_SYNC
)->get()) {
3252 case BX_CLOCK_SYNC_NONE
:
3253 fprintf(fp
, "sync=none");
3255 case BX_CLOCK_SYNC_REALTIME
:
3256 fprintf(fp
, "sync=realtime");
3258 case BX_CLOCK_SYNC_SLOWDOWN
:
3259 fprintf(fp
, "sync=slowdown");
3261 case BX_CLOCK_SYNC_BOTH
:
3262 fprintf(fp
, "sync=both");
3265 BX_PANIC(("Unknown value for sync method"));
3268 switch (SIM
->get_param_num(BXPN_CLOCK_TIME0
)->get()) {
3270 case BX_CLOCK_TIME0_LOCAL
:
3271 fprintf(fp
, ", time0=local");
3273 case BX_CLOCK_TIME0_UTC
:
3274 fprintf(fp
, ", time0=utc");
3277 fprintf(fp
, ", time0=%u", SIM
->get_param_num(BXPN_CLOCK_TIME0
)->get());
3282 if (strlen(SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr()) > 0) {
3283 fprintf(fp
, "cmosimage: file=%s, ", SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr());
3284 fprintf(fp
, "rtc_init=%s\n", SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->get()?"image":"time0");
3286 fprintf(fp
, "# no cmosimage\n");
3291 int bx_write_log_options(FILE *fp
, bx_list_c
*base
)
3293 fprintf(fp
, "log: %s\n", SIM
->get_param_string("filename", base
)->getptr());
3294 fprintf(fp
, "logprefix: %s\n", SIM
->get_param_string("prefix", base
)->getptr());
3295 fprintf(fp
, "debugger_log: %s\n", SIM
->get_param_string("debugger_filename", base
)->getptr());
3296 fprintf(fp
, "panic: action=%s\n",
3297 io
->getaction(logfunctions::get_default_action (LOGLEV_PANIC
)));
3298 fprintf(fp
, "error: action=%s\n",
3299 io
->getaction(logfunctions::get_default_action (LOGLEV_ERROR
)));
3300 fprintf(fp
, "info: action=%s\n",
3301 io
->getaction(logfunctions::get_default_action (LOGLEV_INFO
)));
3302 fprintf(fp
, "debug: action=%s\n",
3303 io
->getaction(logfunctions::get_default_action (LOGLEV_DEBUG
)));
3304 fprintf(fp
, "pass: action=%s\n",
3305 io
->getaction(logfunctions::get_default_action (LOGLEV_PASS
)));
3309 int bx_write_keyboard_options(FILE *fp
)
3311 fprintf(fp
, "keyboard_type: %s\n", SIM
->get_param_enum(BXPN_KBD_TYPE
)->get_selected());
3312 fprintf(fp
, "keyboard_serial_delay: %u\n", SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->get());
3313 fprintf(fp
, "keyboard_paste_delay: %u\n", SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->get());
3314 fprintf(fp
, "keyboard_mapping: enabled=%d, map=%s\n",
3315 SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->get(),
3316 SIM
->get_param_string(BXPN_KBD_KEYMAP
)->getptr());
3317 fprintf(fp
, "user_shortcut: keys=%s\n", SIM
->get_param_string(BXPN_USER_SHORTCUT
)->getptr());
3324 // -2: already exists, and overwrite was off
3325 int bx_write_configuration(const char *rc
, int overwrite
)
3328 char *strptr
, tmppath
[80], tmpaddr
[80], tmpdev
[80];
3330 BX_INFO(("write current configuration to %s", rc
));
3331 // check if it exists. If so, only proceed if overwrite is set.
3332 FILE *fp
= fopen(rc
, "r");
3335 if (!overwrite
) return -2;
3337 fp
= fopen(rc
, "w");
3338 if (fp
== NULL
) return -1;
3339 // finally it's open and we can start writing.
3340 fprintf(fp
, "# configuration file generated by Bochs\n");
3341 fprintf(fp
, "config_interface: %s\n", SIM
->get_param_enum(BXPN_SEL_CONFIG_INTERFACE
)->get_selected());
3342 fprintf(fp
, "display_library: %s", SIM
->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY
)->get_selected());
3343 strptr
= SIM
->get_param_string(BXPN_DISPLAYLIB_OPTIONS
)->getptr();
3344 if (strlen(strptr
) > 0)
3345 fprintf(fp
, ", options=\"%s\"\n", strptr
);
3348 fprintf(fp
, "megs: %d\n", SIM
->get_param_num(BXPN_MEM_SIZE
)->get());
3349 strptr
= SIM
->get_param_string(BXPN_ROM_PATH
)->getptr();
3350 if (strlen(strptr
) > 0) {
3351 fprintf(fp
, "romimage: file=\"%s\"", strptr
);
3352 if (SIM
->get_param_num(BXPN_ROM_ADDRESS
)->get() != 0)
3353 fprintf(fp
, ", address=0x%08x\n", (unsigned int) SIM
->get_param_num(BXPN_ROM_ADDRESS
)->get());
3358 fprintf(fp
, "# no romimage\n");
3360 strptr
= SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->getptr();
3361 if (strlen(strptr
) > 0)
3362 fprintf(fp
, "vgaromimage: file=\"%s\"\n", strptr
);
3364 fprintf(fp
, "# no vgaromimage\n");
3365 fprintf(fp
, "boot: %s", SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get_selected());
3366 for (i
=1; i
<3; i
++) {
3367 sprintf(tmppath
, "boot_params.boot_drive%d", i
+1);
3368 if (SIM
->get_param_enum(tmppath
)->get() != BX_BOOT_NONE
) {
3369 fprintf(fp
, ", %s", SIM
->get_param_enum(tmppath
)->get_selected());
3373 fprintf(fp
, "floppy_bootsig_check: disabled=%d\n", SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->get());
3374 // it would be nice to put this type of function as methods on
3375 // the structs like bx_floppy_options::print or something.
3376 bx_write_floppy_options(fp
, 0);
3377 bx_write_floppy_options(fp
, 1);
3378 for (Bit8u channel
=0; channel
<BX_MAX_ATA_CHANNEL
; channel
++) {
3379 sprintf(tmppath
, "ata.%d", channel
);
3380 base
= (bx_list_c
*) SIM
->get_param(tmppath
);
3381 bx_write_ata_options(fp
, channel
, (bx_list_c
*) SIM
->get_param("resources", base
));
3382 bx_write_atadevice_options(fp
, channel
, 0, (bx_list_c
*) SIM
->get_param("master", base
));
3383 bx_write_atadevice_options(fp
, channel
, 1, (bx_list_c
*) SIM
->get_param("slave", base
));
3385 for (i
=0; i
<BX_N_OPTROM_IMAGES
; i
++) {
3386 sprintf(tmppath
, "memory.optrom.%d.path", i
+1);
3387 sprintf(tmpaddr
, "memory.optrom.%d.addr", i
+1);
3388 strptr
= SIM
->get_param_string(tmppath
)->getptr();
3389 if (strlen(strptr
) > 0)
3390 fprintf(fp
, "optromimage%d: file=\"%s\", address=0x%05x\n", i
+1, strptr
,
3391 (unsigned int)SIM
->get_param_num(tmpaddr
)->get());
3393 for (i
=0; i
<BX_N_OPTRAM_IMAGES
; i
++) {
3394 sprintf(tmppath
, "memory.optram.%d.path", i
+1);
3395 sprintf(tmpaddr
, "memory.optram.%d.addr", i
+1);
3396 strptr
= SIM
->get_param_string(tmppath
)->getptr();
3397 if (strlen(strptr
) > 0)
3398 fprintf(fp
, "optramimage%d: file=\"%s\", address=0x%05x\n", i
+1, strptr
,
3399 (unsigned int)SIM
->get_param_num(tmpaddr
)->get());
3402 for (i
=0; i
<BX_N_PARALLEL_PORTS
; i
++) {
3403 sprintf(tmpdev
, "ports.parallel.%d", i
+1);
3404 base
= (bx_list_c
*) SIM
->get_param(tmpdev
);
3405 bx_write_parport_options(fp
, base
, i
+1);
3408 for (i
=0; i
<BX_N_SERIAL_PORTS
; i
++) {
3409 sprintf(tmpdev
, "ports.serial.%d", i
+1);
3410 base
= (bx_list_c
*) SIM
->get_param(tmpdev
);
3411 bx_write_serial_options(fp
, base
, i
+1);
3413 base
= (bx_list_c
*) SIM
->get_param("ports.usb.1");
3414 bx_write_usb_options(fp
, base
, 1);
3416 fprintf(fp
, "i440fxsupport: enabled=%d",
3417 SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get());
3418 if (SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get()) {
3419 for (i
=0; i
<BX_N_PCI_SLOTS
; i
++) {
3420 sprintf(tmpdev
, "pci.slot.%d", i
+1);
3421 strptr
= SIM
->get_param_string(tmpdev
)->getptr();
3422 if (strlen(strptr
) > 0) {
3423 fprintf(fp
, ", slot%d=%s", i
+1, strptr
);
3428 if (SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->get() != 0xffff) {
3429 fprintf(fp
, "pcidev: vendor=0x%04x, device=0x%04x\n",
3430 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->get(),
3431 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->get());
3433 fprintf(fp
, "vga_update_interval: %u\n", SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->get());
3434 fprintf(fp
, "vga: extension=%s\n", SIM
->get_param_string(BXPN_VGA_EXTENSION
)->getptr());
3436 fprintf(fp
, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, reset_on_triple_fault=%d\n",
3437 SIM
->get_param_num(BXPN_CPU_NPROCESSORS
)->get(), SIM
->get_param_num(BXPN_CPU_NCORES
)->get(),
3438 SIM
->get_param_num(BXPN_CPU_NTHREADS
)->get(), SIM
->get_param_num(BXPN_IPS
)->get(),
3439 SIM
->get_param_num(BXPN_SMP_QUANTUM
)->get(),
3440 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->get());
3442 fprintf(fp
, "cpu: count=1, ips=%u, reset_on_triple_fault=%d\n",
3443 SIM
->get_param_num(BXPN_IPS
)->get(), SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->get());
3445 fprintf(fp
, "text_snapshot_check: enabled=%d\n", SIM
->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK
)->get());
3446 fprintf(fp
, "private_colormap: enabled=%d\n", SIM
->get_param_bool(BXPN_PRIVATE_COLORMAP
)->get());
3448 fprintf(fp
, "fullscreen: enabled=%d\n", SIM
->get_param_bool(BXPN_FULLSCREEN
)->get());
3449 fprintf(fp
, "screenmode: name=\"%s\"\n", SIM
->get_param_string(BXPN_SCREENMODE
)->getptr());
3451 bx_write_clock_cmos_options(fp
);
3452 bx_write_ne2k_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_NE2K
));
3453 bx_write_pnic_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_PNIC
));
3454 bx_write_sb16_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_SB16
));
3455 bx_write_loader_options(fp
);
3456 bx_write_log_options(fp
, (bx_list_c
*) SIM
->get_param("log"));
3457 bx_write_keyboard_options(fp
);
3458 fprintf(fp
, "mouse: enabled=%d, type=%s\n",
3459 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
)->get(),
3460 SIM
->get_param_enum(BXPN_MOUSE_TYPE
)->get_selected());
3461 SIM
->save_user_options(fp
);
3466 #endif // #if BX_PROVIDE_MAIN