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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26