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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (hide annotations)
Mon Oct 8 16:18:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 21480 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.772 2005/06/04 12:02:16 debug Exp $
20050428	Disabling the "-fmove-all-movables" option in the configure
		script, because it causes the compile to fail on OpenBSD/sgi.
20050502	Minor updates.
20050503	Removing the WRT54G mode (it was bogus anyway), and adding a
		comment about Windows NT for MIPS in doc/experiments.html.
		Minor updates to the x86 instruction decoding.
20050504	Adding some more x86 instructions.
		Adding support for reading files from ISO9660 CDROMs (including
		gzipped files). It's an ugly hack, but it seems to work.
		Various other minor updates (dev_vga.c, pc_bios.c etc).
20050505	Some more x86-related updates.
		Beginning (what I hope will be) a major code cleanup phase.
		"bootris" (an x86 bootsector) runs :-)
20050506	Adding some more x86 instructions.
20050507	tmpnam => mkstemp.
		Working on a hack to allow VGA charcells to be shown even when
		not running with X11.
		Adding more x86 instructions.
20050508	x86 32-bit SIB addressing fix, and more instructions.
20050509	Adding more x86 instructions.
20050510	Minor documentation updates, and other updates (x86 stuff etc.)
20050511	More x86-related updates.
20050513	Various updates, mostly x86-related. (Trying to fix flag 
		calculation, factoring out the ugly shift/rotate code, and
		some other things.)
20050514	Adding support for loading some old i386 a.out executables.
		Finally beginning the cleanup of machine/PROM/bios dependant
		info.
		Some minor documentation updates.
		Trying to clean up ARCBIOS stuff a little.
20050515	Trying to make it possible to actually use more than one disk
		type per machine (floppy, ide, scsi).
		Trying to clean up the kbd vs PROM console stuff. (For PC and
		ARC emulation modes, mostly.)
		Beginning to add an 8259 interrupt controller, and connecting
		it to the x86 emulation.
20050516	The first x86 interrupts seem to work (keyboard stuff).
		Adding a 8253/8254 programmable interval timer skeleton.
		FreeDOS now reaches a command prompt and can be interacted
		with.
20050517	After some bugfixes, MS-DOS also (sometimes) reaches a
		command prompt now.
		Trying to fix the pckbc to work with MS-DOS' keyb.com, but no
		success yet.
20050518	Adding a simple 32-bit x86 MMU skeleton.
20050519	Some more work on the x86 stuff. (Beginning the work on paging,
		and various other fixes).
20050520	More updates. Working on dev_vga (4-bit graphics modes), adding
		40 columns support to the PC bios emulation.
		Trying to add support for resizing windows when switching
		between graphics modes.
20050521	Many more x86-related updates.
20050522	Correcting the initial stack pointer's sign-extension for
		ARCBIOS emulation (thanks to Alec Voropay for noticing the
		error).
		Continuing on the cleanup (ARCBIOS etc).
		dev_vga updates.
20050523	More x86 updates: trying to add some support for protected mode
		interrupts (via gate descriptors) and many other fixes.
		More ARCBIOS cleanup.
		Adding a device flag which indicates that reads cause no
		side-effects. (Useful for the "dump" command in the debugger,
		and other things.)
		Adding support for directly starting up x86 ELFs, skipping the
		bootloader stage. (Most ELFs, however, are not suitable for
		this.)
20050524	Adding simple 32-bit x86 TSS task switching, but no privilege
		level support yet.
		More work on dev_vga. A small "Copper bars" demo works. :-)
		Adding support for Trap Flag (single-step exceptions), at least
		in real mode, and various other x86-related fixes.
20050525	Adding a new disk image prefix (gH;S;) which can be used to
		override the default nr of heads and sectors per track.
20050527	Various bug fixes, more work on the x86 mode (stack change on
		interrupts between different priv.levels), and some minor
		documentation updates.
20050528	Various fixes (x86 stuff).
20050529	More x86 fixes. An OpenBSD/i386 bootfloppy reaches userland
		and can be interacted with (although there are problems with
		key repetition). NetBSD/i386 triggers a serious CISC-related
		problem: instruction fetches across page boundaries, where
		the later part isn't actually part of the instruction.
20050530	Various minor updates. (Documentation updates, etc.)
20050531	Adding some experimental code (experiments/new_test_*) which
		could be useful for dynamic (but not binary) translation in
		the future.
20050602	Adding a dummy ARM skeleton.
		Fixing the pckbc key repetition problem (by adding release
		scancodes for all keypresses).
20050603	Minor updates for the next release.
20050604	Release testing. Minor updates.

==============  RELEASE 0.3.3  ==============

20050604	There'll probably be a 0.3.3.1 release soon, with some very
		very tiny updates.


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

  ViewVC Help
Powered by ViewVC 1.1.26