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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Mon Oct 8 16:19:28 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 21567 byte(s)
0.3.7
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 20 * $Id: main.c,v 1.248 2005/11/23 02:17:00 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 dpavlin 14 printf(" or %s [general options] @configfile\n", progname);
204 dpavlin 2 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 dpavlin 12 printf(" -A disable alignment checks in some cases (for higher"
221     " speed)\n");
222 dpavlin 2 #ifdef BINTRANS
223 dpavlin 10 printf(" -B disable dynamic binary translation. (translation"
224     " is turned on\n by default, if the host "
225     "supports it)\n");
226 dpavlin 2 #endif
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     printf(" r read-only (don't allow changes to the"
241 dpavlin 2 " file)\n");
242 dpavlin 6 printf(" s SCSI\n");
243     printf(" t tape\n");
244     printf(" 0-7 force a specific ID\n");
245 dpavlin 2 printf(" -I x emulate clock interrupts at x Hz (affects"
246     " rtc devices only, not\n");
247     printf(" actual runtime speed) (this disables automatic"
248     " clock adjustments)\n");
249     printf(" -i display each instruction as it is executed\n");
250     printf(" -J disable some speed tricks\n");
251     printf(" -j name set the name of the kernel, for example:\n");
252     printf(" -j netbsd for NetBSD/pmax\n");
253     printf(" -j bsd for OpenBSD/pmax\n");
254     printf(" -j vmunix for Ultrix/RISC\n");
255     printf(" -M m emulate m MBs of physical RAM\n");
256     printf(" -m nr run at most nr instructions (on any cpu)\n");
257     printf(" -N display nr of instructions/second average, at"
258     " regular intervals\n");
259     printf(" -n nr set nr of CPUs (for SMP experiments)\n");
260     printf(" -O force netboot (tftp instead of disk), even when"
261     " a disk image is\n"
262     " present (for DECstation, SGI, and ARC emulation)\n");
263     printf(" -o arg set the boot argument (for DEC, ARC, or SGI"
264     " emulation).\n");
265     printf(" Default arg for DEC is '-a', for ARC '-aN'.\n");
266     printf(" -p pc add a breakpoint (remember to use the '0x' "
267     "prefix for hex!)\n");
268     printf(" -Q no built-in PROM emulation (use this for "
269     "running ROM images)\n");
270     printf(" -R use random bootstrap cpu, instead of nr 0\n");
271     printf(" -r register dumps before every instruction\n");
272     printf(" -S initialize emulated RAM to random bytes, "
273     "instead of zeroes\n");
274     printf(" -T enter the single-step debugger on "
275     "unimplemented memory accesses\n");
276     printf(" -t show function trace tree\n");
277     printf(" -U enable slow_serial_interrupts_hack_for_linux\n");
278     #ifdef WITH_X11
279     printf(" -X use X11\n");
280     #endif /* WITH_X11 */
281     printf(" -x open up new xterms for emulated serial ports "
282     "(default is on when\n using configuration files, off"
283     " otherwise)\n");
284     #ifdef WITH_X11
285     printf(" -Y n scale down framebuffer windows by n x n times\n");
286     #endif /* WITH_X11 */
287     printf(" -y x set max_random_cycles_per_chunk to x"
288     " (experimental)\n");
289     printf(" -Z n set nr of graphics cards, for emulating a "
290     "dual-head or tripple-head\n"
291     " environment (only for DECstation emulation)\n");
292     printf(" -z disp add disp as an X11 display to use for "
293     "framebuffers\n");
294    
295     printf("\nUserland options:\n");
296     printf(" -u emul userland-only (syscall) emulation (use -H to"
297     " get a list of\n available emulation modes)\n");
298    
299     printf("\nGeneral options:\n");
300     printf(" -D guarantee fully deterministic behaviour\n");
301     printf(" -H display a list of possible CPU and "
302     "machine types\n");
303     printf(" -h display this help message\n");
304     printf(" -K force the debugger to be entered at the end "
305     "of a simulation\n");
306     printf(" -q quiet mode (don't print startup messages)\n");
307     printf(" -s show opcode usage statistics after simulation\n");
308     printf(" -V start up in the single-step debugger, paused\n");
309     printf(" -v verbose debug messages\n");
310     printf("\n");
311     printf("If you are selecting a machine type to emulate directly "
312     "on the command line,\nthen you must specify one or more names"
313     " of files that you wish to load into\n"
314     "memory. Supported formats are: ELF a.out ecoff srec syms raw\n"
315     "where syms is the text produced by running 'nm' (or 'nm -S') "
316     "on a binary.\n"
317     "To load a raw binary into memory, add \"address:\" in front "
318     "of the filename,\n"
319 dpavlin 4 "or \"address:skiplen:\" or \"address:skiplen:initialpc:\".\n"
320 dpavlin 2 "Examples:\n"
321 dpavlin 4 " 0xbfc00000:rom.bin for a raw ROM image\n"
322     " 0xbfc00000:0x100:rom.bin for an image with "
323 dpavlin 2 "0x100 bytes header\n"
324 dpavlin 4 " 0xbfc00000:0x100:0xbfc00884:rom.bin "
325 dpavlin 2 "start with pc=0xbfc00884\n");
326     }
327    
328    
329     /*
330     * get_cmd_args():
331     *
332     * Reads command line arguments.
333     */
334 dpavlin 4 int get_cmd_args(int argc, char *argv[], struct emul *emul,
335     char ***diskimagesp, int *n_diskimagesp)
336 dpavlin 2 {
337     int ch, res, using_switch_d = 0, using_switch_Z = 0;
338     char *type = NULL, *subtype = NULL;
339     int n_cpus_set = 0;
340     int msopts = 0; /* Machine-specific options used */
341     struct machine *m = emul_add_machine(emul, "default");
342    
343 dpavlin 12 while ((ch = getopt(argc, argv, "ABC:Dd:E:e:HhI:iJj:KM:m:"
344 dpavlin 2 "Nn:Oo:p:QqRrSsTtUu:VvW:XxY:y:Z:z:")) != -1) {
345     switch (ch) {
346 dpavlin 12 case 'A':
347     m->dyntrans_alignment_check = 0;
348     msopts = 1;
349     break;
350 dpavlin 2 case 'B':
351     m->bintrans_enable = 0;
352     msopts = 1;
353     break;
354     case 'C':
355     m->cpu_name = strdup(optarg);
356     msopts = 1;
357     break;
358     case 'D':
359     fully_deterministic = 1;
360     break;
361     case 'd':
362 dpavlin 4 /* diskimage_add() is called further down */
363     (*n_diskimagesp) ++;
364     (*diskimagesp) = realloc(*diskimagesp,
365     sizeof(char *) * (*n_diskimagesp));
366     if (*diskimagesp == NULL) {
367     fprintf(stderr, "out of memory\n");
368     exit(1);
369     }
370     (*diskimagesp)[(*n_diskimagesp) - 1] = strdup(optarg);
371 dpavlin 2 using_switch_d = 1;
372     msopts = 1;
373     break;
374     case 'E':
375     type = optarg;
376     msopts = 1;
377     break;
378     case 'e':
379     subtype = optarg;
380     msopts = 1;
381     break;
382     case 'H':
383     machine_list_available_types_and_cpus();
384     exit(1);
385     case 'h':
386     usage(1);
387     exit(1);
388     case 'I':
389     m->emulated_hz = atoi(optarg);
390     m->automatic_clock_adjustment = 0;
391     msopts = 1;
392     break;
393     case 'i':
394     m->instruction_trace = 1;
395     msopts = 1;
396     break;
397     case 'J':
398     m->speed_tricks = 0;
399     msopts = 1;
400     break;
401     case 'j':
402     m->boot_kernel_filename = strdup(optarg);
403     if (m->boot_kernel_filename == NULL) {
404     fprintf(stderr, "out of memory\n");
405     exit(1);
406     }
407     msopts = 1;
408     break;
409     case 'K':
410     force_debugger_at_exit = 1;
411     break;
412     case 'M':
413     m->physical_ram_in_mb = atoi(optarg);
414     msopts = 1;
415     break;
416     case 'm':
417     m->max_instructions = atoi(optarg);
418     msopts = 1;
419     break;
420     case 'N':
421     m->show_nr_of_instructions = 1;
422     msopts = 1;
423     break;
424     case 'n':
425     m->ncpus = atoi(optarg);
426     n_cpus_set = 1;
427     msopts = 1;
428     break;
429     case 'O':
430     m->force_netboot = 1;
431     msopts = 1;
432     break;
433     case 'o':
434     m->boot_string_argument = strdup(optarg);
435     if (m->boot_string_argument == NULL) {
436     fprintf(stderr, "out of memory\n");
437     exit(1);
438     }
439     msopts = 1;
440     break;
441     case 'p':
442     if (m->n_breakpoints >= MAX_BREAKPOINTS) {
443     fprintf(stderr, "too many breakpoints\n");
444     exit(1);
445     }
446     m->breakpoint_string[m->n_breakpoints] = strdup(optarg);
447     if (m->breakpoint_string[m->n_breakpoints] == NULL) {
448     fprintf(stderr, "out of memory\n");
449     exit(1);
450     }
451     m->breakpoint_flags[m->n_breakpoints] = 0;
452     m->n_breakpoints ++;
453     msopts = 1;
454     break;
455     case 'Q':
456     m->prom_emulation = 0;
457     msopts = 1;
458     break;
459     case 'q':
460     quiet_mode = 1;
461     break;
462     case 'R':
463     m->use_random_bootstrap_cpu = 1;
464     msopts = 1;
465     break;
466     case 'r':
467     m->register_dump = 1;
468     msopts = 1;
469     break;
470     case 'S':
471     m->random_mem_contents = 1;
472     msopts = 1;
473     break;
474     case 's':
475     show_opcode_statistics = 1;
476     break;
477     case 'T':
478     m->single_step_on_bad_addr = 1;
479     msopts = 1;
480     break;
481     case 't':
482     m->show_trace_tree = 1;
483     msopts = 1;
484     break;
485     case 'U':
486     m->slow_serial_interrupts_hack_for_linux = 1;
487     msopts = 1;
488     break;
489     case 'u':
490     m->userland_emul = strdup(optarg);
491     if (m->userland_emul == NULL) {
492     fprintf(stderr, "out of memory\n");
493     exit(1);
494     }
495     m->machine_type = MACHINE_USERLAND;
496     msopts = 1;
497     break;
498     case 'V':
499     single_step = 1;
500     break;
501     case 'v':
502     verbose ++;
503     break;
504     case 'W':
505     internal_w(optarg);
506     exit(0);
507     case 'X':
508     m->use_x11 = 1;
509     msopts = 1;
510     break;
511     case 'x':
512     console_allow_slaves(1);
513     break;
514     case 'Y':
515     m->x11_scaledown = atoi(optarg);
516 dpavlin 20 if (m->x11_scaledown < -1) {
517     m->x11_scaleup = - m->x11_scaledown;
518     m->x11_scaledown = 1;
519     }
520 dpavlin 4 if (m->x11_scaledown < 1) {
521     fprintf(stderr, "Invalid scaledown value.\n");
522     exit(1);
523     }
524 dpavlin 2 msopts = 1;
525     break;
526     case 'y':
527     m->max_random_cycles_per_chunk = atoi(optarg);
528     msopts = 1;
529     break;
530     case 'Z':
531     m->n_gfx_cards = atoi(optarg);
532     using_switch_Z = 1;
533     msopts = 1;
534     break;
535     case 'z':
536     m->x11_n_display_names ++;
537     m->x11_display_names = realloc(
538     m->x11_display_names,
539     m->x11_n_display_names * sizeof(char *));
540     if (m->x11_display_names == NULL) {
541     fprintf(stderr, "out of memory\n");
542     exit(1);
543     }
544     m->x11_display_names[m->x11_n_display_names-1] =
545     strdup(optarg);
546     if (m->x11_display_names
547     [m->x11_n_display_names-1] == NULL) {
548     fprintf(stderr, "out of memory\n");
549     exit(1);
550     }
551     msopts = 1;
552     break;
553     default:
554 dpavlin 10 fprintf(stderr, "Run %s -h for help on command "
555     "line options.\n", progname);
556 dpavlin 2 exit(1);
557     }
558     }
559    
560 dpavlin 12 if (type != NULL || subtype != NULL) {
561     if (type == NULL)
562     type = "";
563 dpavlin 2 if (subtype == NULL)
564     subtype = "";
565     res = machine_name_to_type(type, subtype,
566     &m->machine_type, &m->machine_subtype, &m->arch);
567     if (!res)
568     exit(1);
569     }
570    
571     argc -= optind;
572     argv += optind;
573    
574     extra_argc = argc;
575     extra_argv = argv;
576    
577    
578     if (m->machine_type == MACHINE_NONE && msopts) {
579     fprintf(stderr, "Machine specific options used directly on "
580     "the command line, but no machine\nemulation specified?\n");
581     exit(1);
582     }
583    
584    
585 dpavlin 12 /* -i and -r are pretty verbose: */
586 dpavlin 2
587     if (m->instruction_trace && !verbose) {
588 dpavlin 4 fprintf(stderr, "Implicitly %sturning on -v, because"
589     " of -i\n", quiet_mode? "turning off -q and " : "");
590 dpavlin 2 verbose = 1;
591     quiet_mode = 0;
592     }
593    
594     if (m->register_dump && !verbose) {
595 dpavlin 4 fprintf(stderr, "Implicitly %sturning on -v, because"
596     " of -r\n", quiet_mode? "turning off -q and " : "");
597 dpavlin 2 verbose = 1;
598     quiet_mode = 0;
599     }
600    
601 dpavlin 10 if ((m->instruction_trace || m->register_dump || m->show_trace_tree)
602     && m->bintrans_enable) {
603 dpavlin 20 if (m->arch == ARCH_MIPS)
604     fprintf(stderr, "Implicitly turning off bintrans.\n");
605 dpavlin 10 m->bintrans_enable = 0;
606     }
607 dpavlin 2
608 dpavlin 10
609 dpavlin 2 /*
610     * Usually, an executable filename must be supplied.
611     *
612     * However, it is possible to boot directly from a harddisk image
613 dpavlin 4 * file. If no kernel is supplied, but a diskimage is being used,
614     * then try to boot from disk.
615 dpavlin 2 */
616     if (extra_argc == 0) {
617     if (using_switch_d) {
618     /* Booting directly from a disk image... */
619     } else {
620     usage(0);
621     fprintf(stderr, "\nNo filename given. Aborting.\n");
622     exit(1);
623     }
624     } else if (m->boot_kernel_filename[0] == '\0') {
625     /*
626     * Default boot_kernel_filename is "", which can be overriden
627     * by the -j command line option. If it is still "" here,
628     * and we're not booting directly from a disk image, then
629     * try to set it to the last part of the last file name
630     * given on the command line. (Last part = the stuff after
631     * the last slash.)
632     */
633     char *s = extra_argv[extra_argc - 1];
634     char *s2;
635    
636     s2 = strrchr(s, '/');
637     if (s2 == NULL)
638     s2 = s;
639     else
640     s2 ++;
641    
642     m->boot_kernel_filename = strdup(s2);
643     if (m->boot_kernel_filename == NULL) {
644     fprintf(stderr, "out of memory\n");
645     exit(1);
646     }
647     }
648    
649     if (m->n_gfx_cards < 0 || m->n_gfx_cards > 3) {
650     fprintf(stderr, "Bad number of gfx cards (-Z).\n");
651     exit(1);
652     }
653    
654 dpavlin 20 if (m->bintrans_enable && m->arch == ARCH_MIPS) {
655 dpavlin 2 m->speed_tricks = 0;
656     /* TODO: Print a warning about this? */
657     }
658    
659 dpavlin 12 if (m->n_breakpoints > 0 &&
660     m->bintrans_enable && m->arch == ARCH_MIPS) {
661     fprintf(stderr, "Breakpoints and MIPS binary translation "
662 dpavlin 2 "don't work too well together right now.\n");
663     exit(1);
664     }
665    
666     #ifndef BINTRANS
667     if (m->bintrans_enable) {
668     fprintf(stderr, "WARNING: %s was compiled without "
669     "bintrans support. Ignoring -b.\n", progname);
670     m->bintrans_enable = 0;
671     }
672     #endif
673    
674     #ifndef WITH_X11
675     if (m->use_x11) {
676     fprintf(stderr, "WARNING: %s was compiled without "
677     "X11 support. Ignoring -X.\n", progname);
678     m->use_x11 = 0;
679     }
680     #endif
681    
682     if (!using_switch_Z && !m->use_x11)
683     m->n_gfx_cards = 0;
684    
685     m->bintrans_enabled_from_start = m->bintrans_enable;
686    
687     return 0;
688     }
689    
690    
691     /*
692     * main():
693     *
694     * Two kinds of emulations are started from here:
695     *
696     * o) Simple emulations, using command line arguments, compatible with
697     * earlier version of GXemul/mips64emul.
698     *
699     * o) Emulations set up by parsing special config files. (0 or more.)
700     */
701     int main(int argc, char *argv[])
702     {
703     struct emul **emuls;
704 dpavlin 4 char **diskimages = NULL;
705     int n_diskimages = 0;
706 dpavlin 2 int n_emuls;
707     int i;
708    
709     progname = argv[0];
710    
711     console_init();
712     cpu_init();
713     device_init();
714     machine_init();
715     useremul_init();
716    
717     emuls = malloc(sizeof(struct emul *));
718     if (emuls == NULL) {
719     fprintf(stderr, "out of memory\n");
720     exit(1);
721     }
722    
723     /* Allocate space for a simple emul setup: */
724     n_emuls = 1;
725     emuls[0] = emul_new(NULL);
726     if (emuls[0] == NULL) {
727     fprintf(stderr, "out of memory\n");
728     exit(1);
729     }
730    
731 dpavlin 4 get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages);
732 dpavlin 2
733     if (!fully_deterministic) {
734     /* TODO: More than just time(). Use gettimeofday(). */
735     srandom(time(NULL) ^ (getpid() << 12));
736     } else {
737     /* Fully deterministic. -I must have been supplied. */
738     if (emuls[0]->machines[0]->automatic_clock_adjustment) {
739     fatal("Cannot have -D without -I.\n");
740     exit(1);
741     }
742     }
743    
744     /* Print startup message: */
745     debug("GXemul");
746     #ifdef VERSION
747     debug("-" VERSION);
748     #endif
749     debug(" Copyright (C) 2003-2005 Anders Gavare\n");
750     debug("Read the source code and/or documentation for "
751     "other Copyright messages.\n\n");
752    
753     if (emuls[0]->machines[0]->machine_type == MACHINE_NONE)
754     n_emuls --;
755 dpavlin 4 else {
756     for (i=0; i<n_diskimages; i++)
757     diskimage_add(emuls[0]->machines[0], diskimages[i]);
758     }
759 dpavlin 2
760     /* Simple initialization, from command line arguments: */
761     if (n_emuls > 0) {
762     /* Make sure that there are no configuration files as well: */
763     for (i=1; i<argc; i++)
764     if (argv[i][0] == '@') {
765     fprintf(stderr, "You can either start one "
766     "emulation with one machine directly from "
767     "the command\nline, or start one or more "
768     "emulations using configuration files."
769     " Not both.\n");
770     exit(1);
771     }
772    
773     /* Initialize one emul: */
774     emul_simple_init(emuls[0]);
775     }
776    
777     /* Initialize emulations from config files: */
778     for (i=1; i<argc; i++) {
779     if (argv[i][0] == '@') {
780     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     emuls = realloc(emuls, sizeof(struct emul *) * n_emuls);
788     if (emuls == NULL) {
789     fprintf(stderr, "out of memory\n");
790     exit(1);
791     }
792     emuls[n_emuls - 1] =
793     emul_create_from_configfile(s);
794    
795     /* Always allow slave xterms when using multiple
796     emulations: */
797     console_allow_slaves(1);
798     }
799     }
800    
801     if (n_emuls == 0) {
802 dpavlin 6 fprintf(stderr, "No emulations defined. Maybe you forgot to "
803 dpavlin 12 "use -E xx and/or -e yy, to specify\nthe machine type."
804     " For example:\n\n %s -e 3max -d disk.img\n\n"
805 dpavlin 6 "to boot an emulated DECstation 5000/200 with a disk "
806     "image.\n", progname);
807 dpavlin 2 exit(1);
808     }
809    
810     device_set_exit_on_error(0);
811 dpavlin 20 console_warn_if_slaves_are_needed();
812 dpavlin 2
813     /* Run all emulations: */
814     emul_run(emuls, n_emuls);
815    
816     return 0;
817     }
818    

  ViewVC Help
Powered by ViewVC 1.1.26