1 /////////////////////////////////////////////////////////////////////////
2 // $Id: config.cc,v 1.140 2008/10/14 06:55:18 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 int parse_line_unformatted(const char *context
, char *line
);
51 static int 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()) {
146 device
= BX_FLOPPY_1_44
;
149 device
= BX_FLOPPY_1_2
;
151 SIM
->get_param_enum(BXPN_FLOPPYA_DEVTYPE
)->set(device
);
154 } else if (!strcmp(pname
, BXPN_FLOPPYB_TYPE
)) {
156 if (val
== BX_FLOPPY_AUTO
) {
157 val
= get_floppy_type_from_image(SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->getptr());
158 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(val
);
159 } else if (!SIM
->get_init_done()) {
167 device
= BX_FLOPPY_1_44
;
170 device
= BX_FLOPPY_1_2
;
172 SIM
->get_param_enum(BXPN_FLOPPYB_DEVTYPE
)->set(device
);
175 } else if (!strcmp(pname
, BXPN_FLOPPYA_STATUS
)) {
176 if ((set
) && (SIM
->get_init_done())) {
177 DEV_floppy_set_media_status(0, val
== BX_INSERTED
);
178 bx_gui
->update_drive_status_buttons();
180 } else if (!strcmp(pname
, BXPN_FLOPPYB_STATUS
)) {
181 if ((set
) && (SIM
->get_init_done())) {
182 DEV_floppy_set_media_status(1, val
== BX_INSERTED
);
183 bx_gui
->update_drive_status_buttons();
186 BX_PANIC(("bx_param_handler called with unknown parameter '%s'", pname
));
193 const char *bx_param_string_handler(bx_param_string_c
*param
, int set
, const char *val
, int maxlen
)
195 char pname
[BX_PATHNAME_LEN
];
196 Bit8u channel
, device
;
199 if ((strlen(val
) < 1) || !strcmp ("none", val
)) {
203 bx_list_c
*base
= (bx_list_c
*) param
->get_parent();
204 base
->get_param_path(pname
, BX_PATHNAME_LEN
);
205 if (!strncmp(pname
, "ata.", 4)) {
206 channel
= pname
[4] - '0';
207 if (!strcmp(base
->get_name(), "master")) {
212 if (!strcmp(param
->get_name(), "path")) {
214 if (SIM
->get_init_done()) {
215 Bit32u handle
= DEV_hd_get_device_handle(channel
, device
);
217 DEV_hd_set_cd_media_status(handle
, 0);
218 bx_gui
->update_drive_status_buttons();
220 if (!SIM
->get_param_num("present", base
)->get()) {
221 BX_ERROR(("Cannot add a cdrom drive at runtime"));
222 SIM
->get_param_num("present", base
)->set(0);
224 if (SIM
->get_param_num("type", base
)->get() != BX_ATA_DEVICE_CDROM
) {
225 BX_ERROR(("Device is not a cdrom drive"));
226 SIM
->get_param_num("present", base
)->set(0);
229 if (DEV_hd_present() &&
230 (SIM
->get_param_num("status", base
)->get() == BX_INSERTED
) &&
231 (SIM
->get_param_num("type", base
)->get() == BX_ATA_DEVICE_CDROM
)) {
232 // tell the device model that we removed, then inserted the cd
233 DEV_hd_set_cd_media_status(handle
, 0);
234 DEV_hd_set_cd_media_status(handle
, 1);
240 param
->get_param_path(pname
, BX_PATHNAME_LEN
);
241 if (!strcmp(pname
, BXPN_SCREENMODE
)) {
243 BX_INFO(("Screen mode changed to %s", val
));
245 } else if (!strcmp(pname
, BXPN_FLOPPYA_PATH
)) {
247 if (SIM
->get_init_done()) {
249 DEV_floppy_set_media_status(0, 0);
250 bx_gui
->update_drive_status_buttons();
252 if (!SIM
->get_param_num(BXPN_FLOPPYA_TYPE
)->get_enabled()) {
253 BX_ERROR(("Cannot add a floppy drive at runtime"));
254 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set("none");
257 if ((DEV_floppy_present()) &&
258 (SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->get() == BX_INSERTED
)) {
259 // tell the device model that we removed, then inserted the disk
260 DEV_floppy_set_media_status(0, 0);
261 DEV_floppy_set_media_status(0, 1);
264 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set_enabled(!empty
);
265 SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->set_enabled(!empty
);
268 } else if (!strcmp(pname
, BXPN_FLOPPYB_PATH
)) {
270 if (SIM
->get_init_done()) {
272 DEV_floppy_set_media_status(1, 0);
273 bx_gui
->update_drive_status_buttons();
275 if (!SIM
->get_param_num(BXPN_FLOPPYB_TYPE
)->get_enabled()) {
276 BX_ERROR(("Cannot add a floppy drive at runtime"));
277 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set("none");
280 if ((DEV_floppy_present()) &&
281 (SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->get() == BX_INSERTED
)) {
282 // tell the device model that we removed, then inserted the disk
283 DEV_floppy_set_media_status(1, 0);
284 DEV_floppy_set_media_status(1, 1);
287 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set_enabled(!empty
);
288 SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->set_enabled(!empty
);
292 BX_PANIC(("bx_param_string_handler called with unknown parameter '%s'", pname
));
298 static int bx_param_enable_handler (bx_param_c
*param
, int val
)
300 char pname
[BX_PATHNAME_LEN
];
301 Bit8u channel
, device
;
303 bx_list_c
*base
= (bx_list_c
*) param
->get_parent();
304 base
->get_param_path(pname
, BX_PATHNAME_LEN
);
305 if (!strncmp(pname
, "ata.", 4)) {
306 channel
= pname
[4] - '0';
307 if (!strcmp(base
->get_name(), "master")) {
312 if (!strcmp(param
->get_name(), "status")) {
314 switch (SIM
->get_param_enum("type", base
)->get()) {
315 case BX_ATA_DEVICE_CDROM
:
320 } else if (!strcmp(param
->get_name(), "journal")) {
322 switch (SIM
->get_param_enum("type", base
)->get()) {
323 case BX_ATA_DEVICE_DISK
:
324 switch (SIM
->get_param_enum("mode", base
)->get()) {
325 case BX_ATA_MODE_UNDOABLE
:
326 case BX_ATA_MODE_VOLATILE
:
327 // case BX_ATA_MODE_Z_UNDOABLE:
328 // case BX_ATA_MODE_Z_VOLATILE:
336 BX_PANIC(("bx_param_enable_handler called with unknown parameter '%s'", pname
));
339 BX_PANIC(("bx_param_enable_handler called with unknown parameter '%s'", pname
));
344 void bx_init_options()
349 bx_param_num_c
*ioaddr
, *ioaddr2
, *irq
;
350 bx_param_bool_c
*enabled
;
351 bx_param_enum_c
*mode
, *status
, *type
, *ethmod
;
352 bx_param_string_c
*macaddr
, *ethdev
;
353 bx_param_filename_c
*path
;
354 char name
[BX_PATHNAME_LEN
], descr
[512], group
[16], label
[512];
356 bx_param_c
*root_param
= SIM
->get_param(".");
358 // general options subtree
359 menu
= new bx_list_c(root_param
, "general", "");
361 // config interface option, set in bochsrc or command line
362 static const char *config_interface_list
[] = {
363 #if BX_USE_TEXTCONFIG
371 bx_param_enum_c
*sel_config
= new bx_param_enum_c(menu
,
372 "config_interface", "Configuration interface",
373 "Select configuration interface",
374 config_interface_list
,
377 sel_config
->set_by_name(BX_DEFAULT_CONFIG_INTERFACE
);
379 // quick start option, set by command line arg
380 new bx_param_enum_c(menu
,
388 new bx_param_bool_c(menu
,
390 "Restore Bochs session",
391 "Restore Bochs session",
393 new bx_param_string_c(menu
,
395 "Path to data for restore",
396 "Path to data for restore",
400 // benchmarking mode, set by command line arg
401 new bx_param_num_c(menu
,
404 "set benchmark mode",
405 0, BX_MAX_BIT32U
, 0);
407 // subtree for special menus
408 bx_list_c
*special_menus
= new bx_list_c(root_param
, "menu", "");
411 #define BX_CPU_PROCESSORS_LIMIT 8
412 #define BX_CPU_CORES_LIMIT 4
413 #define BX_CPU_HT_THREADS_LIMIT 4
415 #define BX_CPU_PROCESSORS_LIMIT 1
416 #define BX_CPU_CORES_LIMIT 1
417 #define BX_CPU_HT_THREADS_LIMIT 1
421 bx_list_c
*cpu_param
= new bx_list_c(root_param
, "cpu", "CPU Options", 8 + BX_SUPPORT_SMP
);
424 bx_param_num_c
*nprocessors
= new bx_param_num_c(cpu_param
,
425 "n_processors", "Number of CPUs in SMP mode",
426 "Sets the number of CPUs for multiprocessor emulation",
427 1, BX_CPU_PROCESSORS_LIMIT
,
429 nprocessors
->set_enabled(BX_CPU_PROCESSORS_LIMIT
> 1);
430 bx_param_num_c
*ncores
= new bx_param_num_c(cpu_param
,
431 "n_cores", "Number of processor cores in each CPU in SMP mode",
432 "Sets the number of processor cores per CPU for multiprocessor emulation",
433 1, BX_CPU_CORES_LIMIT
,
435 ncores
->set_enabled(BX_CPU_CORES_LIMIT
> 1);
436 bx_param_num_c
*nthreads
= new bx_param_num_c(cpu_param
,
437 "n_threads", "Number of HT threads per each process core in SMP mode",
438 "Sets the number of HT (Intel(R) HyperThreading Technology) threads per core for multiprocessor emulation",
439 1, BX_CPU_HT_THREADS_LIMIT
,
441 nthreads
->set_enabled(BX_CPU_HT_THREADS_LIMIT
> 1);
442 new bx_param_num_c(cpu_param
,
443 "ips", "Emulated instructions per second (IPS)",
444 "Emulated instructions per second, used to calibrate bochs emulated time with wall clock time.",
448 new bx_param_num_c(cpu_param
,
449 "quantum", "Quantum ticks in SMP simulation",
450 "Maximum amount of instructions allowed to execute before returning control to another CPU.",
451 BX_SMP_QUANTUM_MIN
, BX_SMP_QUANTUM_MAX
,
454 new bx_param_bool_c(cpu_param
,
455 "reset_on_triple_fault", "Enable CPU reset on triple fault",
456 "Enable CPU reset if triple fault occured (highly recommended)",
458 new bx_param_bool_c(cpu_param
,
459 "cpuid_limit_winnt", "Limit max CPUID function to 3",
460 "Limit max CPUID function reported to 3 to workaround WinNT issue",
462 new bx_param_string_c(cpu_param
,
464 "CPUID vendor string",
465 "Set the CPUID vendor string",
466 #if BX_CPU_VENDOR_INTEL
471 BX_CPUID_VENDOR_LEN
+1);
472 new bx_param_string_c(cpu_param
,
474 "CPUID brand string",
475 "Set the CPUID brand string",
476 #if BX_CPU_VENDOR_INTEL
477 " Intel(R) Pentium(R) 4 CPU ",
479 "AMD Athlon(tm) processor",
481 BX_CPUID_BRAND_LEN
+1);
483 cpu_param
->get_options()->set(menu
->SHOW_PARENT
);
486 bx_list_c
*memory
= new bx_list_c(root_param
, "memory", "Memory Options");
487 bx_list_c
*stdmem
= new bx_list_c(memory
, "standard", "Standard Options");
488 bx_list_c
*optrom
= new bx_list_c(memory
, "optrom", "Optional ROM Images");
489 bx_list_c
*optram
= new bx_list_c(memory
, "optram", "Optional RAM Images");
490 bx_list_c
*ram
= new bx_list_c(stdmem
, "ram", "");
491 bx_list_c
*rom
= new bx_list_c(stdmem
, "rom", "");
492 bx_list_c
*vgarom
= new bx_list_c(stdmem
, "vgarom", "");
494 // memory options (ram & rom)
495 bx_param_num_c
*ramsize
= new bx_param_num_c(ram
,
497 "Memory size (megabytes)",
498 "Amount of RAM in megabytes",
500 BX_DEFAULT_MEM_MEGS
);
501 ramsize
->set_ask_format("Enter memory size (MB): [%d] ");
503 ramsize
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
506 path
= new bx_param_filename_c(rom
,
509 "Pathname of ROM image to load",
510 "", BX_PATHNAME_LEN
);
511 path
->set_format("Name of ROM BIOS image: %s");
512 sprintf(name
, "%s/BIOS-bochs-latest", (char *)get_builtin_variable("BXSHARE"));
513 path
->set_initial_val(name
);
514 bx_param_num_c
*romaddr
= new bx_param_num_c(rom
,
517 "The address at which the ROM image should be loaded",
520 romaddr
->set_base(16);
521 romaddr
->set_format("0x%05x");
522 romaddr
->set_long_format("ROM BIOS address: 0x%05x");
524 path
= new bx_param_filename_c(vgarom
,
527 "Pathname of VGA ROM image to load",
528 "", BX_PATHNAME_LEN
);
529 path
->set_format("Name of VGA BIOS image: %s");
530 sprintf(name
, "%s/VGABIOS-lgpl-latest", get_builtin_variable("BXSHARE"));
531 path
->set_initial_val(name
);
533 bx_param_num_c
*optaddr
;
535 for (i
=0; i
<BX_N_OPTROM_IMAGES
; i
++) {
536 sprintf(name
, "%d", i
+1);
537 sprintf(descr
, "Pathname of optional ROM image #%d to load", i
+1);
538 sprintf(label
, "Optional ROM image #%d", i
+1);
539 bx_list_c
*optnum1
= new bx_list_c(optrom
, name
, label
);
540 path
= new bx_param_filename_c(optnum1
,
544 "", BX_PATHNAME_LEN
);
545 sprintf(label
, "Name of optional ROM image #%d", i
+1);
546 strcat(label
, " : %s");
547 path
->set_format(strdup(label
));
548 sprintf(descr
, "The address at which the optional ROM image #%d should be loaded", i
+1);
549 optaddr
= new bx_param_num_c(optnum1
,
555 optaddr
->set_base(16);
556 optaddr
->set_format("0x%05x");
557 sprintf(label
, "Optional ROM #%d address:", i
+1);
558 strcat(label
, " 0x%05x");
559 optaddr
->set_long_format(strdup(label
));
560 optnum1
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
562 optrom
->get_options()->set(bx_list_c::SHOW_PARENT
);
564 for (i
=0; i
<BX_N_OPTRAM_IMAGES
; i
++) {
565 sprintf(name
, "%d", i
+1);
566 sprintf(descr
, "Pathname of optional RAM image #%d to load", i
+1);
567 sprintf(label
, "Optional RAM image #%d", i
+1);
568 bx_list_c
*optnum2
= new bx_list_c(optram
, name
, label
);
569 path
= new bx_param_filename_c(optnum2
,
573 "", BX_PATHNAME_LEN
);
574 sprintf(label
, "Name of optional RAM image #%d", i
+1);
575 strcat(label
, " : %s");
576 path
->set_format(strdup(label
));
577 sprintf(descr
, "The address at which the optional RAM image #%d should be loaded", i
+1);
578 optaddr
= new bx_param_num_c(optnum2
,
584 optaddr
->set_base(16);
585 optaddr
->set_format("0x%05x");
586 sprintf(label
, "Optional RAM #%d address:", i
+1);
587 strcat(label
, " 0x%05x");
588 optaddr
->set_long_format(strdup(label
));
589 optnum2
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
591 optrom
->get_options()->set(bx_list_c::SHOW_PARENT
);
592 memory
->get_options()->set(bx_list_c::USE_TAB_WINDOW
);
594 bx_param_c
*memory_init_list
[] = {
595 SIM
->get_param(BXPN_MEM_SIZE
),
596 SIM
->get_param(BXPN_ROM_PATH
),
597 SIM
->get_param(BXPN_ROM_ADDRESS
),
598 SIM
->get_param(BXPN_VGA_ROM_PATH
),
599 SIM
->get_param("memory.optrom"),
600 SIM
->get_param("memory.optram"),
603 menu
= new bx_list_c(special_menus
, "memory", "Bochs Memory Options", memory_init_list
);
604 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
606 // clock & cmos subtree
607 bx_list_c
*clock_cmos
= new bx_list_c(root_param
, "clock_cmos", "Clock & CMOS Options");
609 // clock & cmos options
610 bx_param_enum_c
*clock_sync
= new bx_param_enum_c(clock_cmos
,
611 "clock_sync", "Synchronisation method",
612 "Host to guest time synchronization method",
616 bx_param_num_c
*time0
= new bx_param_num_c(clock_cmos
,
618 "Initial CMOS time for Bochs\n(1:localtime, 2:utc, other:time in seconds)",
619 "Initial time for Bochs CMOS clock, used if you really want two runs to be identical",
621 BX_CLOCK_TIME0_LOCAL
);
623 bx_list_c
*cmosimage
= new bx_list_c(clock_cmos
, "cmosimage", "CMOS Image Options");
624 bx_param_bool_c
*use_cmosimage
= new bx_param_bool_c(cmosimage
,
625 "enabled", "Use a CMOS image",
626 "Controls the usage of a CMOS image",
628 path
= new bx_param_filename_c(cmosimage
,
629 "path", "Pathname of CMOS image",
630 "Pathname of CMOS image",
631 "", BX_PATHNAME_LEN
);
632 bx_param_bool_c
*rtc_init
= new bx_param_bool_c(cmosimage
,
633 "rtc_init", "Initialize RTC from image",
634 "Controls whether to initialize the RTC with values stored in the image",
636 deplist
= new bx_list_c(NULL
, 2);
638 deplist
->add(rtc_init
);
639 use_cmosimage
->set_dependent_list(deplist
);
641 time0
->set_ask_format("Enter Initial CMOS time (1:localtime, 2:utc, other:time in seconds): [%d] ");
642 clock_sync
->set_ask_format("Enter Synchronisation method: [%s] ");
643 clock_cmos
->get_options()->set(bx_list_c::SHOW_PARENT
);
644 cmosimage
->get_options()->set(bx_list_c::SHOW_PARENT
);
647 bx_list_c
*pci
= new bx_list_c(root_param
, "pci", "PCI Options");
650 bx_param_c
*pci_deps_list
[1+BX_N_PCI_SLOTS
];
651 bx_param_c
**pci_deps_ptr
= &pci_deps_list
[0];
653 bx_param_bool_c
*i440fx_support
= new bx_param_bool_c(pci
,
655 "Enable i440FX PCI Support",
656 "Controls whether to emulate the i440FX PCI chipset",
659 bx_list_c
*slot
= new bx_list_c(pci
, "slot", "PCI Slots");
660 *pci_deps_ptr
++ = slot
;
661 for (i
=0; i
<BX_N_PCI_SLOTS
; i
++) {
662 sprintf(name
, "%d", i
+1);
663 sprintf (descr
, "Name of the device connected to PCI slot #%d", i
+1);
664 sprintf (label
, "PCI slot #%d device", i
+1);
665 bx_param_string_c
*devname
= new bx_param_string_c(slot
,
669 "", BX_PATHNAME_LEN
);
671 *pci_deps_ptr
++ = devname
;
674 bx_list_c
*pcidev
= new bx_list_c(pci
, "pcidev", "Host PCI Device Mapping");
675 *pci_deps_ptr
++ = pcidev
;
676 bx_param_num_c
*pcivid
= new bx_param_num_c(pcidev
,
679 "The vendor ID of the host PCI device to map",
681 0xffff); // vendor id 0xffff = no pci device present
682 pcivid
->set_base(16);
683 pcivid
->set_format("0x%04x");
684 pcivid
->set_long_format("PCI Vendor ID: 0x%04x");
685 #if BX_SUPPORT_PCIDEV
686 *pci_deps_ptr
++ = pcivid
;
688 pcivid
->set_enabled(0);
690 bx_param_num_c
*pcidid
= new bx_param_num_c(pcidev
,
693 "The device ID of the host PCI device to map",
696 pcidid
->set_base(16);
697 pcidid
->set_format("0x%04x");
698 pcidid
->set_long_format("PCI Device ID: 0x%04x");
699 #if BX_SUPPORT_PCIDEV
700 *pci_deps_ptr
++ = pcidid
;
702 pcidid
->set_enabled(0);
704 // add final NULL at the end, and build the menu
705 *pci_deps_ptr
= NULL
;
706 i440fx_support
->set_dependent_list(new bx_list_c(NULL
, "", "", pci_deps_list
));
707 pci
->get_options()->set(bx_list_c::SHOW_PARENT
);
708 slot
->get_options()->set(bx_list_c::SHOW_PARENT
);
709 pcidev
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
712 bx_list_c
*display
= new bx_list_c(root_param
, "display", "Bochs Display & Interface Options", 7);
714 // this is a list of gui libraries that are known to be available at
715 // compile time. The one that is listed first will be the default,
716 // which is used unless the user overrides it on the command line or
717 // in a configuration file.
718 static const char *display_library_list
[] = {
757 bx_param_enum_c
*sel_displaylib
= new bx_param_enum_c(display
,
758 "display_library", "VGA Display Library",
759 "Select VGA Display Library",
760 display_library_list
,
763 sel_displaylib
->set_by_name(BX_DEFAULT_DISPLAY_LIBRARY
);
764 sel_displaylib
->set_ask_format("Choose which library to use for the Bochs display: [%s] ");
766 new bx_param_string_c(display
,
767 "displaylib_options", "Display Library options",
768 "Options passed to Display Library",
772 new bx_param_bool_c(display
,
773 "private_colormap", "Use a private colormap",
774 "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.",
777 bx_param_bool_c
*fullscreen
= new bx_param_bool_c(display
,
778 "fullscreen", "Use full screen mode",
779 "When enabled, bochs occupies the whole screen instead of just a window.",
781 bx_param_string_c
*screenmode
= new bx_param_string_c(display
,
785 "", BX_PATHNAME_LEN
);
786 screenmode
->set_handler(bx_param_string_handler
);
788 fullscreen
->set_enabled(0);
789 screenmode
->set_enabled(0);
792 bx_param_num_c
*vga_update_interval
= new bx_param_num_c(display
,
793 "vga_update_interval",
794 "VGA Update Interval",
795 "Number of microseconds between VGA updates",
798 vga_update_interval
->set_ask_format ("Type a new value for VGA update interval: [%d] ");
800 bx_param_string_c
*vga_extension
= new bx_param_string_c(display
,
803 "Name of the VGA extension",
804 "none", BX_PATHNAME_LEN
);
806 vga_extension
->set_initial_val("vbe");
807 #elif BX_SUPPORT_CLGD54XX
808 vga_extension
->set_initial_val("cirrus");
810 display
->get_options()->set(bx_list_c::SHOW_PARENT
);
812 // keyboard & mouse subtree
813 bx_list_c
*kbd_mouse
= new bx_list_c(root_param
, "keyboard_mouse", "Keyboard & Mouse Options");
814 bx_list_c
*keyboard
= new bx_list_c(kbd_mouse
, "keyboard", "Keyboard Options");
815 bx_list_c
*mouse
= new bx_list_c(kbd_mouse
, "mouse", "Mouse Options");
817 // keyboard & mouse options
818 type
= new bx_param_enum_c(keyboard
,
819 "type", "Keyboard type",
820 "Keyboard type reported by the 'identify keyboard' command",
824 type
->set_ask_format ("Enter keyboard type: [%s] ");
826 new bx_param_num_c(keyboard
,
827 "serial_delay", "Keyboard serial delay",
828 "Approximate time in microseconds that it takes one character to be transfered from the keyboard to controller over the serial path.",
831 new bx_param_num_c(keyboard
,
832 "paste_delay", "Keyboard paste delay",
833 "Approximate time in microseconds between attemps to paste characters to the keyboard controller.",
836 bx_param_bool_c
*use_kbd_mapping
= new bx_param_bool_c(keyboard
,
837 "use_mapping", "Use keyboard mapping",
838 "Controls whether to use the keyboard mapping feature",
840 bx_param_filename_c
*keymap
= new bx_param_filename_c(keyboard
,
841 "keymap", "Keymap filename",
842 "Pathname of the keymap file used",
843 "", BX_PATHNAME_LEN
);
844 deplist
= new bx_list_c(NULL
, 1);
845 deplist
->add(keymap
);
846 use_kbd_mapping
->set_dependent_list(deplist
);
848 bx_param_string_c
*user_shortcut
= new bx_param_string_c(keyboard
,
850 "Userbutton shortcut",
851 "Defines the keyboard shortcut to be sent when you press the 'user' button in the headerbar.",
853 user_shortcut
->set_runtime_param(1);
855 static const char *mouse_type_list
[] = {
859 #if BX_SUPPORT_BUSMOUSE
867 type
= new bx_param_enum_c(mouse
,
868 "type", "Mouse type",
869 "The mouse type can be one of these: 'none', 'ps2', 'imps2', 'serial', 'serial_wheel'"
870 #if BX_SUPPORT_BUSMOUSE
877 type
->set_ask_format("Choose the type of mouse [%s] ");
879 new bx_param_bool_c(mouse
,
880 "enabled", "Enable the mouse capture",
881 "Controls whether the mouse sends events to the guest. The hardware emulation is always enabled.",
883 kbd_mouse
->get_options()->set(bx_list_c::SHOW_PARENT
);
884 keyboard
->get_options()->set(bx_list_c::SHOW_PARENT
);
885 mouse
->get_options()->set(bx_list_c::SHOW_PARENT
);
887 // boot parameter subtree
888 bx_list_c
*boot_params
= new bx_list_c(root_param
, "boot_params", "Boot Options");
890 for (i
=0; i
<3; i
++) {
891 sprintf(name
, "boot_drive%d", i
+1);
892 sprintf(label
, "Boot drive #%d", i
+1);
893 sprintf(descr
, "Name of drive #%d in boot sequence (A, C or CD)", i
+1);
894 bx_param_enum_c
*bootdrive
= new bx_param_enum_c(boot_params
,
898 &bochs_bootdisk_names
[(i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
],
899 (i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
,
900 (i
==0)?BX_BOOT_FLOPPYA
:BX_BOOT_NONE
);
901 bootdrive
->set_ask_format("Boot from floppy drive, hard drive or cdrom ? [%s] ");
904 new bx_param_bool_c(boot_params
,
906 "Skip Floppy Boot Signature Check",
907 "Skips check for the 0xaa55 signature on floppy boot device.",
911 bx_list_c
*load32bitos
= new bx_list_c(boot_params
, "load32bitos", "32-bit OS Loader Hack");
912 bx_param_enum_c
*whichOS
= new bx_param_enum_c(load32bitos
,
914 "Which operating system?",
919 path
= new bx_param_filename_c(load32bitos
,
921 "Pathname of OS to load",
922 "Pathname of the 32-bit OS to load",
923 "", BX_PATHNAME_LEN
);
924 bx_param_filename_c
*iolog
= new bx_param_filename_c(load32bitos
,
926 "Pathname of I/O log file",
927 "I/O logfile used for initializing the hardware",
928 "", BX_PATHNAME_LEN
);
929 bx_param_filename_c
*initrd
= new bx_param_filename_c(load32bitos
,
931 "Pathname of initrd",
932 "Pathname of the initial ramdisk",
933 "", BX_PATHNAME_LEN
);
934 whichOS
->set_ask_format("Enter OS to load: [%s] ");
935 path
->set_ask_format("Enter pathname of OS: [%s]");
936 iolog
->set_ask_format("Enter pathname of I/O log: [%s] ");
937 initrd
->set_ask_format("Enter pathname of initrd: [%s] ");
938 load32bitos
->get_options()->set(menu
->SERIES_ASK
);
939 whichOS
->set_handler(bx_param_handler
);
940 whichOS
->set(Load32bitOSNone
);
941 boot_params
->get_options()->set(bx_list_c::SHOW_PARENT
);
944 bx_list_c
*floppy
= new bx_list_c(root_param
, "floppy", "Floppy Options");
945 bx_list_c
*floppya
= new bx_list_c(floppy
, "0", "Floppy Disk 0");
946 bx_list_c
*floppyb
= new bx_list_c(floppy
, "1", "Floppy Disk 1");
948 bx_param_enum_c
*devtype
;
950 path
= new bx_param_filename_c(floppya
,
952 "First floppy image/device",
953 "Pathname of first floppy image file or device. If you're booting from floppy, this should be a bootable floppy.",
954 "", BX_PATHNAME_LEN
);
955 path
->set_ask_format("Enter new filename, or 'none' for no disk: [%s] ");
956 path
->set_runtime_param(1);
958 devtype
= new bx_param_enum_c(floppya
,
960 "Type of floppy drive",
961 "Type of floppy drive",
965 devtype
->set_enabled(0); // hide devtype parameter
966 type
= new bx_param_enum_c(floppya
,
968 "Type of floppy disk",
969 "Type of floppy disk",
973 type
->set_ask_format("What type of floppy disk? (auto=detect) [%s] ");
974 type
->set_runtime_param(1);
976 status
= new bx_param_enum_c(floppya
,
978 "Is floppya inserted",
979 "Inserted or ejected",
983 status
->set_ask_format("Is the floppy inserted or ejected? [%s] ");
984 status
->set_runtime_param(1);
986 path
->set_handler(bx_param_string_handler
);
987 type
->set_handler(bx_param_handler
);
988 status
->set_handler(bx_param_handler
);
989 path
->set_initial_val("none");
990 floppya
->get_options()->set(bx_list_c::SERIES_ASK
);
992 path
= new bx_param_filename_c(floppyb
,
994 "Second floppy image/device",
995 "Pathname of second floppy image file or device.",
996 "", BX_PATHNAME_LEN
);
997 path
->set_ask_format("Enter new filename, or 'none' for no disk: [%s] ");
998 path
->set_runtime_param(1);
1000 devtype
= new bx_param_enum_c(floppyb
,
1002 "Type of floppy drive",
1003 "Type of floppy drive",
1007 devtype
->set_enabled(0); // hide devtype parameter
1008 type
= new bx_param_enum_c(floppyb
,
1010 "Type of floppy disk",
1011 "Type of floppy disk",
1015 type
->set_ask_format("What type of floppy disk? (auto=detect) [%s] ");
1016 type
->set_runtime_param(1);
1018 status
= new bx_param_enum_c(floppyb
,
1020 "Is floppyb inserted",
1021 "Inserted or ejected",
1022 floppy_status_names
,
1025 status
->set_ask_format("Is the floppy inserted or ejected? [%s] ");
1026 status
->set_runtime_param(1);
1028 path
->set_handler(bx_param_string_handler
);
1029 type
->set_handler(bx_param_handler
);
1030 status
->set_handler(bx_param_handler
);
1031 path
->set_initial_val("none");
1032 floppyb
->get_options()->set(bx_list_c::SERIES_ASK
);
1033 floppy
->get_options()->set(bx_list_c::SHOW_PARENT
);
1035 // ATA/ATAPI subtree
1036 bx_list_c
*ata
= new bx_list_c(root_param
, "ata", "ATA/ATAPI Options");
1039 const char *s_atachannel
[] = {
1045 const char *s_atadevname
[2] = {
1049 const char *s_atadevice
[4][2] = {
1050 { "First HD/CD on channel 0",
1051 "Second HD/CD on channel 0" },
1052 { "First HD/CD on channel 1",
1053 "Second HD/CD on channel 1" },
1054 { "First HD/CD on channel 2",
1055 "Second HD/CD on channel 2" },
1056 { "First HD/CD on channel 3",
1057 "Second HD/CD on channel 3" }
1059 Bit16u ata_default_ioaddr1
[4] = {
1060 0x1f0, 0x170, 0x1e8, 0x168
1062 Bit16u ata_default_ioaddr2
[4] = {
1063 0x3f0, 0x370, 0x3e0, 0x360
1065 Bit8u ata_default_irq
[4] = {
1069 #define BXP_PARAMS_PER_ATA_DEVICE 12
1071 bx_list_c
*ata_menu
[BX_MAX_ATA_CHANNEL
];
1072 bx_list_c
*ata_res
[BX_MAX_ATA_CHANNEL
];
1075 for (channel
=0; channel
<BX_MAX_ATA_CHANNEL
; channel
++) {
1077 sprintf(name
, "%d", channel
);
1078 ata_menu
[channel
] = new bx_list_c(ata
, name
, s_atachannel
[channel
]);
1079 ata_menu
[channel
]->get_options()->set(bx_list_c::USE_TAB_WINDOW
);
1080 ata_res
[channel
] = new bx_list_c(ata_menu
[channel
], "resources", s_atachannel
[channel
], 8);
1081 ata_res
[channel
]->get_options()->set(bx_list_c::SERIES_ASK
);
1083 enabled
= new bx_param_bool_c(ata_res
[channel
],
1085 "Enable ATA channel",
1086 "Controls whether ata channel is installed or not",
1088 enabled
->set_ask_format("Channel is enabled: [%s] ");
1090 ioaddr
= new bx_param_num_c(ata_res
[channel
],
1093 "IO adress of ata command block",
1095 ata_default_ioaddr1
[channel
]);
1096 ioaddr
->set_base(16);
1097 ioaddr
->set_ask_format("Enter new ioaddr1: [0x%x] ");
1099 ioaddr2
= new bx_param_num_c(ata_res
[channel
],
1102 "IO adress of ata control block",
1104 ata_default_ioaddr2
[channel
]);
1105 ioaddr2
->set_base(16);
1106 ioaddr2
->set_ask_format("Enter new ioaddr2: [0x%x] ");
1108 irq
= new bx_param_num_c(ata_res
[channel
],
1111 "IRQ used by this ata channel",
1113 ata_default_irq
[channel
]);
1114 irq
->set_ask_format("Enter new IRQ: [%d] ");
1115 irq
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1117 // all items in the ata[channel] menu depend on the enabled flag.
1118 // The menu list is complete, but a few dependent_list items will
1119 // be added later. Use clone() to make a copy of the dependent_list
1120 // so that it can be changed without affecting the menu.
1121 enabled
->set_dependent_list(ata_res
[channel
]->clone());
1123 for (Bit8u slave
=0; slave
<2; slave
++) {
1124 menu
= new bx_list_c(ata_menu
[channel
],
1125 s_atadevname
[slave
],
1126 s_atadevice
[channel
][slave
],
1127 BXP_PARAMS_PER_ATA_DEVICE
+ 1);
1128 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1130 bx_param_bool_c
*present
= new bx_param_bool_c(menu
,
1132 "Enable this device",
1133 "Controls whether ata device is installed or not",
1135 present
->set_ask_format("Device is enabled: [%s] ");
1137 type
= new bx_param_enum_c(menu
,
1139 "Type of ATA device",
1140 "Type of ATA device (disk or cdrom)",
1141 atadevice_type_names
,
1143 BX_ATA_DEVICE_DISK
);
1144 type
->set_ask_format("Enter type of ATA device, disk or cdrom: [%s] ");
1146 path
= new bx_param_filename_c(menu
,
1148 "Path or physical device name",
1149 "Pathname of the image or physical device (cdrom only)",
1150 "", BX_PATHNAME_LEN
);
1151 path
->set_ask_format("Enter new filename: [%s] ");
1153 mode
= new bx_param_enum_c(menu
,
1155 "Type of disk image",
1156 "Mode of the ATA harddisk",
1157 atadevice_mode_names
,
1160 mode
->set_ask_format("Enter mode of ATA device, (flat, concat, etc.): [%s] ");
1162 status
= new bx_param_enum_c(menu
,
1165 "CD-ROM media status (inserted / ejected)",
1166 atadevice_status_names
,
1169 status
->set_ask_format("Is the device inserted or ejected? [%s] ");
1171 bx_param_filename_c
*journal
= new bx_param_filename_c(menu
,
1173 "Path of journal file",
1174 "Pathname of the journal file",
1175 "", BX_PATHNAME_LEN
);
1176 journal
->set_ask_format("Enter path of journal file: [%s]");
1178 bx_param_num_c
*cylinders
= new bx_param_num_c(menu
,
1181 "Number of cylinders",
1184 cylinders
->set_ask_format("Enter number of cylinders: [%d] ");
1185 bx_param_num_c
*heads
= new bx_param_num_c(menu
,
1191 heads
->set_ask_format("Enter number of heads: [%d] ");
1192 bx_param_num_c
*spt
= new bx_param_num_c(menu
,
1194 "Sectors per track",
1195 "Number of sectors per track",
1198 spt
->set_ask_format("Enter number of sectors per track: [%d] ");
1200 bx_param_string_c
*model
= new bx_param_string_c(menu
,
1203 "String returned by the 'identify device' command",
1204 "Generic 1234", 41);
1205 model
->set_ask_format("Enter new model name: [%s]");
1207 bx_param_enum_c
*biosdetect
= new bx_param_enum_c(menu
,
1210 "Type of bios detection",
1211 atadevice_biosdetect_names
,
1212 BX_ATA_BIOSDETECT_AUTO
,
1213 BX_ATA_BIOSDETECT_NONE
);
1214 biosdetect
->set_ask_format("Enter bios detection type: [%s]");
1216 bx_param_enum_c
*translation
= new bx_param_enum_c(menu
,
1219 "How the ata-disk translation is done by the bios",
1220 atadevice_translation_names
,
1221 BX_ATA_TRANSLATION_AUTO
,
1222 BX_ATA_TRANSLATION_NONE
);
1223 translation
->set_ask_format("Enter translation type: [%s]");
1225 // the menu and all items on it depend on the present flag
1226 present
->set_dependent_list(menu
->clone());
1227 // the present flag depends on the ATA channel's enabled flag
1228 enabled
->get_dependent_list()->add(present
);
1229 // the master/slave menu depends on the ATA channel's enabled flag
1230 enabled
->get_dependent_list()->add(menu
);
1232 type
->set_handler(bx_param_handler
);
1233 mode
->set_handler(bx_param_handler
);
1234 status
->set_handler(bx_param_handler
);
1235 path
->set_handler(bx_param_string_handler
);
1237 // Set the enable_hanlders
1238 journal
->set_enable_handler(bx_param_enable_handler
);
1239 status
->set_enable_handler(bx_param_enable_handler
);
1242 // Enable two ATA interfaces by default, disable the others.
1243 // Now that the dependence relationships are established, call set() on
1244 // the ata device present params to set all enables correctly.
1245 enabled
->set_initial_val(channel
<2);
1246 enabled
->set(channel
<2);
1250 bx_param_c
*disk_menu_init_list
[] = {
1251 SIM
->get_param(BXPN_FLOPPYA
),
1252 SIM
->get_param(BXPN_FLOPPYB
),
1253 SIM
->get_param(BXPN_ATA0_RES
),
1254 SIM
->get_param(BXPN_ATA0_MASTER
),
1255 SIM
->get_param(BXPN_ATA0_SLAVE
),
1256 #if BX_MAX_ATA_CHANNEL>1
1257 SIM
->get_param(BXPN_ATA1_RES
),
1258 SIM
->get_param(BXPN_ATA1_MASTER
),
1259 SIM
->get_param(BXPN_ATA1_SLAVE
),
1261 #if BX_MAX_ATA_CHANNEL>2
1262 SIM
->get_param(BXPN_ATA2_RES
),
1263 SIM
->get_param(BXPN_ATA2_MASTER
),
1264 SIM
->get_param(BXPN_ATA2_SLAVE
),
1266 #if BX_MAX_ATA_CHANNEL>3
1267 SIM
->get_param(BXPN_ATA3_RES
),
1268 SIM
->get_param(BXPN_ATA3_MASTER
),
1269 SIM
->get_param(BXPN_ATA3_SLAVE
),
1271 SIM
->get_param("boot_params"),
1274 menu
= new bx_list_c(special_menus
, "disk", "Bochs Disk Options", disk_menu_init_list
);
1275 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1278 bx_list_c
*ports
= new bx_list_c(root_param
, "ports", "Serial and Parallel Port Options");
1279 ports
->get_options()->set(bx_list_c::USE_TAB_WINDOW
| bx_list_c::SHOW_PARENT
);
1282 bx_list_c
*parallel
= new bx_list_c(ports
, "parallel", "Parallel Port Options");
1283 parallel
->get_options()->set(bx_list_c::SHOW_PARENT
);
1284 for (i
=0; i
<BX_N_PARALLEL_PORTS
; i
++) {
1285 sprintf(name
, "%d", i
+1);
1286 sprintf(label
, "Parallel Port %d", i
+1);
1287 menu
= new bx_list_c(parallel
, name
, label
);
1288 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1289 sprintf(label
, "Enable parallel port #%d", i
+1);
1290 sprintf(descr
, "Controls whether parallel port #%d is installed or not", i
+1);
1291 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
,
1292 (i
==0)? 1 : 0); // only enable #1 by default
1293 sprintf(label
, "Parallel port #%d output file", i
+1);
1294 sprintf(descr
, "Data written to parport#%d by the guest OS is written to this file", i
+1);
1295 path
= new bx_param_filename_c(menu
, "outfile", label
, descr
,
1296 "", BX_PATHNAME_LEN
);
1297 deplist
= new bx_list_c(NULL
, 1);
1299 enabled
->set_dependent_list(deplist
);
1302 static const char *serial_mode_list
[] = {
1318 bx_list_c
*serial
= new bx_list_c(ports
, "serial", "Serial Port Options");
1319 serial
->get_options()->set(bx_list_c::SHOW_PARENT
);
1320 for (i
=0; i
<BX_N_SERIAL_PORTS
; i
++) {
1321 sprintf(name
, "%d", i
+1);
1322 sprintf(label
, "Serial Port %d", i
+1);
1323 menu
= new bx_list_c(serial
, name
, label
);
1324 menu
->get_options()->set(bx_list_c::SERIES_ASK
);
1325 sprintf(label
, "Enable serial port #%d (COM%d)", i
+1, i
+1);
1326 sprintf(descr
, "Controls whether COM%d is installed or not", i
+1);
1327 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
,
1328 (i
==0)?1 : 0); // only enable the first by default
1329 sprintf(label
, "I/O mode of the serial device for COM%d", i
+1);
1330 sprintf(descr
, "The mode can be one these: 'null', 'file', 'pipe', 'term', 'raw', 'mouse', 'socket'");
1331 mode
= new bx_param_enum_c(menu
, "mode", label
, descr
,
1332 serial_mode_list
, 0, 0);
1333 mode
->set_ask_format("Choose I/O mode of the serial device [%s] ");
1334 sprintf(label
, "Pathname of the serial device for COM%d", i
+1);
1335 sprintf(descr
, "The path can be a real serial device or a pty (X/Unix only)");
1336 path
= new bx_param_filename_c(menu
, "dev", label
, descr
,
1337 "", BX_PATHNAME_LEN
);
1338 deplist
= new bx_list_c(NULL
, 2);
1341 enabled
->set_dependent_list(deplist
);
1344 bx_param_string_c
*port
;
1347 bx_list_c
*usb
= new bx_list_c(ports
, "usb", "USB Hub Options");
1348 usb
->get_options()->set(bx_list_c::SHOW_PARENT
);
1349 for (i
=0; i
<BX_N_USB_HUBS
; i
++) {
1350 sprintf(group
, "USB%d", i
+1);
1351 sprintf(name
, "%d", i
+1);
1352 sprintf(label
, "USB Hub %d", i
+1);
1353 menu
= new bx_list_c(usb
, name
, label
);
1354 menu
->set_enabled(BX_SUPPORT_PCIUSB
);
1355 sprintf(label
, "Enable usb hub #%d", i
+1);
1356 sprintf(descr
, "Controls whether %s is installed or not", group
);
1357 enabled
= new bx_param_bool_c(menu
, "enabled", label
, descr
, 0);
1358 enabled
->set_enabled(BX_SUPPORT_PCIUSB
);
1359 port
= new bx_param_string_c(menu
,
1362 "Device connected to USB port #1",
1363 "", BX_PATHNAME_LEN
);
1364 port
->set_group(group
);
1365 port
= new bx_param_string_c(menu
,
1368 "Device connected to USB port #2",
1369 "", BX_PATHNAME_LEN
);
1370 port
->set_group(group
);
1371 enabled
->set_dependent_list(menu
->clone());
1375 bx_list_c
*network
= new bx_list_c(root_param
, "network", "Network Configuration");
1376 network
->get_options()->set(bx_list_c::USE_TAB_WINDOW
| bx_list_c::SHOW_PARENT
);
1378 // ne2k & pnic options
1379 static const char *eth_module_list
[] = {
1381 #if defined(ETH_LINUX)
1390 #if defined(ETH_WIN32)
1393 #if defined(ETH_FBSD)
1406 menu
= new bx_list_c(network
, "ne2k", "NE2000", 7);
1407 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1408 menu
->set_enabled(BX_SUPPORT_NE2K
);
1409 enabled
= new bx_param_bool_c(menu
,
1411 "Enable NE2K NIC emulation",
1412 "Enables the NE2K NIC emulation",
1414 enabled
->set_enabled(BX_SUPPORT_NE2K
);
1415 ioaddr
= new bx_param_num_c(menu
,
1418 "I/O base address of the emulated NE2K device",
1421 ioaddr
->set_base(16);
1422 irq
= new bx_param_num_c(menu
,
1425 "IRQ used by the NE2K device",
1428 irq
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1429 macaddr
= new bx_param_string_c(menu
,
1432 "MAC address of the NE2K device. Don't use an address of a machine on your net.",
1433 "\xfe\xfd\xde\xad\xbe\xef", 6);
1434 macaddr
->get_options()->set(bx_param_string_c::RAW_BYTES
);
1435 macaddr
->set_separator(':');
1436 ethmod
= new bx_param_enum_c(menu
,
1439 "Module used for the connection to the real net.",
1443 ethmod
->set_by_name("null");
1444 ethmod
->set_ask_format("Choose ethernet module for the NE2K [%s] ");
1445 ethdev
= new bx_param_string_c(menu
,
1448 "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
1449 "xl0", BX_PATHNAME_LEN
);
1450 path
= new bx_param_filename_c(menu
,
1452 "Device configuration script",
1453 "Name of the script that is executed after Bochs initializes the network interface (optional).",
1454 "none", BX_PATHNAME_LEN
);
1455 path
->set_ask_format("Enter new script name, or 'none': [%s] ");
1456 enabled
->set_dependent_list(menu
->clone());
1458 menu
= new bx_list_c(network
, "pnic", "PCI Pseudo NIC");
1459 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1460 menu
->set_enabled(BX_SUPPORT_PCIPNIC
);
1461 enabled
= new bx_param_bool_c(menu
,
1463 "Enable Pseudo NIC emulation",
1464 "Enables the Pseudo NIC emulation",
1466 enabled
->set_enabled(BX_SUPPORT_PCIPNIC
);
1467 macaddr
= new bx_param_string_c(menu
,
1470 "MAC address of the Pseudo NIC device. Don't use an address of a machine on your net.",
1471 "\xfe\xfd\xde\xad\xbe\xef", 6);
1472 macaddr
->get_options()->set(bx_param_string_c::RAW_BYTES
);
1473 macaddr
->set_separator(':');
1474 ethmod
= new bx_param_enum_c(menu
,
1477 "Module used for the connection to the real net.",
1481 ethmod
->set_by_name("null");
1482 ethmod
->set_ask_format("Choose ethernet module for the Pseudo NIC [%s]");
1483 ethdev
= new bx_param_string_c(menu
,
1486 "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
1487 "xl0", BX_PATHNAME_LEN
);
1488 path
= new bx_param_filename_c(menu
,
1490 "Device configuration script",
1491 "Name of the script that is executed after Bochs initializes the network interface (optional).",
1492 "none", BX_PATHNAME_LEN
);
1493 path
->set_ask_format("Enter new script name, or 'none': [%s] ");
1494 enabled
->set_dependent_list(menu
->clone());
1497 bx_list_c
*sound
= new bx_list_c(root_param
, "sound", "Sound Configuration");
1498 sound
->get_options()->set(bx_list_c::SHOW_PARENT
);
1499 menu
= new bx_list_c(sound
, "sb16", "SB16 Configuration", 8);
1500 menu
->get_options()->set(bx_list_c::SHOW_PARENT
);
1501 menu
->set_enabled(BX_SUPPORT_SB16
);
1504 enabled
= new bx_param_bool_c(menu
,
1506 "Enable SB16 emulation",
1507 "Enables the SB16 emulation",
1509 enabled
->set_enabled(BX_SUPPORT_SB16
);
1510 bx_param_num_c
*midimode
= new bx_param_num_c(menu
,
1513 "Controls the MIDI output format.",
1516 bx_param_filename_c
*midifile
= new bx_param_filename_c(menu
,
1519 "The filename is where the MIDI data is sent. This can be device or just a file.",
1520 "", BX_PATHNAME_LEN
);
1521 bx_param_num_c
*wavemode
= new bx_param_num_c(menu
,
1524 "Controls the wave output format.",
1527 bx_param_filename_c
*wavefile
= new bx_param_filename_c(menu
,
1530 "This is the device/file where the wave output is stored",
1531 "", BX_PATHNAME_LEN
);
1532 bx_param_num_c
*loglevel
= new bx_param_num_c(menu
,
1535 "Controls how verbose the SB16 emulation is (0 = no log, 5 = all errors and infos).",
1538 bx_param_filename_c
*logfile
= new bx_param_filename_c(menu
,
1541 "The file to write the SB16 emulator messages to.",
1542 "", BX_PATHNAME_LEN
);
1543 bx_param_num_c
*dmatimer
= new bx_param_num_c(menu
,
1546 "Microseconds per second for a DMA cycle.",
1551 midimode
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1552 wavemode
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1553 loglevel
->set_options(bx_param_num_c::USE_SPIN_CONTROL
);
1555 loglevel
->set_group("SB16");
1556 dmatimer
->set_group("SB16");
1557 enabled
->set_dependent_list(menu
->clone());
1558 deplist
= new bx_list_c(NULL
, 1);
1559 deplist
->add(midifile
);
1560 midimode
->set_dependent_list(deplist
);
1561 deplist
= new bx_list_c(NULL
, 1);
1562 deplist
->add(wavefile
);
1563 wavemode
->set_dependent_list(deplist
);
1564 deplist
= new bx_list_c(NULL
, 1);
1565 deplist
->add(logfile
);
1566 loglevel
->set_dependent_list(deplist
);
1568 // misc options subtree
1569 bx_list_c
*misc
= new bx_list_c(root_param
, "misc", "Configure Everything Else");
1570 misc
->get_options()->set(bx_list_c::SHOW_PARENT
);
1571 bx_param_num_c
*gdbstub_opt
;
1573 // text snapshot check panic
1574 new bx_param_bool_c(misc
,
1575 "text_snapshot_check",
1576 "Enable text snapshot check panic",
1577 "Enable panic when text on screen matches snapchk.txt.\nUseful for regression testing.\nIn win32, turns off CR/LF in snapshots and cuts.",
1580 menu
= new bx_list_c(misc
, "gdbstub", "GDB Stub Options");
1581 menu
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::USE_BOX_TITLE
);
1582 menu
->set_enabled(BX_GDBSTUB
);
1583 enabled
= new bx_param_bool_c(menu
,
1588 enabled
->set_enabled(BX_GDBSTUB
);
1589 gdbstub_opt
= new bx_param_num_c(menu
,
1592 "TCP/IP port for GDB stub",
1595 gdbstub_opt
= new bx_param_num_c(menu
,
1601 gdbstub_opt
= new bx_param_num_c(menu
,
1607 gdbstub_opt
= new bx_param_num_c(menu
,
1613 enabled
->set_dependent_list(menu
->clone());
1615 // log options subtree
1616 menu
= new bx_list_c(root_param
, "log", "Logfile Options");
1619 path
= new bx_param_filename_c(menu
,
1622 "Pathname of bochs log file",
1623 "-", BX_PATHNAME_LEN
);
1624 path
->set_ask_format("Enter log filename: [%s] ");
1626 bx_param_string_c
*prefix
= new bx_param_string_c(menu
,
1628 "Log output prefix",
1629 "Prefix prepended to log output",
1630 "%t%e%d", BX_PATHNAME_LEN
);
1631 prefix
->set_ask_format("Enter log prefix: [%s] ");
1633 path
= new bx_param_filename_c(menu
,
1634 "debugger_filename",
1635 "Debugger Log filename",
1636 "Pathname of debugger log file",
1637 "-", BX_PATHNAME_LEN
);
1638 path
->set_ask_format("Enter debugger log filename: [%s] ");
1639 path
->set_enabled(BX_DEBUGGER
);
1642 bx_param_c
*runtime_init_list
[] = {
1643 SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
),
1644 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
),
1645 SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
),
1646 SIM
->get_param_string(BXPN_USER_SHORTCUT
),
1647 SIM
->get_param_num(BXPN_SB16_DMATIMER
),
1648 SIM
->get_param_num(BXPN_SB16_LOGLEVEL
),
1649 SIM
->get_param_string(BXPN_USB1_PORT1
),
1650 SIM
->get_param_string(BXPN_USB1_PORT2
),
1653 menu
= new bx_list_c(special_menus
, "runtime", "Misc runtime options", runtime_init_list
);
1654 menu
->get_options()->set(bx_list_c::SHOW_PARENT
| bx_list_c::SHOW_GROUP_NAME
);
1657 void bx_reset_options()
1660 SIM
->get_param("cpu")->reset();
1662 // memory (ram & rom)
1663 SIM
->get_param("memory")->reset();
1666 SIM
->get_param("clock_cmos")->reset();
1669 SIM
->get_param("pci")->reset();
1671 // display & interface
1672 SIM
->get_param("display")->reset();
1675 SIM
->get_param("keyboard_mouse")->reset();
1678 SIM
->get_param("boot_params")->reset();
1681 SIM
->get_param("floppy")->reset();
1684 SIM
->get_param("ata")->reset();
1687 SIM
->get_param("ports")->reset();
1690 SIM
->get_param("network")->reset();
1693 SIM
->get_param("sound")->reset();
1696 SIM
->get_param("misc")->reset();
1699 SIM
->get_param("log")->reset();
1702 int bx_read_configuration(const char *rcfile
)
1704 // parse rcfile first, then parse arguments in order.
1705 BX_INFO (("reading configuration from %s", rcfile
));
1706 if (parse_bochsrc(rcfile
) < 0) {
1707 BX_PANIC (("reading from %s failed", rcfile
));
1710 // update log actions
1711 for (int level
=0; level
<N_LOGLEV
; level
++) {
1712 int action
= SIM
->get_default_log_action(level
);
1713 io
->set_log_action(level
, action
);
1718 int bx_parse_cmdline(int arg
, int argc
, char *argv
[])
1720 //if (arg < argc) BX_INFO (("parsing command line arguments"));
1722 while (arg
< argc
) {
1723 BX_INFO (("parsing arg %d, %s", arg
, argv
[arg
]));
1724 parse_line_unformatted("cmdline args", argv
[arg
]);
1727 // update log actions
1728 for (int level
=0; level
<N_LOGLEV
; level
++) {
1729 int action
= SIM
->get_default_log_action(level
);
1730 io
->set_log_action(level
, action
);
1736 char *bx_find_bochsrc()
1740 Bit32u retry
= 0, found
= 0;
1741 // try several possibilities for the bochsrc before giving up
1745 case 0: strcpy (rcfile
, ".bochsrc"); break;
1746 case 1: strcpy (rcfile
, "bochsrc"); break;
1747 case 2: strcpy (rcfile
, "bochsrc.txt"); break;
1749 case 3: strcpy (rcfile
, "bochsrc.bxrc"); break;
1750 #elif !BX_WITH_MACOS
1751 // only try this on unix
1754 char *ptr
= getenv("HOME");
1755 if (ptr
) snprintf (rcfile
, sizeof(rcfile
), "%s/.bochsrc", ptr
);
1758 case 4: strcpy (rcfile
, "/etc/bochsrc"); break;
1764 BX_DEBUG (("looking for configuration in %s", rcfile
));
1765 fd
= fopen(rcfile
, "r");
1769 assert (fd
!= NULL
&& rcfile
[0] != 0);
1771 return strdup(rcfile
);
1774 static int parse_bochsrc(const char *rcfile
)
1779 char context
[BX_PATHNAME_LEN
];
1782 // try several possibilities for the bochsrc before giving up
1784 bochsrc_include_count
++;
1786 fd
= fopen (rcfile
, "r");
1787 if (fd
== NULL
) return -1;
1791 ret
= fgets(line
, sizeof(line
)-1, fd
);
1792 line
[sizeof(line
) - 1] = '\0';
1793 size_t len
= strlen(line
);
1794 if ((len
>0) && (line
[len
-1] < ' '))
1796 if ((ret
!= NULL
) && strlen(line
)) {
1797 sprintf(context
, "%s:%u", rcfile
, linenum
);
1798 if (parse_line_unformatted(context
, line
) < 0) {
1800 break; // quit parsing after first error
1804 } while (!feof(fd
));
1806 bochsrc_include_count
--;
1810 static const char *get_builtin_variable(const char *varname
)
1818 static char data
[MAX_PATH
];
1821 if (strlen(varname
)<1) return NULL
;
1823 if (!strcmp(varname
, "BXSHARE")) {
1825 wsprintf(keyname
, "Software\\Bochs %s", VER_STRING
);
1826 code
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, keyname
, 0, KEY_READ
, &hkey
);
1827 if (code
== ERROR_SUCCESS
) {
1830 if (RegQueryValueEx(hkey
, "", NULL
, (LPDWORD
)&type
, (LPBYTE
)data
,
1831 (LPDWORD
)&size
) == ERROR_SUCCESS
) {
1842 return BX_SHARE_PATH
;
1849 static int parse_line_unformatted(const char *context
, char *line
)
1851 #define MAX_PARAMS_LEN 40
1853 unsigned i
, string_i
= 0;
1855 char *params
[MAX_PARAMS_LEN
];
1857 bx_bool inquotes
= 0;
1858 bx_bool comment
= 0;
1860 memset(params
, 0, sizeof(params
));
1861 if (line
== NULL
) return 0;
1863 // if passed nothing but whitespace, just return
1864 for (i
=0; i
<strlen(line
); i
++) {
1865 if (!isspace(line
[i
])) break;
1867 if (i
>=strlen(line
))
1872 if (!strncmp(line
, "#include", 8))
1873 ptr
= strtok(line
, " ");
1875 ptr
= strtok(line
, ":");
1876 while ((ptr
) && (!comment
)) {
1880 string
[string_i
++] = ',';
1882 for (i
=0; i
<strlen(ptr
); i
++) {
1884 inquotes
= !inquotes
;
1885 else if ((ptr
[i
] == '#') && (strncmp(line
+i
, "#include", 8)) && !inquotes
) {
1890 // substitute environment variables.
1891 if (ptr
[i
] == '$') {
1897 while (isalpha(ptr
[i
]) || ptr
[i
]=='_') {
1898 *pv
= ptr
[i
]; pv
++; i
++;
1901 if (strlen(varname
)<1 || !(value
= getenv(varname
))) {
1902 if ((value
= get_builtin_variable(varname
))) {
1903 // append value to the string
1904 for (pv
=(char *)value
; *pv
; pv
++)
1905 string
[string_i
++] = *pv
;
1907 BX_PANIC (("could not look up environment variable '%s'", varname
));
1910 // append value to the string
1911 for (pv
=(char *)value
; *pv
; pv
++)
1912 string
[string_i
++] = *pv
;
1916 if (!isspace(ptr
[i
]) || inquotes
) {
1917 string
[string_i
++] = ptr
[i
];
1921 string
[string_i
] = '\0';
1922 if (string_i
== 0) break;
1924 if (params
[num_params
] != NULL
) {
1925 free(params
[num_params
]);
1926 params
[num_params
] = NULL
;
1928 if (num_params
< MAX_PARAMS_LEN
) {
1929 params
[num_params
++] = strdup(string
);
1931 BX_PANIC (("too many parameters, max is %d\n", MAX_PARAMS_LEN
));
1934 ptr
= strtok(NULL
, ",");
1936 Bit32s retval
= parse_line_formatted(context
, num_params
, ¶ms
[0]);
1937 for (i
=0; i
< MAX_PARAMS_LEN
; i
++)
1939 if (params
[i
] != NULL
)
1948 // These macros are called for all parse errors, so that we can easily
1949 // change the behavior of all occurrences.
1950 #define PARSE_ERR(x) \
1951 do { BX_PANIC(x); return -1; } while (0)
1952 #define PARSE_WARN(x) \
1956 * this supports the "floppyx: image=" option.
1957 * the functions returns the type of the floppy
1958 * image (1.44, 360, etc.), based on the image file size.
1960 int get_floppy_type_from_image(const char *filename
)
1962 struct stat stat_buf
;
1964 if (stat(filename
, &stat_buf
))
1966 return BX_FLOPPY_NONE
;
1969 switch (stat_buf
.st_size
)
1972 return BX_FLOPPY_160K
;
1975 return BX_FLOPPY_180K
;
1978 return BX_FLOPPY_320K
;
1981 return BX_FLOPPY_360K
;
1984 return BX_FLOPPY_720K
;
1987 return BX_FLOPPY_1_2
;
1993 return BX_FLOPPY_1_44
;
1996 return BX_FLOPPY_2_88
;
1999 return BX_FLOPPY_UNKNOWN
;
2003 static Bit32s
parse_log_options(const char *context
, char *loglev
, char *param1
)
2007 if (!strcmp(loglev
, "panic")) {
2008 level
= LOGLEV_PANIC
;
2009 } else if (!strcmp(loglev
, "pass")) {
2010 level
= LOGLEV_PASS
;
2011 } else if (!strcmp(loglev
, "error")) {
2012 level
= LOGLEV_ERROR
;
2013 } else if (!strcmp(loglev
, "info")) {
2014 level
= LOGLEV_INFO
;
2015 } else { /* debug */
2016 level
= LOGLEV_DEBUG
;
2018 if (strncmp(param1
, "action=", 7)) {
2019 PARSE_ERR(("%s: %s directive malformed.", context
, loglev
));
2021 char *action
= param1
+ 7;
2022 if (!strcmp(action
, "fatal"))
2023 SIM
->set_default_log_action(level
, ACT_FATAL
);
2024 else if (!strcmp (action
, "report"))
2025 SIM
->set_default_log_action(level
, ACT_REPORT
);
2026 else if (!strcmp (action
, "ignore"))
2027 SIM
->set_default_log_action(level
, ACT_IGNORE
);
2028 else if (!strcmp (action
, "ask"))
2029 SIM
->set_default_log_action(level
, ACT_ASK
);
2031 PARSE_ERR(("%s: %s directive malformed.", context
, loglev
));
2036 static int parse_debug_symbols(const char *context
, char **params
, int num_params
)
2042 while (num_params
> 0)
2044 if (!strncmp(*params
, "file=", 5)) {
2045 filename
= *params
+ 5;
2047 else if (!strncmp(*params
, "offset=", 7)) {
2049 offset
= strtoul(*params
+ 7, &end
, 0);
2051 PARSE_ERR(("%s: debug_symbols: invalid parameter %s", context
, *params
));
2054 PARSE_ERR(("%s: debug_symbols: invalid parameter %s", context
, *params
));
2056 params
++; num_params
--;
2060 PARSE_ERR(("%s: debug_symbols: missing file name", context
));
2062 if (bx_dbg_symbol_command(filename
, 1, offset
) < 0)
2063 PARSE_ERR(("%s: debug_symbols: failed to load symbols from '%s'", context
, filename
));
2068 static int parse_line_formatted(const char *context
, int num_params
, char *params
[])
2074 if (num_params
< 1) return 0;
2075 if (num_params
< 2) {
2076 PARSE_ERR(("%s: a bochsrc option needs at least one parameter", context
));
2079 if (!strcmp(params
[0], "#include")) {
2080 if (num_params
!= 2) {
2081 PARSE_ERR(("%s: ignoring malformed #include directive.", context
));
2083 if (!strcmp(params
[1], context
)) {
2084 PARSE_ERR(("%s: cannot include this file again.", context
));
2086 if (bochsrc_include_count
== 2) {
2087 PARSE_ERR(("%s: include directive in an included file not supported yet.", context
));
2089 bx_read_configuration(params
[1]);
2091 else if (!strcmp(params
[0], "floppya")) {
2092 for (i
=1; i
<num_params
; i
++) {
2093 if (!strncmp(params
[i
], "2_88=", 5)) {
2094 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2095 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_2_88
);
2097 else if (!strncmp(params
[i
], "1_44=", 5)) {
2098 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2099 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_1_44
);
2101 else if (!strncmp(params
[i
], "1_2=", 4)) {
2102 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][4]);
2103 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_1_2
);
2105 else if (!strncmp(params
[i
], "720k=", 5)) {
2106 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2107 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_720K
);
2109 else if (!strncmp(params
[i
], "360k=", 5)) {
2110 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2111 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_360K
);
2113 // use CMOS reserved types?
2114 else if (!strncmp(params
[i
], "160k=", 5)) {
2115 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2116 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_160K
);
2118 else if (!strncmp(params
[i
], "180k=", 5)) {
2119 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2120 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_180K
);
2122 else if (!strncmp(params
[i
], "320k=", 5)) {
2123 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][5]);
2124 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(BX_FLOPPY_320K
);
2126 else if (!strncmp(params
[i
], "image=", 6)) {
2127 /* "image=" means we should get floppy type from image */
2128 SIM
->get_param_string(BXPN_FLOPPYA_PATH
)->set(¶ms
[i
][6]);
2129 t
= get_floppy_type_from_image(¶ms
[i
][6]);
2130 if (t
!= BX_FLOPPY_UNKNOWN
)
2131 SIM
->get_param_enum(BXPN_FLOPPYA_TYPE
)->set(t
);
2133 PARSE_ERR(("%s: floppya image size doesn't match one of the supported types.", context
));
2135 else if (!strncmp(params
[i
], "status=", 7)) {
2136 SIM
->get_param_enum(BXPN_FLOPPYA_STATUS
)->set_by_name(¶ms
[i
][7]);
2139 PARSE_ERR(("%s: floppya attribute '%s' not understood.", context
,
2145 else if (!strcmp(params
[0], "floppyb")) {
2146 for (i
=1; i
<num_params
; i
++) {
2147 if (!strncmp(params
[i
], "2_88=", 5)) {
2148 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2149 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_2_88
);
2151 else if (!strncmp(params
[i
], "1_44=", 5)) {
2152 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2153 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_1_44
);
2155 else if (!strncmp(params
[i
], "1_2=", 4)) {
2156 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][4]);
2157 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_1_2
);
2159 else if (!strncmp(params
[i
], "720k=", 5)) {
2160 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2161 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_720K
);
2163 else if (!strncmp(params
[i
], "360k=", 5)) {
2164 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2165 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_360K
);
2167 // use CMOS reserved types?
2168 else if (!strncmp(params
[i
], "160k=", 5)) {
2169 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2170 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_160K
);
2172 else if (!strncmp(params
[i
], "180k=", 5)) {
2173 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2174 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_180K
);
2176 else if (!strncmp(params
[i
], "320k=", 5)) {
2177 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][5]);
2178 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(BX_FLOPPY_320K
);
2180 else if (!strncmp(params
[i
], "image=", 6)) {
2181 /* "image=" means we should get floppy type from image */
2182 SIM
->get_param_string(BXPN_FLOPPYB_PATH
)->set(¶ms
[i
][6]);
2183 t
= get_floppy_type_from_image(¶ms
[i
][6]);
2184 if (t
!= BX_FLOPPY_UNKNOWN
)
2185 SIM
->get_param_enum(BXPN_FLOPPYB_TYPE
)->set(t
);
2187 PARSE_ERR(("%s: floppyb image size doesn't match one of the supported types.", context
));
2189 else if (!strncmp(params
[i
], "status=", 7)) {
2190 SIM
->get_param_enum(BXPN_FLOPPYB_STATUS
)->set_by_name(¶ms
[i
][7]);
2193 PARSE_ERR(("%s: floppyb attribute '%s' not understood.", context
,
2199 else if ((!strncmp(params
[0], "ata", 3)) && (strlen(params
[0]) == 4)) {
2201 Bit8u channel
= params
[0][3];
2203 if ((channel
< '0') || (channel
> '9')) {
2204 PARSE_ERR(("%s: ataX directive malformed.", context
));
2207 if (channel
>= BX_MAX_ATA_CHANNEL
) {
2208 PARSE_ERR(("%s: ataX directive malformed.", context
));
2211 if ((num_params
< 2) || (num_params
> 5)) {
2212 PARSE_ERR(("%s: ataX directive malformed.", context
));
2214 sprintf(tmpname
, "ata.%d.resources", channel
);
2215 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2216 if (strncmp(params
[1], "enabled=", 8)) {
2217 PARSE_ERR(("%s: ataX directive malformed.", context
));
2219 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[1][8]));
2222 if (num_params
> 2) {
2223 if (strncmp(params
[2], "ioaddr1=", 8)) {
2224 PARSE_ERR(("%s: ataX directive malformed.", context
));
2227 if ((params
[2][8] == '0') && (params
[2][9] == 'x'))
2228 SIM
->get_param_num("ioaddr1", base
)->set(strtoul(¶ms
[2][8], NULL
, 16));
2230 SIM
->get_param_num("ioaddr1", base
)->set(strtoul(¶ms
[2][8], NULL
, 10));
2234 if (num_params
> 3) {
2235 if (strncmp(params
[3], "ioaddr2=", 8)) {
2236 PARSE_ERR(("%s: ataX directive malformed.", context
));
2239 if ((params
[3][8] == '0') && (params
[3][9] == 'x'))
2240 SIM
->get_param_num("ioaddr2", base
)->set(strtoul(¶ms
[3][8], NULL
, 16));
2242 SIM
->get_param_num("ioaddr2", base
)->set(strtoul(¶ms
[3][8], NULL
, 10));
2246 if (num_params
> 4) {
2247 if (strncmp(params
[4], "irq=", 4)) {
2248 PARSE_ERR(("%s: ataX directive malformed.", context
));
2251 SIM
->get_param_num("irq", base
)->set(atol(¶ms
[4][4]));
2256 // ataX-master, ataX-slave
2257 else if ((!strncmp(params
[0], "ata", 3)) && (strlen(params
[0]) > 4)) {
2258 Bit8u channel
= params
[0][3];
2259 int type
= 0, mode
= BX_ATA_MODE_FLAT
, biosdetect
= BX_ATA_BIOSDETECT_AUTO
;
2260 Bit32u cylinders
= 0, heads
= 0, sectors
= 0;
2263 if ((channel
< '0') || (channel
> '9')) {
2264 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2267 if (channel
>= BX_MAX_ATA_CHANNEL
) {
2268 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2271 if ((strcmp(¶ms
[0][4], "-slave")) &&
2272 (strcmp(¶ms
[0][4], "-master"))) {
2273 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2276 sprintf(tmpname
, "ata.%d.%s", channel
, ¶ms
[0][5]);
2277 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2278 for (i
=1; i
<num_params
; i
++) {
2279 if (!strncmp(params
[i
], "type=", 5)) {
2280 type
= SIM
->get_param_enum("type", base
)->find_by_name(¶ms
[i
][5]);
2282 PARSE_ERR(("%s: ataX-master/slave: unknown type '%s'", context
, ¶ms
[i
][5]));
2284 } else if (!strcmp(params
[i
], "mode=z-undoable")) {
2285 PARSE_ERR(("%s: ataX-master/slave mode 'z-undoable' not implemented yet", context
));
2286 } else if (!strcmp(params
[i
], "mode=z-volatile")) {
2287 PARSE_ERR(("%s: ataX-master/slave mode 'z-volatile' not implemented yet", context
));
2288 } else if (!strncmp(params
[i
], "mode=", 5)) {
2289 mode
= SIM
->get_param_enum("mode", base
)->find_by_name(¶ms
[i
][5]);
2291 PARSE_ERR(("%s: ataX-master/slave: unknown mode '%s'", context
, ¶ms
[i
][5]));
2293 } else if (!strncmp(params
[i
], "path=", 5)) {
2294 SIM
->get_param_string("path", base
)->set(¶ms
[i
][5]);
2295 } else if (!strncmp(params
[i
], "cylinders=", 10)) {
2296 cylinders
= atol(¶ms
[i
][10]);
2297 } else if (!strncmp(params
[i
], "heads=", 6)) {
2298 heads
= atol(¶ms
[i
][6]);
2299 } else if (!strncmp(params
[i
], "spt=", 4)) {
2300 sectors
= atol(¶ms
[i
][4]);
2301 } else if (!strncmp(params
[i
], "model=", 6)) {
2302 SIM
->get_param_string("model", base
)->set(¶ms
[i
][6]);
2303 } else if (!strncmp(params
[i
], "biosdetect=", 11)) {
2304 biosdetect
= SIM
->get_param_enum("biosdetect", base
)->find_by_name(¶ms
[i
][11]);
2305 if (biosdetect
< 0) {
2306 PARSE_ERR(("%s: ataX-master/slave: unknown biosdetect '%s'", context
, ¶ms
[i
][11]));
2308 } else if (!strcmp(params
[i
], "translation=none")) {
2309 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_NONE
);
2310 } else if (!strcmp(params
[i
], "translation=lba")) {
2311 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LBA
);
2312 } else if (!strcmp(params
[i
], "translation=large")) {
2313 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LARGE
);
2314 } else if (!strcmp(params
[i
], "translation=echs")) { // synonym of large
2315 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_LARGE
);
2316 } else if (!strcmp(params
[i
], "translation=rechs")) {
2317 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_RECHS
);
2318 } else if (!strcmp(params
[i
], "translation=auto")) {
2319 SIM
->get_param_enum("translation", base
)->set(BX_ATA_TRANSLATION_AUTO
);
2320 } else if (!strcmp(params
[i
], "status=ejected")) {
2321 SIM
->get_param_enum("status", base
)->set(BX_EJECTED
);
2322 } else if (!strcmp(params
[i
], "status=inserted")) {
2323 SIM
->get_param_enum("status", base
)->set(BX_INSERTED
);
2324 } else if (!strncmp(params
[i
], "journal=", 8)) {
2325 SIM
->get_param_string("journal", base
)->set(¶ms
[i
][8]);
2327 PARSE_ERR(("%s: ataX-master/slave directive malformed.", context
));
2331 // Enables the ata device
2332 if (strlen(SIM
->get_param_string("path", base
)->getptr()) > 0) {
2333 SIM
->get_param_bool("present", base
)->set(1);
2334 SIM
->get_param_enum("type", base
)->set(type
);
2335 SIM
->get_param_enum("mode", base
)->set(mode
);
2336 SIM
->get_param_num("cylinders", base
)->set(cylinders
);
2337 SIM
->get_param_num("heads", base
)->set(heads
);
2338 SIM
->get_param_num("spt", base
)->set(sectors
);
2339 SIM
->get_param_num("biosdetect", base
)->set(biosdetect
);
2341 SIM
->get_param_bool("present", base
)->set(0);
2344 // if enabled, check if device ok
2345 if (SIM
->get_param_bool("present", base
)->get() == 1) {
2346 if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_DISK
) {
2347 if ((SIM
->get_param_num("cylinders", base
)->get() == 0) &&
2348 (SIM
->get_param_num("heads", base
)->get() == 0) &&
2349 (SIM
->get_param_num("spt", base
)->get() == 0)) {
2350 PARSE_WARN(("%s: ataX-master/slave CHS set to 0/0/0 - autodetection enabled", context
));
2351 // using heads = 16 and spt = 63 for autodetection (bximage defaults)
2352 SIM
->get_param_num("heads", base
)->set(16);
2353 SIM
->get_param_num("spt", base
)->set(63);
2355 } else if (SIM
->get_param_enum("type", base
)->get() != BX_ATA_DEVICE_CDROM
) {
2356 PARSE_WARN(("%s: ataX-master/slave: type should be specified", context
));
2359 } else if (!strcmp(params
[0], "boot")) {
2361 if (num_params
< 2) {
2362 PARSE_ERR(("%s: boot directive malformed.", context
));
2364 for (i
=1; i
<num_params
; i
++) {
2365 sprintf(tmppath
, "boot_params.boot_drive%d", i
);
2366 if (!strcmp(params
[i
], "none")) {
2367 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_NONE
);
2368 } else if (!strcmp(params
[i
], "a")) {
2369 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_FLOPPYA
);
2370 } else if (!strcmp(params
[i
], "floppy")) {
2371 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_FLOPPYA
);
2372 } else if (!strcmp(params
[i
], "c")) {
2373 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_DISKC
);
2374 } else if (!strcmp(params
[i
], "disk")) {
2375 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_DISKC
);
2376 } else if (!strcmp(params
[i
], "cdrom")) {
2377 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_CDROM
);
2378 } else if (!strcmp(params
[i
], "network")) {
2379 SIM
->get_param_enum(tmppath
)->set(BX_BOOT_NETWORK
);
2381 PARSE_ERR(("%s: boot directive with unknown boot drive '%s'. use 'floppy', 'disk', 'cdrom' or 'network'.", context
, params
[i
]));
2384 if (SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == BX_BOOT_NONE
) {
2385 PARSE_ERR(("%s: first boot drive must be one of 'floppy', 'disk' or 'cdrom'.", context
));
2387 if ((SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE2
)->get()) ||
2388 (SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get()) ||
2389 ((SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get() != BX_BOOT_NONE
) &&
2390 (SIM
->get_param_enum(BXPN_BOOTDRIVE2
)->get() == SIM
->get_param_enum(BXPN_BOOTDRIVE3
)->get()))) {
2391 PARSE_ERR(("%s: a boot drive appears twice in boot sequence.", context
));
2393 } else if (!strcmp(params
[0], "floppy_bootsig_check")) {
2394 if (num_params
!= 2) {
2395 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2397 if (strncmp(params
[1], "disabled=", 9)) {
2398 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2400 if (params
[1][9] == '0')
2401 SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->set(0);
2402 else if (params
[1][9] == '1')
2403 SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->set(1);
2405 PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context
));
2407 } else if (!strcmp(params
[0], "log")) {
2408 if (num_params
!= 2) {
2409 PARSE_ERR(("%s: log directive has wrong # args.", context
));
2411 SIM
->get_param_string(BXPN_LOG_FILENAME
)->set(params
[1]);
2412 } else if (!strcmp(params
[0], "logprefix")) {
2413 if (num_params
!= 2) {
2414 PARSE_ERR(("%s: logprefix directive has wrong # args.", context
));
2416 SIM
->get_param_string(BXPN_LOG_PREFIX
)->set(params
[1]);
2417 } else if (!strcmp(params
[0], "debugger_log")) {
2418 if (num_params
!= 2) {
2419 PARSE_ERR(("%s: debugger_log directive has wrong # args.", context
));
2421 SIM
->get_param_string(BXPN_DEBUGGER_LOG_FILENAME
)->set(params
[1]);
2422 } else if (!strcmp(params
[0], "panic")) {
2423 if (num_params
!= 2) {
2424 PARSE_ERR(("%s: panic directive malformed.", context
));
2426 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2429 } else if (!strcmp(params
[0], "pass")) {
2430 if (num_params
!= 2) {
2431 PARSE_ERR(("%s: pass directive malformed.", context
));
2433 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2436 } else if (!strcmp(params
[0], "error")) {
2437 if (num_params
!= 2) {
2438 PARSE_ERR(("%s: error directive malformed.", context
));
2440 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2443 } else if (!strcmp(params
[0], "info")) {
2444 if (num_params
!= 2) {
2445 PARSE_ERR(("%s: info directive malformed.", context
));
2447 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2450 } else if (!strcmp(params
[0], "debug")) {
2451 if (num_params
!= 2) {
2452 PARSE_ERR(("%s: debug directive malformed.", context
));
2454 if (parse_log_options(context
, params
[0], params
[1]) < 0) {
2457 } else if (!strcmp(params
[0], "cpu")) {
2458 if (num_params
< 2) {
2459 PARSE_ERR(("%s: cpu directive malformed.", context
));
2461 for (i
=1; i
<num_params
; i
++) {
2462 if (!strncmp(params
[i
], "count=", 6)) {
2463 unsigned processors
= 1, cores
= 1, threads
= 1;
2464 sscanf(¶ms
[i
][6], "%u:%u:%u", &processors
, &cores
, &threads
);
2465 unsigned smp_threads
= cores
*threads
*processors
;
2466 if (smp_threads
> BX_MAX_SMP_THREADS_SUPPORTED
) {
2467 PARSE_ERR(("%s: too many SMP threads defined, only %u threads supported",
2468 context
, BX_MAX_SMP_THREADS_SUPPORTED
));
2470 if (smp_threads
< 1) {
2471 PARSE_ERR(("%s: at least one CPU thread should be defined, cpu directive malformed", context
));
2473 SIM
->get_param_num(BXPN_CPU_NPROCESSORS
)->set(processors
);
2474 SIM
->get_param_num(BXPN_CPU_NCORES
)->set(cores
);
2475 SIM
->get_param_num(BXPN_CPU_NTHREADS
)->set(threads
);
2476 } else if (!strncmp(params
[i
], "ips=", 4)) {
2477 SIM
->get_param_num(BXPN_IPS
)->set(atol(¶ms
[i
][4]));
2478 if (SIM
->get_param_num(BXPN_IPS
)->get() < BX_MIN_IPS
) {
2479 PARSE_WARN(("%s: WARNING: ips is AWFULLY low!", context
));
2482 } else if (!strncmp(params
[i
], "quantum=", 8)) {
2483 SIM
->get_param_num(BXPN_SMP_QUANTUM
)->set(atol(¶ms
[i
][8]));
2485 } else if (!strncmp(params
[i
], "reset_on_triple_fault=", 22)) {
2486 if (params
[i
][22] == '0' || params
[i
][22] == '1') {
2487 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->set(params
[i
][22] - '0');
2489 PARSE_ERR(("%s: cpu directive malformed.", context
));
2491 } else if (!strncmp(params
[i
], "cpuid_limit_winnt=", 18)) {
2492 if (params
[i
][18] == '0' || params
[i
][18] == '1') {
2493 SIM
->get_param_bool(BXPN_CPUID_LIMIT_WINNT
)->set(params
[i
][18] - '0');
2495 PARSE_ERR(("%s: cpu directive malformed.", context
));
2497 } else if (!strncmp(params
[i
], "vendor_string=", 14)) {
2498 if (strlen(¶ms
[i
][14]) != BX_CPUID_VENDOR_LEN
) {
2499 PARSE_ERR(("%s: cpu directive malformed.", context
));
2501 SIM
->get_param_string(BXPN_VENDOR_STRING
)->set(¶ms
[i
][14]);
2502 } else if (!strncmp(params
[i
], "brand_string=", 13)) {
2503 if (strlen(¶ms
[i
][13]) > BX_CPUID_BRAND_LEN
) {
2504 PARSE_ERR(("%s: cpu directive malformed.", context
));
2506 SIM
->get_param_string(BXPN_BRAND_STRING
)->set(¶ms
[i
][13]);
2508 PARSE_ERR(("%s: cpu directive malformed.", context
));
2511 } else if (!strcmp(params
[0], "megs")) {
2512 if (num_params
!= 2) {
2513 PARSE_ERR(("%s: megs directive: wrong # args.", context
));
2515 SIM
->get_param_num(BXPN_MEM_SIZE
)->set(atol(params
[1]));
2516 } else if (!strcmp(params
[0], "romimage")) {
2517 if ((num_params
< 2) || (num_params
> 3)) {
2518 PARSE_ERR(("%s: romimage directive: wrong # args.", context
));
2520 if (!strncmp(params
[1], "file=", 5)) {
2521 SIM
->get_param_string(BXPN_ROM_PATH
)->set(¶ms
[1][5]);
2523 PARSE_ERR(("%s: romimage directive malformed.", context
));
2525 if (num_params
== 3) {
2526 if (!strncmp(params
[2], "address=", 8)) {
2527 if ((params
[2][8] == '0') && (params
[2][9] == 'x'))
2528 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(strtoul(¶ms
[2][8], NULL
, 16));
2530 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(strtoul(¶ms
[2][8], NULL
, 10));
2532 PARSE_ERR(("%s: romimage directive malformed.", context
));
2535 SIM
->get_param_num(BXPN_ROM_ADDRESS
)->set(0);
2537 } else if (!strcmp(params
[0], "vgaromimage")) {
2538 if (num_params
!= 2) {
2539 PARSE_ERR(("%s: vgaromimage directive: wrong # args.", context
));
2541 if (!strncmp(params
[1], "file=", 5)) {
2542 SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->set(¶ms
[1][5]);
2544 BX_INFO(("WARNING: syntax has changed, please use 'vgaromimage: file=...' now"));
2545 SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->set(params
[1]);
2547 } else if (!strncmp(params
[0], "optromimage", 11)) {
2548 int num
= atoi(¶ms
[0][11]);
2549 char tmppath
[80], tmpaddr
[80];
2550 if ((num
< 1) || (num
> BX_N_OPTROM_IMAGES
)) {
2551 PARSE_ERR(("%s: optromimage%d: not supported", context
, num
));
2553 if (num_params
!= 3) {
2554 PARSE_ERR(("%s: optromimage%d directive: wrong # args.", context
, num
));
2556 sprintf(tmppath
, "memory.optrom.%d.path", num
);
2557 sprintf(tmpaddr
, "memory.optrom.%d.addr", num
);
2558 for (i
=1; i
<num_params
; i
++) {
2559 if (!strncmp(params
[i
], "file=", 5)) {
2560 SIM
->get_param_string(tmppath
)->set(¶ms
[i
][5]);
2561 } else if (!strncmp(params
[i
], "address=", 8)) {
2562 if ((params
[i
][8] == '0') && (params
[2][9] == 'x'))
2563 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 16));
2565 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 10));
2567 PARSE_ERR(("%s: optromimage%d directive malformed.", context
, num
));
2570 } else if (!strncmp(params
[0], "optramimage", 11)) {
2571 int num
= atoi(¶ms
[0][11]);
2572 char tmppath
[80], tmpaddr
[80];
2573 if ((num
< 1) || (num
> BX_N_OPTRAM_IMAGES
)) {
2574 PARSE_ERR(("%s: optramimage%d: not supported", context
, num
));
2576 if (num_params
!= 3) {
2577 PARSE_ERR(("%s: optramimage%d directive: wrong # args.", context
, num
));
2579 sprintf(tmppath
, "memory.optram.%d.path", num
);
2580 sprintf(tmpaddr
, "memory.optram.%d.addr", num
);
2581 for (i
=1; i
<num_params
; i
++) {
2582 if (!strncmp(params
[i
], "file=", 5)) {
2583 SIM
->get_param_string(tmppath
)->set(¶ms
[i
][5]);
2584 } else if (!strncmp(params
[i
], "address=", 8)) {
2585 if ((params
[i
][8] == '0') && (params
[2][9] == 'x'))
2586 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 16));
2588 SIM
->get_param_num(tmpaddr
)->set(strtoul(¶ms
[i
][8], NULL
, 10));
2590 PARSE_ERR(("%s: optramimage%d directive malformed.", context
, num
));
2593 } else if (!strcmp(params
[0], "vga_update_interval")) {
2594 if (num_params
!= 2) {
2595 PARSE_ERR(("%s: vga_update_interval directive: wrong # args.", context
));
2597 SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->set(atol(params
[1]));
2598 if (SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->get() < 50000) {
2599 BX_INFO(("%s: vga_update_interval seems awfully small!", context
));
2601 } else if (!strcmp(params
[0], "vga")) {
2602 if (num_params
!= 2) {
2603 PARSE_ERR(("%s: vga directive: wrong # args.", context
));
2605 if (!strncmp(params
[1], "extension=", 10)) {
2606 SIM
->get_param_string(BXPN_VGA_EXTENSION
)->set(¶ms
[1][10]);
2608 } else if (!strcmp(params
[0], "keyboard_serial_delay")) {
2609 if (num_params
!= 2) {
2610 PARSE_ERR(("%s: keyboard_serial_delay directive: wrong # args.", context
));
2612 SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->set(atol(params
[1]));
2613 if (SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->get() < 5) {
2614 PARSE_ERR (("%s: keyboard_serial_delay not big enough!", context
));
2616 } else if (!strcmp(params
[0], "keyboard_paste_delay")) {
2617 if (num_params
!= 2) {
2618 PARSE_ERR(("%s: keyboard_paste_delay directive: wrong # args.", context
));
2620 SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->set(atol(params
[1]));
2621 if (SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->get() < 1000) {
2622 PARSE_ERR (("%s: keyboard_paste_delay not big enough!", context
));
2624 } else if (!strcmp(params
[0], "ips")) {
2625 PARSE_WARN(("%s: ips directive is DEPRECATED (use cpu directive parameter 'ips').", context
));
2626 if (num_params
!= 2) {
2627 PARSE_ERR(("%s: ips directive: wrong # args.", context
));
2629 SIM
->get_param_num(BXPN_IPS
)->set(atol(params
[1]));
2630 if (SIM
->get_param_num(BXPN_IPS
)->get() < BX_MIN_IPS
) {
2631 PARSE_WARN(("%s: WARNING: ips is AWFULLY low!", context
));
2633 } else if (!strcmp(params
[0], "text_snapshot_check")) {
2634 if (num_params
!= 2) {
2635 PARSE_ERR(("%s: text_snapshot_check directive: wrong # args.", context
));
2637 if (!strncmp(params
[1], "enabled=", 8)) {
2638 if (params
[1][8] == '0' || params
[1][8] == '1')
2639 SIM
->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK
)->set(params
[1][8] - '0');
2641 PARSE_ERR(("%s: text_snapshot_check directive malformed.", context
));
2643 PARSE_ERR(("%s: text_snapshot_check directive malformed.", context
));
2645 } else if (!strcmp(params
[0], "mouse")) {
2646 if (num_params
< 2) {
2647 PARSE_ERR(("%s: mouse directive malformed.", context
));
2649 for (i
=1; i
<num_params
; i
++) {
2650 if (!strncmp(params
[i
], "enabled=", 8)) {
2651 if (params
[i
][8] == '0' || params
[i
][8] == '1')
2652 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
)->set(params
[i
][8] - '0');
2654 PARSE_ERR(("%s: mouse directive malformed.", context
));
2655 } else if (!strncmp(params
[i
], "type=", 5)) {
2656 if (!SIM
->get_param_enum(BXPN_MOUSE_TYPE
)->set_by_name(¶ms
[i
][5]))
2657 PARSE_ERR(("%s: mouse type '%s' not available", context
, ¶ms
[i
][5]));
2659 PARSE_ERR(("%s: mouse directive malformed.", context
));
2662 } else if (!strcmp(params
[0], "private_colormap")) {
2663 if (num_params
!= 2) {
2664 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2666 if (strncmp(params
[1], "enabled=", 8)) {
2667 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2669 if (params
[1][8] == '0' || params
[1][8] == '1')
2670 SIM
->get_param_bool(BXPN_PRIVATE_COLORMAP
)->set(params
[1][8] - '0');
2672 PARSE_ERR(("%s: private_colormap directive malformed.", context
));
2674 } else if (!strcmp(params
[0], "fullscreen")) {
2676 if (num_params
!= 2) {
2677 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2679 if (strncmp(params
[1], "enabled=", 8)) {
2680 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2682 if (params
[1][8] == '0' || params
[1][8] == '1') {
2683 SIM
->get_param_bool(BXPN_FULLSCREEN
)->set(params
[1][8] - '0');
2685 PARSE_ERR(("%s: fullscreen directive malformed.", context
));
2688 } else if (!strcmp(params
[0], "screenmode")) {
2690 if (num_params
!= 2) {
2691 PARSE_ERR(("%s: screenmode directive malformed.", context
));
2693 if (strncmp(params
[1], "name=", 5)) {
2694 PARSE_ERR(("%s: screenmode directive malformed.", context
));
2696 SIM
->get_param_string(BXPN_SCREENMODE
)->set(¶ms
[1][5]);
2698 } else if (!strcmp(params
[0], "sb16")) {
2700 base
= (bx_list_c
*) SIM
->get_param(BXPN_SB16
);
2701 for (i
=1; i
<num_params
; i
++) {
2702 if (!strncmp(params
[i
], "enabled=", 8)) {
2703 enable
= atol(¶ms
[i
][8]);
2704 } else if (!strncmp(params
[i
], "midi=", 5)) {
2705 SIM
->get_param_string("midifile", base
)->set(¶ms
[i
][5]);
2706 } else if (!strncmp(params
[i
], "midimode=", 9)) {
2707 SIM
->get_param_num("midimode", base
)->set(atol(¶ms
[i
][9]));
2708 } else if (!strncmp(params
[i
], "wave=", 5)) {
2709 SIM
->get_param_string("wavefile", base
)->set(¶ms
[i
][5]);
2710 } else if (!strncmp(params
[i
], "wavemode=", 9)) {
2711 SIM
->get_param_num("wavemode", base
)->set(atol(¶ms
[i
][9]));
2712 } else if (!strncmp(params
[i
], "log=", 4)) {
2713 SIM
->get_param_string("logfile", base
)->set(¶ms
[i
][4]);
2714 } else if (!strncmp(params
[i
], "loglevel=", 9)) {
2715 SIM
->get_param_num("loglevel", base
)->set(atol(¶ms
[i
][9]));
2716 } else if (!strncmp(params
[i
], "dmatimer=", 9)) {
2717 SIM
->get_param_num("dmatimer", base
)->set(atol(¶ms
[i
][9]));
2719 BX_ERROR(("%s: unknown parameter for sb16 ignored.", context
));
2722 if ((enable
!= 0) && (SIM
->get_param_num("dmatimer", base
)->get() > 0))
2723 SIM
->get_param_bool("enabled", base
)->set(1);
2725 SIM
->get_param_bool("enabled", base
)->set(0);
2726 } else if ((!strncmp(params
[0], "com", 3)) && (strlen(params
[0]) == 4)) {
2729 if ((idx
< '1') || (idx
> '9')) {
2730 PARSE_ERR(("%s: comX directive malformed.", context
));
2733 if (idx
> BX_N_SERIAL_PORTS
) {
2734 PARSE_ERR(("%s: comX port number out of range.", context
));
2736 sprintf(tmpname
, "ports.serial.%d", idx
);
2737 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2738 for (i
=1; i
<num_params
; i
++) {
2739 if (!strncmp(params
[i
], "enabled=", 8)) {
2740 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2741 } else if (!strncmp(params
[i
], "mode=", 5)) {
2742 if (!SIM
->get_param_enum("mode", base
)->set_by_name(¶ms
[i
][5]))
2743 PARSE_ERR(("%s: com%d serial port mode '%s' not available", context
, idx
, ¶ms
[i
][5]));
2744 SIM
->get_param_bool("enabled", base
)->set(1);
2745 } else if (!strncmp(params
[i
], "dev=", 4)) {
2746 SIM
->get_param_string("dev", base
)->set(¶ms
[i
][4]);
2747 SIM
->get_param_bool("enabled", base
)->set(1);
2749 PARSE_ERR(("%s: unknown parameter for com%d ignored.", context
, idx
));
2752 } else if ((!strncmp(params
[0], "parport", 7)) && (strlen(params
[0]) == 8)) {
2755 if ((idx
< '1') || (idx
> '9')) {
2756 PARSE_ERR(("%s: parportX directive malformed.", context
));
2759 if (idx
> BX_N_PARALLEL_PORTS
) {
2760 PARSE_ERR(("%s: parportX port number out of range.", context
));
2762 sprintf(tmpname
, "ports.parallel.%d", idx
);
2763 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2764 for (i
=1; i
<num_params
; i
++) {
2765 if (!strncmp(params
[i
], "enabled=", 8)) {
2766 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2767 } else if (!strncmp(params
[i
], "file=", 5)) {
2768 SIM
->get_param_string("outfile", base
)->set(¶ms
[i
][5]);
2769 SIM
->get_param_bool("enabled", base
)->set(1);
2771 BX_ERROR(("%s: unknown parameter for parport%d ignored.", context
, idx
));
2774 } else if ((!strncmp(params
[0], "usb", 3)) && (strlen(params
[0]) == 4)) {
2777 if ((idx
< '1') || (idx
> '9')) {
2778 PARSE_ERR(("%s: usbX directive malformed.", context
));
2781 if (idx
> BX_N_USB_HUBS
) {
2782 PARSE_ERR(("%s: usbX hub number out of range.", context
));
2784 sprintf(tmpname
, "ports.usb.%d", idx
);
2785 base
= (bx_list_c
*) SIM
->get_param(tmpname
);
2786 for (i
=1; i
<num_params
; i
++) {
2787 if (!strncmp(params
[i
], "enabled=", 8)) {
2788 SIM
->get_param_bool("enabled", base
)->set(atol(¶ms
[i
][8]));
2789 } else if (!strncmp(params
[i
], "port1=", 6)) {
2790 SIM
->get_param_string("port1", base
)->set(¶ms
[i
][6]);
2791 } else if (!strncmp(params
[i
], "option1=", 8)) {
2792 PARSE_WARN(("%s: usb port1 option is now deprecated", context
));
2793 } else if (!strncmp(params
[i
], "port2=", 6)) {
2794 SIM
->get_param_string("port2", base
)->set(¶ms
[i
][6]);
2795 } else if (!strncmp(params
[i
], "option2=", 8)) {
2796 PARSE_WARN(("%s: usb port2 option is now deprecated", context
));
2797 } else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2798 PARSE_WARN(("%s: usb ioaddr is now DEPRECATED (assigned by BIOS).", context
));
2799 } else if (!strncmp(params
[i
], "irq=", 4)) {
2800 PARSE_WARN(("%s: usb irq is now DEPRECATED (assigned by BIOS).", context
));
2802 PARSE_WARN(("%s: unknown parameter '%s' for usb%d ignored.", context
, params
[i
], idx
));
2805 } else if (!strcmp(params
[0], "i440fxsupport")) {
2807 for (i
=1; i
<num_params
; i
++) {
2808 if (!strncmp(params
[i
], "enabled=", 8)) {
2809 SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->set(atol(¶ms
[i
][8]));
2810 } else if ((!strncmp(params
[i
], "slot", 4)) && (params
[i
][5] == '=')) {
2811 slot
= atol(¶ms
[i
][4]);
2812 if ((slot
> 0) && (slot
< 6)) {
2813 sprintf(tmpdev
, "pci.slot.%d", slot
);
2814 SIM
->get_param_string(tmpdev
)->set(¶ms
[i
][6]);
2816 BX_ERROR(("%s: unknown pci slot number ignored.", context
));
2819 PARSE_ERR(("%s: i440fxsupport: unknown parameter '%s'.", context
, params
[i
]));
2822 } else if (!strcmp(params
[0], "pcidev")) {
2823 if (num_params
!= 3) {
2824 PARSE_ERR(("%s: pcidev directive malformed.", context
));
2826 for (i
=1; i
<num_params
; i
++) {
2827 if (!strncmp(params
[i
], "vendor=", 7)) {
2828 if ((params
[i
][7] == '0') && (toupper(params
[i
][8]) == 'X'))
2829 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2831 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->set(strtoul(¶ms
[i
][7], NULL
, 10));
2833 else if (!strncmp(params
[i
], "device=", 7)) {
2834 if ((params
[i
][7] == '0') && (toupper(params
[i
][8]) == 'X'))
2835 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2837 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->set(strtoul(¶ms
[i
][7], NULL
, 10));
2840 BX_ERROR(("%s: unknown parameter for pcidev ignored.", context
));
2843 } else if (!strcmp(params
[0], "cmosimage")) {
2844 for (i
=1; i
<num_params
; i
++) {
2845 if (!strncmp(params
[i
], "file=", 5)) {
2846 SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->set(¶ms
[i
][5]);
2847 } else if (!strcmp(params
[i
], "rtc_init=time0")) {
2848 SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->set(0);
2849 } else if (!strcmp(params
[i
], "rtc_init=image")) {
2850 SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->set(1);
2852 // for backward compatiblity
2853 SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->set(params
[i
]);
2856 if (strlen(SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr()) > 0) {
2857 SIM
->get_param_bool(BXPN_CMOSIMAGE_ENABLED
)->set(1);
2859 } else if (!strcmp(params
[0], "clock")) {
2860 for (i
=1; i
<num_params
; i
++) {
2861 if (!strncmp(params
[i
], "sync=", 5)) {
2862 SIM
->get_param_enum(BXPN_CLOCK_SYNC
)->set_by_name(¶ms
[i
][5]);
2864 else if (!strcmp(params
[i
], "time0=local")) {
2865 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(BX_CLOCK_TIME0_LOCAL
);
2867 else if (!strcmp(params
[i
], "time0=utc")) {
2868 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(BX_CLOCK_TIME0_UTC
);
2870 else if (!strncmp(params
[i
], "time0=", 6)) {
2871 SIM
->get_param_num(BXPN_CLOCK_TIME0
)->set(atoi(¶ms
[i
][6]));
2874 BX_ERROR(("%s: unknown parameter for clock ignored.", context
));
2878 else if (!strcmp(params
[0], "gdbstub")) {
2880 if (num_params
< 2) {
2881 PARSE_ERR(("%s: gdbstub directive: wrong # args.", context
));
2883 base
= (bx_list_c
*) SIM
->get_param(BXPN_GDBSTUB
);
2884 for (i
=1; i
<num_params
; i
++) {
2885 if (!strncmp(params
[i
], "enabled=", 8)) {
2886 if (params
[i
][8] == '0') {
2887 SIM
->get_param_bool("enabled", base
)->set(0);
2888 BX_INFO(("Disabled gdbstub"));
2889 bx_dbg
.gdbstub_enabled
= 0;
2891 else if (params
[i
][8] == '1') {
2892 SIM
->get_param_bool("enabled", base
)->set(1);
2893 BX_INFO(("Enabled gdbstub"));
2894 bx_dbg
.gdbstub_enabled
= 1;
2897 PARSE_ERR(("%s: gdbstub directive malformed.", context
));
2900 else if (!strncmp(params
[i
], "port=", 5)) {
2901 SIM
->get_param_num("port", base
)->set(atoi(¶ms
[i
][5]));
2903 else if (!strncmp(params
[i
], "text_base=", 10)) {
2904 SIM
->get_param_num("text_base", base
)->set(atoi(¶ms
[i
][10]));
2906 else if (!strncmp(params
[i
], "data_base=", 10)) {
2907 SIM
->get_param_num("data_base", base
)->set(atoi(¶ms
[i
][10]));
2909 else if (!strncmp(params
[i
], "bss_base=", 9)) {
2910 SIM
->get_param_num("bss_base", base
)->set(atoi(¶ms
[i
][9]));
2913 PARSE_ERR(("%s: gdbstub directive malformed.", context
));
2917 PARSE_ERR(("%s: Bochs is not compiled with gdbstub support", context
));
2920 else if (!strcmp(params
[0], "magic_break")) {
2922 if (num_params
!= 2) {
2923 PARSE_ERR(("%s: magic_break directive: wrong # args.", context
));
2925 if (strncmp(params
[1], "enabled=", 8)) {
2926 PARSE_ERR(("%s: magic_break directive malformed.", context
));
2928 if (params
[1][8] == '0') {
2929 BX_INFO(("Ignoring magic break points"));
2930 bx_dbg
.magic_break_enabled
= 0;
2932 else if (params
[1][8] == '1') {
2933 BX_INFO(("Stopping on magic break points"));
2934 bx_dbg
.magic_break_enabled
= 1;
2937 PARSE_ERR(("%s: magic_break directive malformed.", context
));
2940 PARSE_ERR(("%s: Bochs is not compiled with internal debugger support", context
));
2943 else if (!strcmp(params
[0], "debug_symbols")) {
2944 if (parse_debug_symbols(context
, params
+ 1, num_params
- 1) < 0) {
2948 else if (!strcmp(params
[0], "print_timestamps")) {
2949 if (num_params
!= 2) {
2950 PARSE_ERR(("%s: print_timestamps directive: wrong # args.", context
));
2952 if (strncmp(params
[1], "enabled=", 8)) {
2953 PARSE_ERR(("%s: print_timestamps directive malformed.", context
));
2955 if (params
[1][8] == '0' || params
[1][8] == '1') {
2956 bx_dbg
.print_timestamps
= params
[1][8] - '0';
2959 PARSE_ERR(("%s: print_timestamps directive malformed.", context
));
2962 else if (!strcmp(params
[0], "ne2k")) {
2967 base
= (bx_list_c
*) SIM
->get_param(BXPN_NE2K
);
2968 if (!SIM
->get_param_bool("enabled", base
)->get()) {
2969 SIM
->get_param_enum("ethmod", base
)->set_by_name("null");
2971 for (i
=1; i
<num_params
; i
++) {
2972 if (!strncmp(params
[i
], "enabled=", 8)) {
2973 if (atol(¶ms
[i
][8]) == 0) valid
|= 0x80;
2975 else if (!strncmp(params
[i
], "ioaddr=", 7)) {
2976 SIM
->get_param_num("ioaddr", base
)->set(strtoul(¶ms
[i
][7], NULL
, 16));
2979 else if (!strncmp(params
[i
], "irq=", 4)) {
2980 SIM
->get_param_num("irq", base
)->set(atol(¶ms
[i
][4]));
2983 else if (!strncmp(params
[i
], "mac=", 4)) {
2984 n
= sscanf(¶ms
[i
][4], "%x:%x:%x:%x:%x:%x",
2985 &tmp
[0],&tmp
[1],&tmp
[2],&tmp
[3],&tmp
[4],&tmp
[5]);
2987 PARSE_ERR(("%s: ne2k mac address malformed.", context
));
2990 tmpchar
[n
] = (unsigned char)tmp
[n
];
2991 SIM
->get_param_string("macaddr", base
)->set(tmpchar
);
2994 else if (!strncmp(params
[i
], "ethmod=", 7)) {
2995 if (!SIM
->get_param_enum("ethmod", base
)->set_by_name(¶ms
[i
][7]))
2996 PARSE_ERR(("%s: ethernet module '%s' not available", context
, ¶ms
[i
][7]));
2998 else if (!strncmp(params
[i
], "ethdev=", 7)) {
2999 SIM
->get_param_string("ethdev", base
)->set(¶ms
[i
][7]);
3001 else if (!strncmp(params
[i
], "script=", 7)) {
3002 SIM
->get_param_string("script", base
)->set(¶ms
[i
][7]);
3005 PARSE_WARN(("%s: unknown parameter '%s' for ne2k ignored.", context
, params
[i
]));
3008 if (!SIM
->get_param_bool("enabled", base
)->get()) {
3009 if (valid
== 0x07) {
3010 SIM
->get_param_bool("enabled", base
)->set(1);
3011 } else if (valid
< 0x80) {
3012 PARSE_ERR(("%s: ne2k directive incomplete (ioaddr, irq and mac are required)", context
));
3016 SIM
->get_param_bool("enabled", base
)->set(0);
3019 } else if (!strcmp(params
[0], "pnic")) {
3024 base
= (bx_list_c
*) SIM
->get_param(BXPN_PNIC
);
3025 if (!SIM
->get_param_bool("enabled", base
)->get()) {
3026 SIM
->get_param_enum("ethmod", base
)->set_by_name("null");
3028 for (i
=1; i
<num_params
; i
++) {
3029 if (!strncmp(params
[i
], "enabled=", 8)) {
3030 if (atol(¶ms
[i
][8]) == 0) valid
|= 0x80;
3031 } else if (!strncmp(params
[i
], "ioaddr=", 7)) {
3032 PARSE_WARN(("%s: pnic ioaddr is now DEPRECATED (assigned by BIOS).", context
));
3033 } else if (!strncmp(params
[i
], "irq=", 4)) {
3034 PARSE_WARN(("%s: pnic irq is now DEPRECATED (assigned by BIOS).", context
));
3035 } else if (!strncmp(params
[i
], "mac=", 4)) {
3036 n
= sscanf(¶ms
[i
][4], "%x:%x:%x:%x:%x:%x",
3037 &tmp
[0],&tmp
[1],&tmp
[2],&tmp
[3],&tmp
[4],&tmp
[5]);
3039 PARSE_ERR(("%s: pnic mac address malformed.", context
));
3042 tmpchar
[n
] = (unsigned char)tmp
[n
];
3043 SIM
->get_param_string("macaddr", base
)->set(tmpchar
);
3045 } else if (!strncmp(params
[i
], "ethmod=", 7)) {
3046 if (!SIM
->get_param_enum("ethmod", base
)->set_by_name(¶ms
[i
][7]))
3047 PARSE_ERR(("%s: ethernet module '%s' not available", context
, ¶ms
[i
][7]));
3048 } else if (!strncmp(params
[i
], "ethdev=", 7)) {
3049 SIM
->get_param_string("ethdev", base
)->set(¶ms
[i
][7]);
3050 } else if (!strncmp(params
[i
], "script=", 7)) {
3051 SIM
->get_param_string("script", base
)->set(¶ms
[i
][7]);
3053 PARSE_WARN(("%s: unknown parameter '%s' for pnic ignored.", context
, params
[i
]));
3056 if (!SIM
->get_param_bool("enabled", base
)->get()) {
3057 if (valid
== 0x07) {
3058 SIM
->get_param_bool("enabled", base
)->set(1);
3059 } else if (valid
< 0x80) {
3060 PARSE_ERR(("%s: pnic directive incomplete (mac is required)", context
));
3064 SIM
->get_param_bool("enabled", base
)->set(0);
3067 } else if (!strcmp(params
[0], "load32bitOSImage")) {
3068 if ((num_params
!=4) && (num_params
!=5)) {
3069 PARSE_ERR(("%s: load32bitOSImage directive: wrong # args.", context
));
3071 if (strncmp(params
[1], "os=", 3)) {
3072 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
3074 if (!strcmp(¶ms
[1][3], "nullkernel")) {
3075 SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->set(Load32bitOSNullKernel
);
3077 else if (!strcmp(¶ms
[1][3], "linux")) {
3078 SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->set(Load32bitOSLinux
);
3081 PARSE_ERR(("%s: load32bitOSImage: unsupported OS.", context
));
3083 if (strncmp(params
[2], "path=", 5)) {
3084 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
3086 if (strncmp(params
[3], "iolog=", 6)) {
3087 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
3089 SIM
->get_param_string(BXPN_LOAD32BITOS_PATH
)->set(¶ms
[2][5]);
3090 SIM
->get_param_string(BXPN_LOAD32BITOS_IOLOG
)->set(¶ms
[3][6]);
3091 if (num_params
== 5) {
3092 if (strncmp(params
[4], "initrd=", 7)) {
3093 PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context
));
3095 SIM
->get_param_string(BXPN_LOAD32BITOS_INITRD
)->set(¶ms
[4][7]);
3098 else if (!strcmp(params
[0], "keyboard_type")) {
3099 if (num_params
!= 2) {
3100 PARSE_ERR(("%s: keyboard_type directive: wrong # args.", context
));
3102 if (!SIM
->get_param_enum(BXPN_KBD_TYPE
)->set_by_name(params
[1])) {
3103 PARSE_ERR(("%s: keyboard_type directive: wrong arg '%s'.", context
,params
[1]));
3106 else if (!strcmp(params
[0], "keyboard_mapping")
3107 ||!strcmp(params
[0], "keyboardmapping")) {
3108 for (i
=1; i
<num_params
; i
++) {
3109 if (!strncmp(params
[i
], "enabled=", 8)) {
3110 SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->set(atol(¶ms
[i
][8]));
3112 else if (!strncmp(params
[i
], "map=", 4)) {
3113 SIM
->get_param_string(BXPN_KBD_KEYMAP
)->set(¶ms
[i
][4]);
3117 else if (!strcmp(params
[0], "user_shortcut"))
3119 if (num_params
!= 2) {
3120 PARSE_ERR(("%s: user_shortcut directive: wrong # args.", context
));
3122 if(!strncmp(params
[1], "keys=", 4)) {
3123 SIM
->get_param_string(BXPN_USER_SHORTCUT
)->set(¶ms
[1][5]);
3124 if ((strchr(¶ms
[1][5], '-') == NULL
) && (strlen(¶ms
[1][5]) > 5))
3125 PARSE_WARN(("user_shortcut: old-style syntax detected"));
3127 PARSE_ERR(("%s: user_shortcut directive malformed.", context
));
3130 else if (!strcmp(params
[0], "config_interface"))
3132 if (num_params
!= 2) {
3133 PARSE_ERR(("%s: config_interface directive: wrong # args.", context
));
3135 if (!SIM
->get_param_enum(BXPN_SEL_CONFIG_INTERFACE
)->set_by_name(params
[1]))
3136 PARSE_ERR(("%s: config_interface '%s' not available", context
, params
[1]));
3138 else if (!strcmp(params
[0], "display_library")) {
3139 if ((num_params
< 2) || (num_params
> 3)) {
3140 PARSE_ERR(("%s: display_library directive: wrong # args.", context
));
3142 if (!SIM
->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY
)->set_by_name(params
[1]))
3143 PARSE_ERR(("%s: display library '%s' not available", context
, params
[1]));
3144 if (num_params
== 3) {
3145 if (!strncmp(params
[2], "options=", 8)) {
3146 SIM
->get_param_string(BXPN_DISPLAYLIB_OPTIONS
)->set(¶ms
[2][8]);
3150 // user-defined options handled by registered functions
3151 else if ((i
= SIM
->find_user_option(params
[0])) >= 0)
3153 return SIM
->parse_user_option(i
, context
, num_params
, ¶ms
[0]);
3157 PARSE_ERR(("%s: directive '%s' not understood", context
, params
[0]));
3163 static const char *fdtypes
[] = {
3164 "none", "1_2", "1_44", "2_88", "720k", "360k", "160k", "180k", "320k"
3167 int bx_write_floppy_options(FILE *fp
, int drive
)
3169 char path
[80], type
[80], status
[80];
3171 BX_ASSERT(drive
==0 || drive
==1);
3172 sprintf(path
, "floppy.%d.path", drive
);
3173 sprintf(type
, "floppy.%d.type", drive
);
3174 sprintf(status
, "floppy.%d.status", drive
);
3175 if (SIM
->get_param_enum(type
)->get() == BX_FLOPPY_NONE
) {
3176 fprintf(fp
, "# no floppy%c\n", (char)'a'+drive
);
3179 BX_ASSERT(SIM
->get_param_enum(type
)->get() > BX_FLOPPY_NONE
&&
3180 SIM
->get_param_enum(type
)->get() <= BX_FLOPPY_LAST
);
3181 fprintf(fp
, "floppy%c: %s=\"%s\", status=%s\n",
3183 fdtypes
[SIM
->get_param_enum(type
)->get() - BX_FLOPPY_NONE
],
3184 SIM
->get_param_string(path
)->getptr(),
3185 SIM
->get_param_enum(status
)->get_selected());
3189 int bx_write_ata_options(FILE *fp
, Bit8u channel
, bx_list_c
*base
)
3191 fprintf(fp
, "ata%d: enabled=%d", channel
, SIM
->get_param_bool("enabled", base
)->get());
3193 if (SIM
->get_param_bool("enabled", base
)->get()) {
3194 fprintf(fp
, ", ioaddr1=0x%x, ioaddr2=0x%x, irq=%d", SIM
->get_param_num("ioaddr1", base
)->get(),
3195 SIM
->get_param_num("ioaddr2", base
)->get(), SIM
->get_param_num("irq", base
)->get());
3202 int bx_write_atadevice_options(FILE *fp
, Bit8u channel
, Bit8u drive
, bx_list_c
*base
)
3204 if (SIM
->get_param_bool("present", base
)->get()) {
3205 fprintf(fp
, "ata%d-%s: ", channel
, drive
==0?"master":"slave");
3207 if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_DISK
) {
3208 fprintf(fp
, "type=disk");
3210 fprintf(fp
, ", mode=%s", SIM
->get_param_enum("mode", base
)->get_selected());
3211 fprintf(fp
, ", translation=%s", SIM
->get_param_enum("translation", base
)->get_selected());
3212 fprintf(fp
, ", path=\"%s\", cylinders=%d, heads=%d, spt=%d",
3213 SIM
->get_param_string("path", base
)->getptr(),
3214 SIM
->get_param_num("cylinders", base
)->get(),
3215 SIM
->get_param_num("heads", base
)->get(),
3216 SIM
->get_param_num("spt", base
)->get());
3218 if (SIM
->get_param_string("journal", base
)->getptr() != NULL
)
3219 if (strcmp(SIM
->get_param_string("journal", base
)->getptr(), "") != 0)
3220 fprintf(fp
, ", journal=\"%s\"", SIM
->get_param_string("journal", base
)->getptr());
3222 } else if (SIM
->get_param_enum("type", base
)->get() == BX_ATA_DEVICE_CDROM
) {
3223 fprintf(fp
, "type=cdrom, path=\"%s\", status=%s",
3224 SIM
->get_param_string("path", base
)->getptr(),
3225 SIM
->get_param_enum("status", base
)->get_selected());
3228 fprintf(fp
, ", biosdetect=%s", SIM
->get_param_enum("biosdetect", base
)->get_selected());
3230 if (SIM
->get_param_string("model", base
)->getptr()>0) {
3231 fprintf(fp
, ", model=\"%s\"", SIM
->get_param_string("model", base
)->getptr());
3239 int bx_write_parport_options(FILE *fp
, bx_list_c
*base
, int n
)
3241 fprintf(fp
, "parport%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3242 if (SIM
->get_param_bool("enabled", base
)->get()) {
3243 fprintf(fp
, ", file=\"%s\"", SIM
->get_param_string("outfile", base
)->getptr());
3249 int bx_write_serial_options(FILE *fp
, bx_list_c
*base
, int n
)
3251 fprintf(fp
, "com%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3252 if (SIM
->get_param_bool("enabled", base
)->get()) {
3253 fprintf(fp
, ", mode=%s", SIM
->get_param_enum("mode", base
)->get_selected());
3254 fprintf(fp
, ", dev=\"%s\"", SIM
->get_param_string("dev", base
)->getptr());
3260 int bx_write_usb_options(FILE *fp
, bx_list_c
*base
, int n
)
3262 fprintf(fp
, "usb%d: enabled=%d", n
, SIM
->get_param_bool("enabled", base
)->get());
3263 if (SIM
->get_param_bool("enabled", base
)->get()) {
3264 fprintf(fp
, ", port1=%s", SIM
->get_param_string("port1", base
)->getptr());
3265 fprintf(fp
, ", port2=%s", SIM
->get_param_string("port2", base
)->getptr());
3271 int bx_write_pnic_options(FILE *fp
, bx_list_c
*base
)
3273 fprintf (fp
, "pnic: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3274 if (SIM
->get_param_bool("enabled", base
)->get()) {
3275 char *ptr
= SIM
->get_param_string("macaddr", base
)->getptr();
3276 fprintf (fp
, ", mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s",
3277 (unsigned int)(0xff & ptr
[0]),
3278 (unsigned int)(0xff & ptr
[1]),
3279 (unsigned int)(0xff & ptr
[2]),
3280 (unsigned int)(0xff & ptr
[3]),
3281 (unsigned int)(0xff & ptr
[4]),
3282 (unsigned int)(0xff & ptr
[5]),
3283 SIM
->get_param_enum("ethmod", base
)->get_selected(),
3284 SIM
->get_param_string("ethdev", base
)->getptr(),
3285 SIM
->get_param_string("script", base
)->getptr());
3291 int bx_write_ne2k_options (FILE *fp
, bx_list_c
*base
)
3293 fprintf(fp
, "ne2k: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3294 if (SIM
->get_param_bool("enabled", base
)->get()) {
3295 char *ptr
= SIM
->get_param_string("macaddr", base
)->getptr();
3296 fprintf(fp
, ", ioaddr=0x%x, irq=%d, mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s",
3297 SIM
->get_param_num("ioaddr", base
)->get(),
3298 SIM
->get_param_num("irq", base
)->get(),
3299 (unsigned int)(0xff & ptr
[0]),
3300 (unsigned int)(0xff & ptr
[1]),
3301 (unsigned int)(0xff & ptr
[2]),
3302 (unsigned int)(0xff & ptr
[3]),
3303 (unsigned int)(0xff & ptr
[4]),
3304 (unsigned int)(0xff & ptr
[5]),
3305 SIM
->get_param_enum("ethmod", base
)->get_selected(),
3306 SIM
->get_param_string("ethdev", base
)->getptr(),
3307 SIM
->get_param_string("script", base
)->getptr());
3313 int bx_write_sb16_options (FILE *fp
, bx_list_c
*base
)
3315 fprintf(fp
, "sb16: enabled=%d", SIM
->get_param_bool("enabled", base
)->get());
3316 if (SIM
->get_param_bool("enabled", base
)->get()) {
3317 fprintf(fp
, ", midimode=%d, midi=%s, wavemode=%d, wave=%s, loglevel=%d, log=%s, dmatimer=%d",
3318 SIM
->get_param_num("midimode", base
)->get(),
3319 SIM
->get_param_string("midifile", base
)->getptr(),
3320 SIM
->get_param_num("wavemode", base
)->get(),
3321 SIM
->get_param_string("wavefile", base
)->getptr(),
3322 SIM
->get_param_num("loglevel", base
)->get(),
3323 SIM
->get_param_string("logfile", base
)->getptr(),
3324 SIM
->get_param_num("dmatimer", base
)->get());
3330 int bx_write_loader_options(FILE *fp
)
3332 if (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSNone
) {
3333 fprintf(fp
, "# no loader\n");
3336 BX_ASSERT((SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSLinux
) ||
3337 (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSNullKernel
));
3338 fprintf (fp
, "load32bitOSImage: os=%s, path=%s, iolog=%s, initrd=%s\n",
3339 (SIM
->get_param_enum(BXPN_LOAD32BITOS_WHICH
)->get() == Load32bitOSLinux
) ? "linux" : "nullkernel",
3340 SIM
->get_param_string(BXPN_LOAD32BITOS_PATH
)->getptr(),
3341 SIM
->get_param_string(BXPN_LOAD32BITOS_IOLOG
)->getptr(),
3342 SIM
->get_param_string(BXPN_LOAD32BITOS_INITRD
)->getptr());
3346 int bx_write_clock_cmos_options(FILE *fp
)
3348 fprintf(fp
, "clock: ");
3350 switch (SIM
->get_param_enum(BXPN_CLOCK_SYNC
)->get()) {
3351 case BX_CLOCK_SYNC_NONE
:
3352 fprintf(fp
, "sync=none");
3354 case BX_CLOCK_SYNC_REALTIME
:
3355 fprintf(fp
, "sync=realtime");
3357 case BX_CLOCK_SYNC_SLOWDOWN
:
3358 fprintf(fp
, "sync=slowdown");
3360 case BX_CLOCK_SYNC_BOTH
:
3361 fprintf(fp
, "sync=both");
3364 BX_PANIC(("Unknown value for sync method"));
3367 switch (SIM
->get_param_num(BXPN_CLOCK_TIME0
)->get()) {
3369 case BX_CLOCK_TIME0_LOCAL
:
3370 fprintf(fp
, ", time0=local");
3372 case BX_CLOCK_TIME0_UTC
:
3373 fprintf(fp
, ", time0=utc");
3376 fprintf(fp
, ", time0=%u", SIM
->get_param_num(BXPN_CLOCK_TIME0
)->get());
3381 if (strlen(SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr()) > 0) {
3382 fprintf(fp
, "cmosimage: file=%s, ", SIM
->get_param_string(BXPN_CMOSIMAGE_PATH
)->getptr());
3383 fprintf(fp
, "rtc_init=%s\n", SIM
->get_param_bool(BXPN_CMOSIMAGE_RTC_INIT
)->get()?"image":"time0");
3385 fprintf(fp
, "# no cmosimage\n");
3390 int bx_write_log_options(FILE *fp
, bx_list_c
*base
)
3392 fprintf(fp
, "log: %s\n", SIM
->get_param_string("filename", base
)->getptr());
3393 fprintf(fp
, "logprefix: %s\n", SIM
->get_param_string("prefix", base
)->getptr());
3395 fprintf(fp
, "debugger_log: %s\n", SIM
->get_param_string("debugger_filename", base
)->getptr());
3397 fprintf(fp
, "panic: action=%s\n",
3398 io
->getaction(logfunctions::get_default_action(LOGLEV_PANIC
)));
3399 fprintf(fp
, "error: action=%s\n",
3400 io
->getaction(logfunctions::get_default_action(LOGLEV_ERROR
)));
3401 fprintf(fp
, "info: action=%s\n",
3402 io
->getaction(logfunctions::get_default_action(LOGLEV_INFO
)));
3403 fprintf(fp
, "debug: action=%s\n",
3404 io
->getaction(logfunctions::get_default_action(LOGLEV_DEBUG
)));
3405 fprintf(fp
, "pass: action=%s\n",
3406 io
->getaction(logfunctions::get_default_action(LOGLEV_PASS
)));
3410 int bx_write_keyboard_options(FILE *fp
)
3412 fprintf(fp
, "keyboard_type: %s\n", SIM
->get_param_enum(BXPN_KBD_TYPE
)->get_selected());
3413 fprintf(fp
, "keyboard_serial_delay: %u\n", SIM
->get_param_num(BXPN_KBD_SERIAL_DELAY
)->get());
3414 fprintf(fp
, "keyboard_paste_delay: %u\n", SIM
->get_param_num(BXPN_KBD_PASTE_DELAY
)->get());
3415 fprintf(fp
, "keyboard_mapping: enabled=%d, map=%s\n",
3416 SIM
->get_param_bool(BXPN_KBD_USEMAPPING
)->get(),
3417 SIM
->get_param_string(BXPN_KBD_KEYMAP
)->getptr());
3418 fprintf(fp
, "user_shortcut: keys=%s\n", SIM
->get_param_string(BXPN_USER_SHORTCUT
)->getptr());
3425 // -2: already exists, and overwrite was off
3426 int bx_write_configuration(const char *rc
, int overwrite
)
3429 char *strptr
, tmppath
[80], tmpaddr
[80], tmpdev
[80];
3431 BX_INFO(("write current configuration to %s", rc
));
3432 // check if it exists. If so, only proceed if overwrite is set.
3433 FILE *fp
= fopen(rc
, "r");
3436 if (!overwrite
) return -2;
3438 fp
= fopen(rc
, "w");
3439 if (fp
== NULL
) return -1;
3440 // finally it's open and we can start writing.
3441 fprintf(fp
, "# configuration file generated by Bochs\n");
3442 fprintf(fp
, "config_interface: %s\n", SIM
->get_param_enum(BXPN_SEL_CONFIG_INTERFACE
)->get_selected());
3443 fprintf(fp
, "display_library: %s", SIM
->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY
)->get_selected());
3444 strptr
= SIM
->get_param_string(BXPN_DISPLAYLIB_OPTIONS
)->getptr();
3445 if (strlen(strptr
) > 0)
3446 fprintf(fp
, ", options=\"%s\"\n", strptr
);
3449 fprintf(fp
, "megs: %d\n", SIM
->get_param_num(BXPN_MEM_SIZE
)->get());
3450 strptr
= SIM
->get_param_string(BXPN_ROM_PATH
)->getptr();
3451 if (strlen(strptr
) > 0) {
3452 fprintf(fp
, "romimage: file=\"%s\"", strptr
);
3453 if (SIM
->get_param_num(BXPN_ROM_ADDRESS
)->get() != 0)
3454 fprintf(fp
, ", address=0x%08x\n", (unsigned int) SIM
->get_param_num(BXPN_ROM_ADDRESS
)->get());
3459 fprintf(fp
, "# no romimage\n");
3461 strptr
= SIM
->get_param_string(BXPN_VGA_ROM_PATH
)->getptr();
3462 if (strlen(strptr
) > 0)
3463 fprintf(fp
, "vgaromimage: file=\"%s\"\n", strptr
);
3465 fprintf(fp
, "# no vgaromimage\n");
3466 fprintf(fp
, "boot: %s", SIM
->get_param_enum(BXPN_BOOTDRIVE1
)->get_selected());
3467 for (i
=1; i
<3; i
++) {
3468 sprintf(tmppath
, "boot_params.boot_drive%d", i
+1);
3469 if (SIM
->get_param_enum(tmppath
)->get() != BX_BOOT_NONE
) {
3470 fprintf(fp
, ", %s", SIM
->get_param_enum(tmppath
)->get_selected());
3474 fprintf(fp
, "floppy_bootsig_check: disabled=%d\n", SIM
->get_param_bool(BXPN_FLOPPYSIGCHECK
)->get());
3475 // it would be nice to put this type of function as methods on
3476 // the structs like bx_floppy_options::print or something.
3477 bx_write_floppy_options(fp
, 0);
3478 bx_write_floppy_options(fp
, 1);
3479 for (Bit8u channel
=0; channel
<BX_MAX_ATA_CHANNEL
; channel
++) {
3480 sprintf(tmppath
, "ata.%d", channel
);
3481 base
= (bx_list_c
*) SIM
->get_param(tmppath
);
3482 bx_write_ata_options(fp
, channel
, (bx_list_c
*) SIM
->get_param("resources", base
));
3483 bx_write_atadevice_options(fp
, channel
, 0, (bx_list_c
*) SIM
->get_param("master", base
));
3484 bx_write_atadevice_options(fp
, channel
, 1, (bx_list_c
*) SIM
->get_param("slave", base
));
3486 for (i
=0; i
<BX_N_OPTROM_IMAGES
; i
++) {
3487 sprintf(tmppath
, "memory.optrom.%d.path", i
+1);
3488 sprintf(tmpaddr
, "memory.optrom.%d.addr", i
+1);
3489 strptr
= SIM
->get_param_string(tmppath
)->getptr();
3490 if (strlen(strptr
) > 0)
3491 fprintf(fp
, "optromimage%d: file=\"%s\", address=0x%05x\n", i
+1, strptr
,
3492 (unsigned int)SIM
->get_param_num(tmpaddr
)->get());
3494 for (i
=0; i
<BX_N_OPTRAM_IMAGES
; i
++) {
3495 sprintf(tmppath
, "memory.optram.%d.path", i
+1);
3496 sprintf(tmpaddr
, "memory.optram.%d.addr", i
+1);
3497 strptr
= SIM
->get_param_string(tmppath
)->getptr();
3498 if (strlen(strptr
) > 0)
3499 fprintf(fp
, "optramimage%d: file=\"%s\", address=0x%05x\n", i
+1, strptr
,
3500 (unsigned int)SIM
->get_param_num(tmpaddr
)->get());
3503 for (i
=0; i
<BX_N_PARALLEL_PORTS
; i
++) {
3504 sprintf(tmpdev
, "ports.parallel.%d", i
+1);
3505 base
= (bx_list_c
*) SIM
->get_param(tmpdev
);
3506 bx_write_parport_options(fp
, base
, i
+1);
3509 for (i
=0; i
<BX_N_SERIAL_PORTS
; i
++) {
3510 sprintf(tmpdev
, "ports.serial.%d", i
+1);
3511 base
= (bx_list_c
*) SIM
->get_param(tmpdev
);
3512 bx_write_serial_options(fp
, base
, i
+1);
3514 base
= (bx_list_c
*) SIM
->get_param("ports.usb.1");
3515 bx_write_usb_options(fp
, base
, 1);
3517 fprintf(fp
, "i440fxsupport: enabled=%d",
3518 SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get());
3519 if (SIM
->get_param_bool(BXPN_I440FX_SUPPORT
)->get()) {
3520 for (i
=0; i
<BX_N_PCI_SLOTS
; i
++) {
3521 sprintf(tmpdev
, "pci.slot.%d", i
+1);
3522 strptr
= SIM
->get_param_string(tmpdev
)->getptr();
3523 if (strlen(strptr
) > 0) {
3524 fprintf(fp
, ", slot%d=%s", i
+1, strptr
);
3529 if (SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->get() != 0xffff) {
3530 fprintf(fp
, "pcidev: vendor=0x%04x, device=0x%04x\n",
3531 SIM
->get_param_num(BXPN_PCIDEV_VENDOR
)->get(),
3532 SIM
->get_param_num(BXPN_PCIDEV_DEVICE
)->get());
3534 fprintf(fp
, "vga_update_interval: %u\n", SIM
->get_param_num(BXPN_VGA_UPDATE_INTERVAL
)->get());
3535 fprintf(fp
, "vga: extension=%s\n", SIM
->get_param_string(BXPN_VGA_EXTENSION
)->getptr());
3537 fprintf(fp
, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, reset_on_triple_fault=%d, cpuid_limit_winnt=%d\n",
3538 SIM
->get_param_num(BXPN_CPU_NPROCESSORS
)->get(), SIM
->get_param_num(BXPN_CPU_NCORES
)->get(),
3539 SIM
->get_param_num(BXPN_CPU_NTHREADS
)->get(), SIM
->get_param_num(BXPN_IPS
)->get(),
3540 SIM
->get_param_num(BXPN_SMP_QUANTUM
)->get(),
3541 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->get(),
3542 SIM
->get_param_bool(BXPN_CPUID_LIMIT_WINNT
)->get());
3544 fprintf(fp
, "cpu: count=1, ips=%u, reset_on_triple_fault=%d, cpuid_limit_winnt=%d\n",
3545 SIM
->get_param_num(BXPN_IPS
)->get(),
3546 SIM
->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT
)->get(),
3547 SIM
->get_param_bool(BXPN_CPUID_LIMIT_WINNT
)->get());
3549 fprintf(fp
, "text_snapshot_check: enabled=%d\n", SIM
->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK
)->get());
3550 fprintf(fp
, "private_colormap: enabled=%d\n", SIM
->get_param_bool(BXPN_PRIVATE_COLORMAP
)->get());
3552 fprintf(fp
, "fullscreen: enabled=%d\n", SIM
->get_param_bool(BXPN_FULLSCREEN
)->get());
3553 fprintf(fp
, "screenmode: name=\"%s\"\n", SIM
->get_param_string(BXPN_SCREENMODE
)->getptr());
3555 bx_write_clock_cmos_options(fp
);
3556 bx_write_ne2k_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_NE2K
));
3557 bx_write_pnic_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_PNIC
));
3558 bx_write_sb16_options(fp
, (bx_list_c
*) SIM
->get_param(BXPN_SB16
));
3559 bx_write_loader_options(fp
);
3560 bx_write_log_options(fp
, (bx_list_c
*) SIM
->get_param("log"));
3561 bx_write_keyboard_options(fp
);
3562 fprintf(fp
, "mouse: enabled=%d, type=%s\n",
3563 SIM
->get_param_bool(BXPN_MOUSE_ENABLED
)->get(),
3564 SIM
->get_param_enum(BXPN_MOUSE_TYPE
)->get_selected());
3565 SIM
->save_user_options(fp
);
3570 #endif // #if BX_PROVIDE_MAIN