/[gxemul]/upstream/0.4.6/src/main.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/0.4.6/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 43 - (hide annotations)
Mon Oct 8 16:22:43 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 23321 byte(s)
0.4.6
1 dpavlin 2 /*
2 dpavlin 34 * Copyright (C) 2003-2007 Anders Gavare. All rights reserved.
3 dpavlin 2 *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 42 * $Id: main.c,v 1.305 2007/06/15 17:02:38 debug Exp $
29 dpavlin 2 */
30    
31     #include <stdio.h>
32     #include <stdlib.h>
33     #include <stdarg.h>
34     #include <string.h>
35     #include <time.h>
36     #include <unistd.h>
37    
38     #include "console.h"
39     #include "cpu.h"
40 dpavlin 26 #include "debugger.h"
41 dpavlin 2 #include "device.h"
42     #include "diskimage.h"
43     #include "emul.h"
44     #include "machine.h"
45     #include "misc.h"
46 dpavlin 24 #include "settings.h"
47 dpavlin 32 #include "timer.h"
48 dpavlin 42 #include "useremul.h"
49 dpavlin 2
50    
51 dpavlin 42 extern int single_step;
52 dpavlin 2 extern int force_debugger_at_exit;
53    
54     extern int optind;
55     extern char *optarg;
56    
57 dpavlin 24 struct settings *global_settings;
58    
59 dpavlin 2 int extra_argc;
60     char **extra_argv;
61     char *progname;
62    
63 dpavlin 34 size_t dyntrans_cache_size = DEFAULT_DYNTRANS_CACHE_SIZE;
64     int native_code_translation_enabled = 0;
65 dpavlin 32 int skip_srandom_call = 0;
66 dpavlin 2
67    
68     /*****************************************************************************
69     *
70     * NOTE: debug(), fatal(), and debug_indentation() are not re-entrant.
71     * The global variable quiet_mode can be used to suppress the output
72     * of debug(), but not the output of fatal().
73     *
74     *****************************************************************************/
75    
76     int verbose = 0;
77     int quiet_mode = 0;
78    
79     static int debug_indent = 0;
80     static int debug_currently_at_start_of_line = 1;
81    
82    
83     /*
84     * va_debug():
85     *
86     * Used internally by debug() and fatal().
87     */
88     static void va_debug(va_list argp, char *fmt)
89     {
90     char buf[DEBUG_BUFSIZE + 1];
91     char *s;
92     int i;
93    
94     buf[0] = buf[DEBUG_BUFSIZE] = 0;
95     vsnprintf(buf, DEBUG_BUFSIZE, fmt, argp);
96    
97     s = buf;
98     while (*s) {
99     if (debug_currently_at_start_of_line) {
100     for (i=0; i<debug_indent; i++)
101     printf(" ");
102     }
103    
104     printf("%c", *s);
105    
106     debug_currently_at_start_of_line = 0;
107     if (*s == '\n' || *s == '\r')
108     debug_currently_at_start_of_line = 1;
109     s++;
110     }
111     }
112    
113    
114     /*
115     * debug_indentation():
116     *
117     * Modify the debug indentation.
118     */
119     void debug_indentation(int diff)
120     {
121     debug_indent += diff;
122     if (debug_indent < 0)
123     fprintf(stderr, "WARNING: debug_indent less than 0!\n");
124     }
125    
126    
127     /*
128     * debug():
129     *
130     * Debug output (ignored if quiet_mode is set).
131     */
132     void debug(char *fmt, ...)
133     {
134     va_list argp;
135    
136     if (quiet_mode)
137     return;
138    
139     va_start(argp, fmt);
140     va_debug(argp, fmt);
141     va_end(argp);
142     }
143    
144    
145     /*
146     * fatal():
147     *
148     * Fatal works like debug(), but doesn't care about the quiet_mode
149     * setting.
150     */
151     void fatal(char *fmt, ...)
152     {
153     va_list argp;
154    
155     va_start(argp, fmt);
156     va_debug(argp, fmt);
157     va_end(argp);
158     }
159    
160    
161     /*****************************************************************************/
162    
163    
164     /*
165     * internal_w():
166     *
167     * For internal use by gxemul itself.
168     */
169     void internal_w(char *arg)
170     {
171     if (arg == NULL || strncmp(arg, "W@", 2) != 0) {
172     fprintf(stderr, "-W is for internal use by gxemul,"
173     " not for manual use.\n");
174     exit(1);
175     }
176    
177     arg += 2;
178    
179     switch (arg[0]) {
180     case 'S':
181     console_slave(arg + 1);
182     break;
183     default:
184     fprintf(stderr, "internal_w(): UNIMPLEMENTED arg = '%s'\n",
185     arg);
186     }
187     }
188    
189    
190     /*****************************************************************************/
191    
192    
193     /*
194     * usage():
195     *
196     * Prints program usage to stdout.
197     */
198     static void usage(int longusage)
199     {
200     printf("GXemul");
201     #ifdef VERSION
202 dpavlin 28 printf(" " VERSION);
203 dpavlin 2 #endif
204 dpavlin 34 printf(" Copyright (C) 2003-2007 Anders Gavare\n");
205 dpavlin 2 printf("Read the source code and/or documentation for "
206     "other Copyright messages.\n");
207    
208     printf("\nusage: %s [machine, other, and general options] [file "
209     "[...]]\n", progname);
210 dpavlin 14 printf(" or %s [general options] @configfile\n", progname);
211 dpavlin 2 printf(" or %s [userland, other, and general options] file "
212     "[args ...]\n", progname);
213    
214     if (!longusage) {
215     printf("\nRun %s -h for help on command line options.\n",
216     progname);
217     return;
218     }
219    
220     printf("\nMachine selection options:\n");
221     printf(" -E t try to emulate machine type t. (Use -H to get "
222     "a list of types.)\n");
223     printf(" -e st try to emulate machine subtype st. (Use this "
224     "with -E.)\n");
225    
226     printf("\nOther options:\n");
227     printf(" -C x try to emulate a specific CPU. (Use -H to get a "
228     "list of types.)\n");
229     printf(" -d fname add fname as a disk image. You can add \"xxx:\""
230     " as a prefix\n");
231     printf(" where xxx is one or more of the following:\n");
232 dpavlin 6 printf(" b specifies that this is the boot"
233 dpavlin 2 " device\n");
234 dpavlin 6 printf(" c CD-ROM\n");
235     printf(" d DISK\n");
236     printf(" f FLOPPY\n");
237     printf(" gH;S; set geometry to H heads and S"
238     " sectors-per-track\n");
239     printf(" i IDE\n");
240 dpavlin 34 printf(" oOFS; set base offset to OFS (for ISO9660"
241     " filesystems)\n");
242 dpavlin 6 printf(" r read-only (don't allow changes to the"
243 dpavlin 2 " file)\n");
244 dpavlin 6 printf(" s SCSI\n");
245     printf(" t tape\n");
246 dpavlin 38 printf(" V add an overlay\n");
247 dpavlin 6 printf(" 0-7 force a specific ID\n");
248 dpavlin 32 printf(" -I hz set the main cpu frequency to hz (not used by "
249 dpavlin 34 "all combinations\n of machines and guest OSes)\n");
250 dpavlin 2 printf(" -i display each instruction as it is executed\n");
251 dpavlin 28 printf(" -J disable dyntrans instruction combinations\n");
252 dpavlin 24 printf(" -j name set the name of the kernel; for DECstation "
253     "emulation, this passes\n the name to the bootloader,"
254     " for example:\n");
255     printf(" -j netbsd (NetBSD/pmax) "
256     "-j bsd (OpenBSD/pmax)\n");
257     printf(" -j vmsprite (Sprite/pmax) "
258     "-j vmunix (Ultrix/RISC)\n");
259     printf(" For other emulation modes, if the boot disk is an"
260     " ISO9660\n filesystem, -j sets the name of the"
261     " kernel to load.\n");
262 dpavlin 2 printf(" -M m emulate m MBs of physical RAM\n");
263     printf(" -N display nr of instructions/second average, at"
264     " regular intervals\n");
265     printf(" -n nr set nr of CPUs (for SMP experiments)\n");
266     printf(" -O force netboot (tftp instead of disk), even when"
267     " a disk image is\n"
268     " present (for DECstation, SGI, and ARC emulation)\n");
269 dpavlin 24 printf(" -o arg set the boot argument, for DEC, ARC, or SGI"
270     " emulation\n");
271     printf(" (default arg for DEC is -a, for ARC/SGI -aN)\n");
272 dpavlin 2 printf(" -p pc add a breakpoint (remember to use the '0x' "
273     "prefix for hex!)\n");
274     printf(" -Q no built-in PROM emulation (use this for "
275     "running ROM images)\n");
276     printf(" -R use random bootstrap cpu, instead of nr 0\n");
277     printf(" -r register dumps before every instruction\n");
278     printf(" -S initialize emulated RAM to random bytes, "
279     "instead of zeroes\n");
280 dpavlin 28 printf(" -s f:name write statistics to file 'name', "
281     "f is one or more of the following:\n");
282     printf(" v virtual program counter\n");
283     printf(" p physical equivalent of program counter\n");
284     printf(" i internal ic->f representation of "
285     "the program counter\n");
286     printf(" and optionally:\n");
287     printf(" d disable statistics gathering at "
288     "startup\n");
289     printf(" o overwrite instead of append\n");
290 dpavlin 34 printf(" -T halt on non-existant memory accesses\n");
291 dpavlin 2 printf(" -t show function trace tree\n");
292     printf(" -U enable slow_serial_interrupts_hack_for_linux\n");
293     #ifdef WITH_X11
294     printf(" -X use X11\n");
295     printf(" -x open up new xterms for emulated serial ports "
296 dpavlin 22 "(default is on when\n using configuration files or"
297     " when X11 is used, off otherwise)\n");
298 dpavlin 2 printf(" -Y n scale down framebuffer windows by n x n times\n");
299     #endif /* WITH_X11 */
300     printf(" -Z n set nr of graphics cards, for emulating a "
301     "dual-head or tripple-head\n"
302     " environment (only for DECstation emulation)\n");
303     printf(" -z disp add disp as an X11 display to use for "
304     "framebuffers\n");
305    
306     printf("\nUserland options:\n");
307     printf(" -u emul userland-only (syscall) emulation (use -H to"
308     " get a list of\n available emulation modes)\n");
309    
310     printf("\nGeneral options:\n");
311 dpavlin 42 printf(" -b enable native code generation, if available\n");
312     printf(" -B disable native code generation (this is "
313     "the default)\n");
314 dpavlin 22 printf(" -c cmd add cmd as a command to run before starting "
315     "the simulation\n");
316 dpavlin 32 printf(" -D skip the srandom call at startup\n");
317 dpavlin 2 printf(" -H display a list of possible CPU and "
318     "machine types\n");
319     printf(" -h display this help message\n");
320 dpavlin 34 printf(" -k n set dyntrans translation caches to n MB (default"
321     " size is %i MB)\n", DEFAULT_DYNTRANS_CACHE_SIZE / 1048576);
322 dpavlin 2 printf(" -K force the debugger to be entered at the end "
323     "of a simulation\n");
324     printf(" -q quiet mode (don't print startup messages)\n");
325     printf(" -V start up in the single-step debugger, paused\n");
326     printf(" -v verbose debug messages\n");
327     printf("\n");
328     printf("If you are selecting a machine type to emulate directly "
329     "on the command line,\nthen you must specify one or more names"
330     " of files that you wish to load into\n"
331     "memory. Supported formats are: ELF a.out ecoff srec syms raw\n"
332     "where syms is the text produced by running 'nm' (or 'nm -S') "
333     "on a binary.\n"
334     "To load a raw binary into memory, add \"address:\" in front "
335     "of the filename,\n"
336 dpavlin 4 "or \"address:skiplen:\" or \"address:skiplen:initialpc:\".\n"
337 dpavlin 42 "\nExamples:\n"
338 dpavlin 4 " 0xbfc00000:rom.bin for a raw ROM image\n"
339     " 0xbfc00000:0x100:rom.bin for an image with "
340 dpavlin 2 "0x100 bytes header\n"
341 dpavlin 4 " 0xbfc00000:0x100:0xbfc00884:rom.bin "
342 dpavlin 42 "start with pc=0xbfc00884\n\n");
343 dpavlin 2 }
344    
345    
346     /*
347     * get_cmd_args():
348     *
349     * Reads command line arguments.
350     */
351 dpavlin 4 int get_cmd_args(int argc, char *argv[], struct emul *emul,
352     char ***diskimagesp, int *n_diskimagesp)
353 dpavlin 2 {
354     int ch, res, using_switch_d = 0, using_switch_Z = 0;
355 dpavlin 24 int using_switch_e = 0, using_switch_E = 0;
356 dpavlin 2 char *type = NULL, *subtype = NULL;
357     int n_cpus_set = 0;
358     int msopts = 0; /* Machine-specific options used */
359     struct machine *m = emul_add_machine(emul, "default");
360    
361 dpavlin 24 char *opts =
362 dpavlin 42 "bBC:c:Dd:E:e:HhI:iJj:k:KM:Nn:Oo:p:QqRrSs:TtUu:VvW:"
363 dpavlin 24 #ifdef WITH_X11
364     "XxY:"
365     #endif
366     "Z:z:";
367    
368     while ((ch = getopt(argc, argv, opts)) != -1) {
369 dpavlin 2 switch (ch) {
370 dpavlin 34 case 'b':
371     native_code_translation_enabled = 1;
372     break;
373     case 'B':
374     native_code_translation_enabled = 0;
375     break;
376 dpavlin 2 case 'C':
377 dpavlin 42 CHECK_ALLOCATION(m->cpu_name = strdup(optarg));
378 dpavlin 2 msopts = 1;
379     break;
380 dpavlin 22 case 'c':
381     emul->n_debugger_cmds ++;
382 dpavlin 42 CHECK_ALLOCATION(emul->debugger_cmds =
383     realloc(emul->debugger_cmds,
384     emul->n_debugger_cmds * sizeof(char *)));
385     CHECK_ALLOCATION(emul->debugger_cmds[emul->
386     n_debugger_cmds-1] = strdup(optarg));
387 dpavlin 22 break;
388 dpavlin 2 case 'D':
389 dpavlin 32 skip_srandom_call = 1;
390 dpavlin 2 break;
391     case 'd':
392 dpavlin 4 /* diskimage_add() is called further down */
393     (*n_diskimagesp) ++;
394 dpavlin 42 CHECK_ALLOCATION( (*diskimagesp) =
395     realloc(*diskimagesp,
396     sizeof(char *) * (*n_diskimagesp)) );
397     CHECK_ALLOCATION( (*diskimagesp)[(*n_diskimagesp) - 1] =
398     strdup(optarg) );
399 dpavlin 2 using_switch_d = 1;
400     msopts = 1;
401     break;
402     case 'E':
403 dpavlin 24 if (using_switch_E ++ > 0) {
404     fprintf(stderr, "-E already used.\n");
405     exit(1);
406     }
407 dpavlin 2 type = optarg;
408     msopts = 1;
409     break;
410     case 'e':
411 dpavlin 24 if (using_switch_e ++ > 0) {
412     fprintf(stderr, "-e already used.\n");
413     exit(1);
414     }
415 dpavlin 2 subtype = optarg;
416     msopts = 1;
417     break;
418     case 'H':
419     machine_list_available_types_and_cpus();
420     exit(1);
421     case 'h':
422     usage(1);
423     exit(1);
424     case 'I':
425     m->emulated_hz = atoi(optarg);
426     msopts = 1;
427     break;
428     case 'i':
429     m->instruction_trace = 1;
430     msopts = 1;
431     break;
432     case 'J':
433 dpavlin 28 m->allow_instruction_combinations = 0;
434 dpavlin 2 msopts = 1;
435     break;
436     case 'j':
437 dpavlin 42 CHECK_ALLOCATION(m->boot_kernel_filename =
438     strdup(optarg));
439 dpavlin 2 msopts = 1;
440     break;
441 dpavlin 34 case 'k':
442     dyntrans_cache_size = atoi(optarg) * 1048576;
443     if (dyntrans_cache_size < 1) {
444     fprintf(stderr, "The dyntrans cache size must"
445     " be at least 1 MB.\n");
446     exit(1);
447     }
448     break;
449 dpavlin 2 case 'K':
450     force_debugger_at_exit = 1;
451     break;
452     case 'M':
453     m->physical_ram_in_mb = atoi(optarg);
454     msopts = 1;
455     break;
456     case 'N':
457     m->show_nr_of_instructions = 1;
458     msopts = 1;
459     break;
460     case 'n':
461     m->ncpus = atoi(optarg);
462     n_cpus_set = 1;
463     msopts = 1;
464     break;
465     case 'O':
466     m->force_netboot = 1;
467     msopts = 1;
468     break;
469     case 'o':
470 dpavlin 42 CHECK_ALLOCATION(m->boot_string_argument =
471     strdup(optarg));
472 dpavlin 2 msopts = 1;
473     break;
474     case 'p':
475 dpavlin 42 machine_add_breakpoint_string(m, optarg);
476 dpavlin 2 msopts = 1;
477     break;
478     case 'Q':
479     m->prom_emulation = 0;
480     msopts = 1;
481     break;
482     case 'q':
483     quiet_mode = 1;
484     break;
485     case 'R':
486     m->use_random_bootstrap_cpu = 1;
487     msopts = 1;
488     break;
489     case 'r':
490     m->register_dump = 1;
491     msopts = 1;
492     break;
493     case 'S':
494     m->random_mem_contents = 1;
495     msopts = 1;
496     break;
497 dpavlin 28 case 's':
498     machine_statistics_init(m, optarg);
499 dpavlin 34 native_code_translation_enabled = 0;
500 dpavlin 28 msopts = 1;
501     break;
502 dpavlin 34 case 'T':
503     m->halt_on_nonexistant_memaccess = 1;
504     msopts = 1;
505     break;
506 dpavlin 2 case 't':
507     m->show_trace_tree = 1;
508     msopts = 1;
509     break;
510     case 'U':
511     m->slow_serial_interrupts_hack_for_linux = 1;
512     msopts = 1;
513     break;
514     case 'u':
515 dpavlin 42 CHECK_ALLOCATION(m->userland_emul = strdup(optarg));
516 dpavlin 2 m->machine_type = MACHINE_USERLAND;
517     msopts = 1;
518     break;
519     case 'V':
520 dpavlin 26 single_step = ENTER_SINGLE_STEPPING;
521 dpavlin 2 break;
522     case 'v':
523     verbose ++;
524     break;
525     case 'W':
526     internal_w(optarg);
527     exit(0);
528     case 'X':
529 dpavlin 42 m->x11_md.in_use = 1;
530 dpavlin 2 msopts = 1;
531 dpavlin 22 /* FALL-THROUGH */
532 dpavlin 2 case 'x':
533     console_allow_slaves(1);
534     break;
535     case 'Y':
536 dpavlin 42 m->x11_md.scaledown = atoi(optarg);
537     if (m->x11_md.scaledown < -1) {
538     m->x11_md.scaleup = - m->x11_md.scaledown;
539     m->x11_md.scaledown = 1;
540 dpavlin 20 }
541 dpavlin 42 if (m->x11_md.scaledown < 1) {
542 dpavlin 4 fprintf(stderr, "Invalid scaledown value.\n");
543     exit(1);
544     }
545 dpavlin 2 msopts = 1;
546     break;
547     case 'Z':
548     m->n_gfx_cards = atoi(optarg);
549     using_switch_Z = 1;
550     msopts = 1;
551     break;
552     case 'z':
553 dpavlin 42 m->x11_md.n_display_names ++;
554     CHECK_ALLOCATION(m->x11_md.display_names = realloc(
555     m->x11_md.display_names,
556     m->x11_md.n_display_names * sizeof(char *)));
557     CHECK_ALLOCATION(m->x11_md.display_names[
558     m->x11_md.n_display_names-1] = strdup(optarg));
559 dpavlin 2 msopts = 1;
560     break;
561     default:
562 dpavlin 10 fprintf(stderr, "Run %s -h for help on command "
563     "line options.\n", progname);
564 dpavlin 2 exit(1);
565     }
566     }
567    
568 dpavlin 12 if (type != NULL || subtype != NULL) {
569     if (type == NULL)
570     type = "";
571 dpavlin 2 if (subtype == NULL)
572     subtype = "";
573     res = machine_name_to_type(type, subtype,
574     &m->machine_type, &m->machine_subtype, &m->arch);
575     if (!res)
576     exit(1);
577     }
578    
579     argc -= optind;
580     argv += optind;
581    
582     extra_argc = argc;
583     extra_argv = argv;
584    
585    
586     if (m->machine_type == MACHINE_NONE && msopts) {
587     fprintf(stderr, "Machine specific options used directly on "
588     "the command line, but no machine\nemulation specified?\n");
589     exit(1);
590     }
591    
592    
593 dpavlin 12 /* -i and -r are pretty verbose: */
594 dpavlin 2
595     if (m->instruction_trace && !verbose) {
596 dpavlin 4 fprintf(stderr, "Implicitly %sturning on -v, because"
597     " of -i\n", quiet_mode? "turning off -q and " : "");
598 dpavlin 2 verbose = 1;
599     quiet_mode = 0;
600     }
601    
602     if (m->register_dump && !verbose) {
603 dpavlin 4 fprintf(stderr, "Implicitly %sturning on -v, because"
604     " of -r\n", quiet_mode? "turning off -q and " : "");
605 dpavlin 2 verbose = 1;
606     quiet_mode = 0;
607     }
608    
609    
610     /*
611     * Usually, an executable filename must be supplied.
612     *
613     * However, it is possible to boot directly from a harddisk image
614 dpavlin 4 * file. If no kernel is supplied, but a diskimage is being used,
615     * then try to boot from disk.
616 dpavlin 2 */
617     if (extra_argc == 0) {
618     if (using_switch_d) {
619     /* Booting directly from a disk image... */
620     } else {
621     usage(0);
622     fprintf(stderr, "\nNo filename given. Aborting.\n");
623     exit(1);
624     }
625     } else if (m->boot_kernel_filename[0] == '\0') {
626     /*
627     * Default boot_kernel_filename is "", which can be overriden
628     * by the -j command line option. If it is still "" here,
629     * and we're not booting directly from a disk image, then
630     * try to set it to the last part of the last file name
631     * given on the command line. (Last part = the stuff after
632     * the last slash.)
633     */
634     char *s = extra_argv[extra_argc - 1];
635     char *s2;
636    
637     s2 = strrchr(s, '/');
638     if (s2 == NULL)
639     s2 = s;
640     else
641     s2 ++;
642    
643 dpavlin 42 CHECK_ALLOCATION(m->boot_kernel_filename = strdup(s2));
644 dpavlin 2 }
645    
646     if (m->n_gfx_cards < 0 || m->n_gfx_cards > 3) {
647     fprintf(stderr, "Bad number of gfx cards (-Z).\n");
648     exit(1);
649     }
650    
651 dpavlin 42 if (!using_switch_Z && !m->x11_md.in_use)
652 dpavlin 2 m->n_gfx_cards = 0;
653    
654     return 0;
655     }
656    
657    
658     /*
659     * main():
660     *
661     * Two kinds of emulations are started from here:
662     *
663     * o) Simple emulations, using command line arguments, compatible with
664     * earlier version of GXemul/mips64emul.
665     *
666     * o) Emulations set up by parsing special config files. (0 or more.)
667     */
668     int main(int argc, char *argv[])
669     {
670 dpavlin 32 /* Setting constants: */
671     const int constant_yes = 1;
672     const int constant_true = 1;
673     const int constant_no = 0;
674     const int constant_false = 0;
675    
676 dpavlin 2 struct emul **emuls;
677 dpavlin 4 char **diskimages = NULL;
678     int n_diskimages = 0;
679 dpavlin 2 int n_emuls;
680     int i;
681    
682     progname = argv[0];
683    
684 dpavlin 32
685     /*
686     * Create the settings object, and add global settings to it:
687     *
688     * Read-only "constants": yes, no, true, false.
689     * Global emulator settings: verbose, single_step, ...
690     */
691 dpavlin 24 global_settings = settings_new();
692    
693 dpavlin 32 settings_add(global_settings, "yes", 0, SETTINGS_TYPE_INT,
694     SETTINGS_FORMAT_YESNO, (void *)&constant_yes);
695     settings_add(global_settings, "no", 0, SETTINGS_TYPE_INT,
696     SETTINGS_FORMAT_YESNO, (void *)&constant_no);
697     settings_add(global_settings, "true", 0, SETTINGS_TYPE_INT,
698     SETTINGS_FORMAT_BOOL, (void *)&constant_true);
699     settings_add(global_settings, "false", 0, SETTINGS_TYPE_INT,
700     SETTINGS_FORMAT_BOOL, (void *)&constant_false);
701    
702 dpavlin 34 /* Read-only settings: */
703     settings_add(global_settings, "native_code_translation_enabled", 0,
704     SETTINGS_TYPE_INT, SETTINGS_FORMAT_YESNO,
705     (void *)&native_code_translation_enabled);
706 dpavlin 24 settings_add(global_settings, "single_step", 0,
707     SETTINGS_TYPE_INT, SETTINGS_FORMAT_YESNO, (void *)&single_step);
708 dpavlin 34
709     /* Read/write settings: */
710 dpavlin 24 settings_add(global_settings, "force_debugger_at_exit", 1,
711     SETTINGS_TYPE_INT, SETTINGS_FORMAT_YESNO,
712     (void *)&force_debugger_at_exit);
713     settings_add(global_settings, "verbose", 1,
714     SETTINGS_TYPE_INT, SETTINGS_FORMAT_YESNO, (void *)&verbose);
715     settings_add(global_settings, "quiet_mode", 1,
716     SETTINGS_TYPE_INT, SETTINGS_FORMAT_YESNO, (void *)&quiet_mode);
717    
718     /* Initialize all emulator subsystems: */
719 dpavlin 2 console_init();
720     cpu_init();
721     device_init();
722     machine_init();
723 dpavlin 32 timer_init();
724 dpavlin 2 useremul_init();
725    
726     emuls = malloc(sizeof(struct emul *));
727 dpavlin 42 CHECK_ALLOCATION(emuls);
728 dpavlin 2
729     /* Allocate space for a simple emul setup: */
730     n_emuls = 1;
731 dpavlin 34 emuls[0] = emul_new(NULL, 0);
732 dpavlin 32 settings_add(global_settings, "emul[0]", 1,
733     SETTINGS_TYPE_SUBSETTINGS, 0, emuls[0]->settings);
734 dpavlin 2
735 dpavlin 4 get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages);
736 dpavlin 2
737 dpavlin 32 if (!skip_srandom_call) {
738     struct timeval tv;
739     gettimeofday(&tv, NULL);
740     srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec);
741 dpavlin 2 }
742    
743     /* Print startup message: */
744     debug("GXemul");
745     #ifdef VERSION
746 dpavlin 28 debug(" " VERSION);
747 dpavlin 2 #endif
748 dpavlin 34 debug(" Copyright (C) 2003-2007 Anders Gavare\n");
749 dpavlin 2 debug("Read the source code and/or documentation for "
750     "other Copyright messages.\n\n");
751    
752 dpavlin 32 if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) {
753 dpavlin 2 n_emuls --;
754 dpavlin 32 } else {
755 dpavlin 4 for (i=0; i<n_diskimages; i++)
756     diskimage_add(emuls[0]->machines[0], diskimages[i]);
757     }
758 dpavlin 2
759     /* Simple initialization, from command line arguments: */
760     if (n_emuls > 0) {
761     /* Make sure that there are no configuration files as well: */
762     for (i=1; i<argc; i++)
763     if (argv[i][0] == '@') {
764     fprintf(stderr, "You can either start one "
765     "emulation with one machine directly from "
766     "the command\nline, or start one or more "
767     "emulations using configuration files."
768     " Not both.\n");
769     exit(1);
770     }
771    
772     /* Initialize one emul: */
773     emul_simple_init(emuls[0]);
774     }
775    
776     /* Initialize emulations from config files: */
777     for (i=1; i<argc; i++) {
778     if (argv[i][0] == '@') {
779 dpavlin 32 char tmpstr[50];
780 dpavlin 2 char *s = argv[i] + 1;
781     if (strlen(s) == 0 && i+1 < argc &&
782     argv[i+1][0] != '@') {
783     i++;
784     s = argv[i];
785     }
786     n_emuls ++;
787 dpavlin 42 CHECK_ALLOCATION(emuls = realloc(emuls,
788     sizeof(struct emul *) * n_emuls));
789 dpavlin 2
790     /* Always allow slave xterms when using multiple
791     emulations: */
792     console_allow_slaves(1);
793 dpavlin 22
794 dpavlin 32 /* Destroy the temporary emuls[0], since it will
795     be overwritten: */
796     if (n_emuls == 1) {
797     emul_destroy(emuls[0]);
798     settings_remove(global_settings, "emul[0]");
799     }
800    
801 dpavlin 22 emuls[n_emuls - 1] =
802 dpavlin 34 emul_create_from_configfile(s, n_emuls - 1);
803 dpavlin 32
804     snprintf(tmpstr, sizeof(tmpstr), "emul[%i]", n_emuls-1);
805     settings_add(global_settings, tmpstr, 1,
806     SETTINGS_TYPE_SUBSETTINGS, 0,
807     emuls[n_emuls-1]->settings);
808 dpavlin 2 }
809     }
810    
811     if (n_emuls == 0) {
812 dpavlin 6 fprintf(stderr, "No emulations defined. Maybe you forgot to "
813 dpavlin 12 "use -E xx and/or -e yy, to specify\nthe machine type."
814     " For example:\n\n %s -e 3max -d disk.img\n\n"
815 dpavlin 6 "to boot an emulated DECstation 5000/200 with a disk "
816     "image.\n", progname);
817 dpavlin 2 exit(1);
818     }
819    
820     device_set_exit_on_error(0);
821 dpavlin 22 console_warn_if_slaves_are_needed(1);
822 dpavlin 2
823 dpavlin 32
824 dpavlin 2 /* Run all emulations: */
825     emul_run(emuls, n_emuls);
826    
827 dpavlin 32
828     /*
829     * Deinitialize everything:
830     */
831    
832     console_deinit();
833    
834     for (i=0; i<n_emuls; i++)
835     emul_destroy(emuls[i]);
836    
837     settings_remove_all(global_settings);
838 dpavlin 24 settings_destroy(global_settings);
839    
840 dpavlin 2 return 0;
841     }
842    

  ViewVC Help
Powered by ViewVC 1.1.26