/[gxemul]/upstream/0.3.8/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.3.8/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26