|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
1.1.1.3 root 3: *
4: * Main program
5: *
6: * Copyright 1995 Ed Hanway
7: * Copyright 1995, 1996, 1997 Bernd Schmidt
1.1 root 8: */
9:
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12: #include <assert.h>
13:
14: #include "config.h"
15: #include "options.h"
1.1.1.3 root 16: #include "threaddep/penguin.h"
1.1.1.2 root 17: #include "uae.h"
1.1.1.3 root 18: #include "gensound.h"
19: #include "sounddep/sound.h"
1.1.1.2 root 20: #include "events.h"
1.1 root 21: #include "memory.h"
22: #include "custom.h"
23: #include "serial.h"
1.1.1.2 root 24: #include "readcpu.h"
1.1 root 25: #include "newcpu.h"
26: #include "disk.h"
27: #include "debug.h"
28: #include "xwin.h"
1.1.1.3 root 29: #include "joystick.h"
1.1 root 30: #include "keybuf.h"
31: #include "gui.h"
32: #include "zfile.h"
33: #include "autoconf.h"
1.1.1.2 root 34: #include "osemu.h"
1.1.1.3 root 35: #include "osdep/exectasks.h"
1.1 root 36: #include "compiler.h"
1.1.1.3 root 37: #include "picasso96.h"
38: #include "uaeexe.h"
1.1.1.4 ! root 39: #include "getopt.h"
1.1 root 40:
1.1.1.4 ! root 41: long int version = 256*65536L*UAEMAJOR + 65536L*UAEMINOR + UAESUBREV;
1.1.1.3 root 42:
43: struct uae_prefs currprefs;
44:
1.1.1.4 ! root 45: struct uae_prefs changed_prefs;
! 46:
! 47: int no_gui = 0, use_debugger = 0, use_gfxlib = 0;
! 48:
! 49: int joystickpresent = 0;
! 50:
! 51: int cloanto_rom = 0;
! 52:
! 53: char warning_buffer[256];
! 54:
! 55: char romfile[256] = "kick.rom";
! 56: char keyfile[256] = "";
! 57: char prtname[256] = DEFPRTNAME;
! 58:
! 59: char optionsfile[256];
! 60:
! 61: /* If you want to pipe printer output to a file, put something like
! 62: * "cat >>printerfile.tmp" above.
! 63: * The printer support was only tested with the driver "PostScript" on
! 64: * Amiga side, using apsfilter for linux to print ps-data.
! 65: *
! 66: * Under DOS it ought to be -p LPT1: or -p PRN: but you'll need a
! 67: * PostScript printer or ghostscript -=SR=-
! 68: */
! 69:
! 70: /* People must provide their own name for this */
! 71: char sername[256] = "";
! 72:
! 73: /* Slightly stupid place for this... */
! 74: /* ncurses.c might use quite a few of those. */
! 75: char *colormodes[] = { "256 colors", "32768 colors", "65536 colors",
! 76: "256 colors dithered", "16 colors dithered", "16 million colors",
! 77: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
! 78: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
! 79: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
! 80: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
! 81: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
! 82: };
! 83:
1.1.1.3 root 84: static void default_currprefs (void)
85: {
1.1.1.4 ! root 86: /* Note to porters: please don't change any of these options! UAE is supposed
! 87: * to behave identically on all platforms if possible. */
1.1.1.3 root 88: currprefs.framerate = 1;
89: currprefs.illegal_mem = 0;
90: currprefs.no_xhair = 0;
91: currprefs.use_serial = 0;
92: currprefs.serial_demand = 0;
93: currprefs.parallel_demand = 0;
94: currprefs.automount_uaedev = 1;
95:
96: currprefs.fake_joystick = 2 + (0<<8);
97: currprefs.keyboard_lang = KBD_LANG_US;
98: currprefs.emul_accuracy = 2;
99: currprefs.test_drawing_speed = 0;
100:
101: currprefs.produce_sound = 0;
102: currprefs.stereo = 0;
103: currprefs.sound_bits = DEFAULT_SOUND_BITS;
104: currprefs.sound_freq = DEFAULT_SOUND_FREQ;
105: currprefs.sound_minbsiz = DEFAULT_SOUND_MINB;
106: currprefs.sound_maxbsiz = DEFAULT_SOUND_MAXB;
107:
108: currprefs.gfx_width = 800;
109: currprefs.gfx_height = 600;
110: currprefs.gfx_lores = 0;
111: currprefs.gfx_linedbl = 0;
1.1.1.4 ! root 112: currprefs.gfx_afullscreen = 0;
! 113: currprefs.gfx_pfullscreen = 0;
1.1.1.3 root 114: currprefs.gfx_correct_aspect = 0;
115: currprefs.gfx_xcenter = 0;
116: currprefs.gfx_ycenter = 0;
117: currprefs.color_mode = 0;
118:
119: currprefs.use_low_bandwidth = 0;
120: currprefs.use_mitshm = 0;
121:
122: currprefs.immediate_blits = 0;
123: currprefs.blits_32bit_enabled = 0;
124:
125: strcpy (currprefs.df[0], "df0.adf");
126: strcpy (currprefs.df[1], "df1.adf");
127: strcpy (currprefs.df[2], "df2.adf");
128: strcpy (currprefs.df[3], "df3.adf");
129:
130: currprefs.m68k_speed = 4;
131: currprefs.cpu_level = 0;
132: currprefs.cpu_compatible = 0;
133: currprefs.address_space_24 = 1;
1.1 root 134:
1.1.1.4 ! root 135: currprefs.fastmem_size = 0x00000000;
! 136: currprefs.a3000mem_size = 0x00000000;
! 137: currprefs.z3fastmem_size = 0x00000000;
! 138: currprefs.chipmem_size = 0x00200000;
! 139: currprefs.bogomem_size = 0x00000000;
! 140: currprefs.gfxmem_size = 0x00000000;
1.1 root 141:
1.1.1.4 ! root 142: currprefs.mountinfo = alloc_mountinfo ();
! 143: }
1.1 root 144:
1.1.1.4 ! root 145: void fixup_prefs_dimensions (struct uae_prefs *prefs)
! 146: {
! 147: if (prefs->gfx_width < 320)
! 148: prefs->gfx_width = 320;
! 149: if (prefs->gfx_height < 200)
! 150: prefs->gfx_height = 200;
! 151: if (prefs->gfx_height > 300 && ! prefs->gfx_linedbl)
! 152: prefs->gfx_height = 300;
! 153: if (prefs->gfx_height > 600)
! 154: prefs->gfx_height = 600;
1.1 root 155:
1.1.1.4 ! root 156: prefs->gfx_width += 7; /* X86.S wants multiples of 4 bytes, might be 8 in the future. */
! 157: prefs->gfx_width &= ~7;
! 158: }
1.1.1.3 root 159:
1.1.1.4 ! root 160: static void fix_options (void)
1.1.1.2 root 161: {
1.1.1.3 root 162: int err = 0;
163:
1.1.1.4 ! root 164: if ((currprefs.chipmem_size & (currprefs.chipmem_size - 1)) != 0
! 165: || currprefs.chipmem_size < 0x80000
! 166: || currprefs.chipmem_size > 0x800000)
1.1.1.3 root 167: {
1.1.1.4 ! root 168: currprefs.chipmem_size = 0x200000;
1.1.1.3 root 169: fprintf (stderr, "Unsupported chipmem size!\n");
170: err = 1;
171: }
1.1.1.4 ! root 172: if ((currprefs.fastmem_size & (currprefs.fastmem_size - 1)) != 0
! 173: || (currprefs.fastmem_size != 0 && (currprefs.fastmem_size < 0x100000 || currprefs.fastmem_size > 0x800000)))
1.1.1.3 root 174: {
1.1.1.4 ! root 175: currprefs.fastmem_size = 0;
1.1.1.3 root 176: fprintf (stderr, "Unsupported fastmem size!\n");
177: err = 1;
178: }
1.1.1.4 ! root 179: if ((currprefs.gfxmem_size & (currprefs.gfxmem_size - 1)) != 0
! 180: || (currprefs.gfxmem_size != 0 && (currprefs.gfxmem_size < 0x100000 || currprefs.gfxmem_size > 0x800000)))
1.1.1.3 root 181: {
1.1.1.4 ! root 182: currprefs.gfxmem_size = 0;
1.1.1.3 root 183: fprintf (stderr, "Unsupported graphics card memory size!\n");
184: err = 1;
185: }
1.1.1.4 ! root 186: if ((currprefs.z3fastmem_size & (currprefs.z3fastmem_size - 1)) != 0
! 187: || (currprefs.z3fastmem_size != 0 && (currprefs.z3fastmem_size < 0x100000 || currprefs.z3fastmem_size > 0x4000000)))
1.1.1.3 root 188: {
1.1.1.4 ! root 189: currprefs.z3fastmem_size = 0;
1.1.1.3 root 190: fprintf (stderr, "Unsupported Zorro III fastmem size!\n");
191: err = 1;
192: }
1.1.1.4 ! root 193: if (currprefs.address_space_24 && (currprefs.gfxmem_size != 0 || currprefs.z3fastmem_size != 0)) {
! 194: currprefs.z3fastmem_size = currprefs.gfxmem_size = 0;
1.1.1.3 root 195: fprintf (stderr, "Can't use a graphics card or Zorro III fastmem when using a 24 bit\n"
196: "address space - sorry.\n");
197: }
1.1.1.4 ! root 198: if ((currprefs.bogomem_size & (currprefs.bogomem_size - 1)) != 0
! 199: || (currprefs.bogomem_size != 0 && (currprefs.bogomem_size < 0x80000 || currprefs.bogomem_size > 0x100000)))
1.1.1.3 root 200: {
1.1.1.4 ! root 201: currprefs.bogomem_size = 0;
1.1.1.3 root 202: fprintf (stderr, "Unsupported bogomem size!\n");
203: err = 1;
204: }
205:
1.1.1.4 ! root 206: if (currprefs.chipmem_size > 0x200000 && currprefs.fastmem_size != 0) {
1.1.1.3 root 207: fprintf (stderr, "You can't use fastmem and more than 2MB chip at the same time!\n");
1.1.1.4 ! root 208: currprefs.fastmem_size = 0;
1.1.1.3 root 209: err = 1;
210: }
1.1.1.4 ! root 211: if (currprefs.m68k_speed < -1 || currprefs.m68k_speed > 20) {
! 212: fprintf (stderr, "Bad value for -w parameter: must be -1, 0, or within 1..20.\n");
1.1.1.3 root 213: currprefs.m68k_speed = 4;
214: err = 1;
215: }
216: if (currprefs.produce_sound < 0 || currprefs.produce_sound > 3) {
217: fprintf (stderr, "Bad value for -S parameter: enable value must be within 0..3\n");
218: currprefs.produce_sound = 0;
219: err = 1;
220: }
1.1.1.4 ! root 221: if (currprefs.cpu_level < 2 && currprefs.z3fastmem_size > 0) {
1.1.1.3 root 222: fprintf (stderr, "Z3 fast memory can't be used with a 68000/68010 emulation. It\n"
223: "requires a 68020 emulation. Turning off Z3 fast memory.\n");
1.1.1.4 ! root 224: currprefs.z3fastmem_size = 0;
1.1.1.3 root 225: err = 1;
226: }
1.1.1.4 ! root 227: if (currprefs.cpu_level < 2 && currprefs.gfxmem_size > 0) {
1.1.1.3 root 228: fprintf (stderr, "Picasso96 can't be used with a 68000/68010 emulation. It\n"
229: "requires a 68020 emulation. Turning off Picasso96.\n");
1.1.1.4 ! root 230: currprefs.gfxmem_size = 0;
1.1.1.3 root 231: err = 1;
232: }
233:
234: if (err)
235: fprintf (stderr, "Please use \"uae -h\" to get usage information.\n");
236: }
237:
238: int quit_program = 0;
239:
240: void uae_reset (void)
241: {
1.1.1.4 ! root 242: if (quit_program == 0)
1.1.1.3 root 243: quit_program = -2;
244: }
245:
246: void uae_quit (void)
247: {
248: if (quit_program != -1)
249: quit_program = -1;
1.1.1.2 root 250: }
1.1 root 251:
1.1.1.3 root 252: /*
253: * This function is dangerous, at least if you use different versions of UAE
254: * from time to time (as I do). For example, running the SVGAlib version with
255: * "-o" will discard the keyboard language information...
256: */
1.1.1.4 ! root 257: void save_options (FILE *f)
1.1.1.3 root 258: {
259: int i;
260: if (use_debugger)
261: fprintf (f, "-D\n");
262: fprintf (f, "-r %s\n", romfile);
263: if (strlen (keyfile) > 0)
264: fprintf (f, "-K %s\n", keyfile);
265: for (i = 0; i < 4; i++)
266: if (strlen (currprefs.df[i]) > 0)
267: fprintf (f, "-%d %s\n", i, currprefs.df[i]);
268:
269: #ifndef UNSUPPORTED_OPTION_p
270: fprintf (f, "-p %s\n", prtname);
271: #endif
272: #ifndef UNSUPPORTED_OPTION_S
273: fprintf (f, "-S %d:%c:%d:%d:%d:%d\n", currprefs.produce_sound,
274: currprefs.stereo ? 's' : 'm',
275: currprefs.sound_bits,
276: currprefs.sound_freq,
277: currprefs.sound_maxbsiz,
278: currprefs.sound_minbsiz);
279: #endif
280: if (currprefs.fake_joystick)
281: fprintf (f, "-J %c%c\n", "01MABC"[currprefs.fake_joystick & 255],
282: "01MABC"[(currprefs.fake_joystick >> 8) & 255]);
283: fprintf (f, "-f %d\n", currprefs.framerate);
284: fprintf (f, "-O %d:%d:", currprefs.gfx_width, currprefs.gfx_height);
285: if (currprefs.gfx_lores)
286: fprintf (f, "l");
287: switch (currprefs.gfx_xcenter) {
288: case 1: fprintf (f, "x"); break;
289: case 2: fprintf (f, "X"); break;
290: default: break;
291: }
292: switch (currprefs.gfx_ycenter) {
293: case 1: fprintf (f, "y"); break;
294: case 2: fprintf (f, "Y"); break;
295: default: break;
296: }
297: if (currprefs.gfx_linedbl)
298: fprintf (f, "d");
299: if (currprefs.gfx_correct_aspect)
300: fprintf (f, "c");
301: fprintf (f, "\n-H %d\n", currprefs.color_mode);
1.1.1.4 ! root 302: if (currprefs.fastmem_size > 0)
! 303: fprintf (f, "-F %d\n", currprefs.fastmem_size / 0x100000);
! 304: if (currprefs.z3fastmem_size > 0)
! 305: fprintf (f, "-Z %d\n", currprefs.z3fastmem_size / 0x100000);
! 306: if (currprefs.bogomem_size > 0)
! 307: fprintf (f, "-s %d\n", currprefs.bogomem_size / 0x40000);
! 308: if (currprefs.gfxmem_size > 0)
! 309: fprintf (f, "-U %d\n", currprefs.gfxmem_size / 0x100000);
! 310: fprintf (f, "-c %d\n", currprefs.chipmem_size / 0x80000);
1.1.1.3 root 311:
312: fprintf (f, "-C %d%s\n", currprefs.cpu_level,
313: (currprefs.cpu_compatible ? "c"
314: : currprefs.address_space_24 && currprefs.cpu_level > 1 ? "a"
315: : ""));
316:
317: if (!currprefs.automount_uaedev)
318: fprintf (f, "-a\n");
319: if (currprefs.use_low_bandwidth)
320: fprintf (f, "-L\n");
321: if (currprefs.use_mitshm)
322: fprintf (f, "-T\n");
323: fprintf (f, "-w %d\n", currprefs.m68k_speed);
324: fprintf (f, "-A %d\n", currprefs.emul_accuracy);
325: /* We don't write "-t" - I can hardly imagine a user who wants that in his
326: * config file. */
1.1.1.4 ! root 327: write_filesys_config (currprefs.mountinfo, f);
1.1.1.3 root 328: #ifndef UNSUPPORTED_OPTION_l
329: fprintf (f, "-l %s\n", (currprefs.keyboard_lang == KBD_LANG_DE ? "de"
330: : currprefs.keyboard_lang == KBD_LANG_ES ? "es"
331: : currprefs.keyboard_lang == KBD_LANG_US ? "us"
332: : currprefs.keyboard_lang == KBD_LANG_SE ? "se"
333: : currprefs.keyboard_lang == KBD_LANG_FR ? "fr"
334: : currprefs.keyboard_lang == KBD_LANG_IT ? "it"
335: : "FOO"));
336: #endif
337: }
338:
339: struct optiondef {
340: const char *getopt_str;
341: const char *helpstr;
342: };
343:
344:
345: static struct optiondef uaeopts[] = {
346: { "h", " -h : Print help\n" },
347: #ifndef UNSUPPORTED_OPTION_l
348: { "l:", " -l lang : Set keyboard language to lang, where lang is\n"
349: " DE, SE, US, ES, FR or IT\n" },
350: #endif
351: { "m:", " -m VOL:dir : Mount directory called <dir> as AmigaDOS volume VOL:\n" },
352: { "M:", " -M VOL:dir : like -m, but mount read-only\n" },
353: { "W:", " -W specs : Mount a hardfile. The \"specs\" parameter consists of\n"
354: " \"sectors per track:number of surfaces:filename\"\n" },
355: { "s:", " -s n : Emulate n*256 KB slow memory at 0xC00000\n" },
356: { "c:", " -c n : Emulate n*512 KB chip memory at 0x000000\n" },
357: { "F:", " -F n : Emulate n MB fast memory at 0x200000\n" },
358: { "Z:", " -Z n : Emulate n MB Zorro III fast memory\n" },
359: #if defined PICASSO96
360: { "U:", " -U n : Emulate a Picasso96 compatible graphics card with n MB memory\n" },
361: #endif
362: { "w:", " -w n : Set CPU speed to n (default 4)\n" },
363: { "a", " -a : Add no expansion devices (disables fastmem and\n"
364: " harddisk support\n" },
365: { "J:", " -J xy : Specify how to emulate joystick port 0 (x) and 1 (y)\n"
366: " Use 0 for joystick 0, 1 for joystick 1, M for mouse,\n"
367: " a/b/c for various keyboard replacements\n" },
368: { "f:", " -f n : Set the frame rate to 1/n (draw only every nth frame)\n" },
369: #ifndef UNSUPPORTED_OPTION_D
370: { "D", " -D : Start up the built-in debugger\n" },
371: #endif
372: { "i", " -i : Print illegal memory accesses\n" },
373: { "t", " -t : Test drawing speed (makes the emulator very slow)\n" },
374: #ifndef UNSUPPORTED_OPTION_G
375: { "G", " -G : Disable user interface\n" },
376: #endif
377: { "A:", " -A n : Set emulator accuracy to n (0, 1 or 2)\n" },
378: #ifdef USE_EXECLIB
379: { "g", " -g : Turn on gfx-lib replacement (EXPERIMENTAL).\n" },
380: #endif
381: { "C:", " -C parms : Set CPU parameters. '0' for 68000 emulation, '1' for\n"
382: " 68010, '2' for 68020, '3' for 68020/68881. Additionally,\n"
383: " you can specify 'c' for a slow but compatible emulation\n"
384: " and 'a' for a 24 bit address space.\n" },
385: { "n:", " -n parms : Set blitter parameters: 'i' enables immediate blits,\n"
386: " '3' enables 32 bit blits (may crash RISC machines)\n" },
387: { "0:1:2:3:", " -[0123] file : Use file instead of df[0123].adf as disk image\n" },
388: { "r:", " -r file : Use file as ROM image instead of kick.rom\n" },
389: { "K:", " -K file : Use file as ROM key file for encrypted ROMs.\n" },
390: #ifndef UNSUPPORTED_OPTION_S
391: { "S:", " -S spec : Set parameters for sound emulation (see below)\n" },
392: #endif
393: #ifndef UNSUPPORTED_OPTION_p
394: { "p:", " -p prt : Use <prt> for printer output (default " DEFPRTNAME ").\n" },
395: #endif
396: #ifndef UNSUPPORTED_OPTION_I
397: { "I:", " -I device : Use <device> for serial output (e.g. " DEFSERNAME ").\n" },
398: { "d:", " -d [s][p] : Open serial/parallel port on demand only.\n" },
399: #endif
400: #ifdef TARGET_SPECIAL_OPTIONS
401: TARGET_SPECIAL_OPTIONS
402: #endif
403: { "O:", " -O modespec : Define graphics mode (see below)\n" },
404: { "H:", " -H mode : Set the color mode (see below)\n" }
405: };
406:
1.1.1.4 ! root 407: void usage (void)
1.1 root 408: {
1.1.1.3 root 409: int i;
410:
411: printf ("UAE - The Un*x Amiga emulator\n");
412: printf ("Summary of command-line options (please read the README for more details):\n");
413: for (i = 0; i < sizeof uaeopts / sizeof *uaeopts; i++)
414: printf ("%s", uaeopts[i].helpstr);
415:
416: printf ("\n");
417: printf ("%s",
418: "The format for the \"-S\" sound spec parameter is as follows:\n"
419: " -S enable:stereo:bits:freq:maxbuffer:minbuffer\n"
420: " You do not need to give the full specs, you can terminate after every field.\n"
421: " enable: Either 0 (no sound), 1 (emulated, but not output), 2 (emulated), or\n"
422: " 3 (completely accurate emulation). The suggested value is 2.\n"
423: " stereo: Either 's' (stereo) or 'm' (mono).\n"
424: " bits: Number of bits to use for sound output, usually 8 or 16\n"
425: " freq: Frequency for sound output; usually 44100 or 22050\n"
426: " maxbuffer: Maximum buffer size for sound output\n"
427: " minbuffer: Minimum buffer size for sound output\n"
428: "Larger buffers need less computing power, but the sound will be delayed.\n"
429: "Some of these settings will have no effect on certain ports of UAE.\n");
430: printf ("%s",
431: #ifndef COLOR_MODE_HELP_STRING
1.1 root 432: "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
433: " 3 (256 colors, with dithering for better results)\n"
434: " 4 (16 colors, dithered); 5 (16 million colors)\n"
1.1.1.3 root 435: #else
436: COLOR_MODE_HELP_STRING
437: #endif
438: );
439: printf ("%s",
1.1.1.2 root 440: "The format for the modespec parameter of \"-O\" is as follows:\n"
441: " -O width:height:modifiers\n"
442: " \"width\" and \"height\" specify the dimensions of the picture.\n"
443: " \"modifiers\" is a string that contains zero or more of the following\n"
444: " characters:\n"
1.1.1.3 root 445: " l: Treat the display as lores, drawing only every second pixel\n"
1.1.1.2 root 446: " x, y: Center the screen horizontally or vertically.\n"
1.1.1.3 root 447: " d: Doubles the height of the display for better interlace emulation\n"
448: " c: Correct aspect ratio\n"
1.1.1.2 root 449: "UAE may choose to ignore the color mode setting and/or adjust the\n"
1.1.1.3 root 450: "video mode setting to reasonable values.\n");
1.1 root 451: }
452:
1.1.1.2 root 453: static void parse_gfx_specs (char *spec)
454: {
455: char *x0 = my_strdup (spec);
456: char *x1, *x2;
1.1.1.3 root 457:
1.1.1.2 root 458: x1 = strchr (x0, ':');
459: if (x1 == 0)
460: goto argh;
461: x2 = strchr (x1+1, ':');
462: if (x2 == 0)
463: goto argh;
464: *x1++ = 0; *x2++ = 0;
1.1.1.3 root 465:
466: currprefs.gfx_width = atoi (x0);
467: currprefs.gfx_height = atoi (x1);
468: currprefs.gfx_lores = strchr (x2, 'l') != 0;
469: currprefs.gfx_xcenter = strchr (x2, 'x') != 0 ? 1 : strchr (x2, 'X') != 0 ? 2 : 0;
470: currprefs.gfx_ycenter = strchr (x2, 'y') != 0 ? 1 : strchr (x2, 'Y') != 0 ? 2 : 0;
471: currprefs.gfx_linedbl = strchr (x2, 'd') != 0;
1.1.1.4 ! root 472: currprefs.gfx_afullscreen = strchr (x2, 'a') != 0;
! 473: currprefs.gfx_pfullscreen = strchr (x2, 'p') != 0;
1.1.1.3 root 474: currprefs.gfx_correct_aspect = strchr (x2, 'c') != 0;
475:
1.1.1.2 root 476: free (x0);
477: return;
1.1.1.3 root 478:
1.1.1.2 root 479: argh:
480: fprintf (stderr, "Bad display mode specification.\n");
481: fprintf (stderr, "The format to use is: \"width:height:modifiers\"\n");
1.1.1.3 root 482: fprintf (stderr, "Type \"uae -h\" for detailed help.\n");
1.1.1.2 root 483: free (x0);
484: }
485:
1.1.1.3 root 486: static void parse_sound_spec (char *spec)
487: {
488: char *x0 = my_strdup (spec);
489: char *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL, *x5 = NULL;
1.1 root 490:
1.1.1.3 root 491: x1 = strchr (x0, ':');
492: if (x1 != NULL) {
493: *x1++ = '\0';
494: x2 = strchr (x1 + 1, ':');
495: if (x2 != NULL) {
496: *x2++ = '\0';
497: x3 = strchr (x2 + 1, ':');
498: if (x3 != NULL) {
499: *x3++ = '\0';
500: x4 = strchr (x3 + 1, ':');
501: if (x4 != NULL) {
502: *x4++ = '\0';
503: x5 = strchr (x4 + 1, ':');
504: }
505: }
506: }
507: }
508: currprefs.produce_sound = atoi (x0);
509: if (x1) {
510: if (*x1 == 's')
511: currprefs.stereo = 1;
512: else
513: currprefs.stereo = 0;
514: }
515: if (x2)
516: currprefs.sound_bits = atoi (x2);
517: if (x3)
518: currprefs.sound_freq = atoi (x3);
519: if (x4)
520: currprefs.sound_maxbsiz = currprefs.sound_minbsiz = atoi (x4);
521: if (x5)
522: currprefs.sound_minbsiz = atoi (x5);
523: free (x0);
524: return;
525: }
526:
527: const char *gameport_state (int nr)
1.1 root 528: {
1.1.1.3 root 529: if (JSEM_ISJOY0 (nr, currprefs.fake_joystick) && nr_joysticks > 0)
530: return "using joystick #0";
531: else if (JSEM_ISJOY1 (nr, currprefs.fake_joystick) && nr_joysticks > 1)
532: return "using joystick #1";
533: else if (JSEM_ISMOUSE (nr, currprefs.fake_joystick))
534: return "using mouse";
535: else if (JSEM_ISNUMPAD (nr, currprefs.fake_joystick))
536: return "using numeric pad as joystick";
537: else if (JSEM_ISCURSOR (nr, currprefs.fake_joystick))
538: return "using cursor keys as joystick";
539: else if (JSEM_ISSOMEWHEREELSE (nr, currprefs.fake_joystick))
540: return "using T/F/H/B/Alt as joystick";
541:
542: return "not connected";
543: }
544:
1.1.1.4 ! root 545: int parse_joy_spec (char *spec)
1.1.1.3 root 546: {
547: int v0 = 2, v1 = 0;
548: if (strlen(spec) != 2)
549: goto bad;
550:
551: switch (spec[0]) {
552: case '0': v0 = 0; break;
553: case '1': v0 = 1; break;
554: case 'M': case 'm': v0 = 2; break;
555: case 'A': case 'a': v0 = 3; break;
556: case 'B': case 'b': v0 = 4; break;
557: case 'C': case 'c': v0 = 5; break;
558: default: goto bad;
559: }
560:
561: switch (spec[1]) {
562: case '0': v1 = 0; break;
563: case '1': v1 = 1; break;
564: case 'M': case 'm': v1 = 2; break;
565: case 'A': case 'a': v1 = 3; break;
566: case 'B': case 'b': v1 = 4; break;
567: case 'C': case 'c': v1 = 5; break;
568: default: goto bad;
569: }
570: if (v0 == v1)
571: goto bad;
572: /* Let's scare Pascal programmers */
573: if (0)
574: bad:
575: fprintf (stderr, "Bad joystick mode specification. Use -J xy, where x and y\n"
576: "can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n"
577: "a, b or c for different keyboard settings.\n");
578:
579: return v0 + (v1 << 8);
580: }
581:
582: static void parse_filesys_spec (int readonly, char *spec)
583: {
584: char buf[256];
585: char *s2;
586:
1.1.1.4 ! root 587: strncpy (buf, spec, 255); buf[255] = 0;
! 588: s2 = strchr (buf, ':');
! 589: if (s2) {
1.1.1.3 root 590: *s2++ = '\0';
591: #ifdef __DOS__
592: {
593: char *tmp;
594:
1.1.1.4 ! root 595: while ((tmp = strchr (s2, '\\')))
1.1.1.3 root 596: *tmp = '/';
597: }
1.1.1.2 root 598: #endif
1.1.1.4 ! root 599: s2 = add_filesys_unit (currprefs.mountinfo, buf, s2, readonly, 0, 0, 0);
1.1.1.3 root 600: if (s2)
601: fprintf (stderr, "%s\n", s2);
602: } else {
603: fprintf (stderr, "Usage: [-m | -M] VOLNAME:mount_point\n");
604: }
605: }
606:
607: static void parse_hardfile_spec (char *spec)
608: {
609: char *x0 = my_strdup (spec);
610: char *x1, *x2, *x3;
611:
612: x1 = strchr (x0, ':');
613: if (x1 == NULL)
614: goto argh;
615: *x1++ = '\0';
616: x2 = strchr (x1 + 1, ':');
617: if (x2 == NULL)
618: goto argh;
619: *x2++ = '\0';
620: x3 = strchr (x2 + 1, ':');
621: if (x3 == NULL)
622: goto argh;
623: *x3++ = '\0';
1.1.1.4 ! root 624: x3 = add_filesys_unit (currprefs.mountinfo, 0, x3, 0, atoi (x0), atoi (x1), atoi (x2));
1.1.1.3 root 625: if (x3)
626: fprintf (stderr, "%s\n", x3);
627:
628: free (x0);
629: return;
630:
631: argh:
632: free (x0);
633: fprintf (stderr, "Bad hardfile parameter specified - type \"uae -h\" for help.\n");
634: return;
635: }
636:
637: static void parse_cpu_specs (char *spec)
638: {
639: if (*spec < '0' || *spec > '3') {
640: fprintf (stderr, "CPU parameter string must begin with '0', '1', '2' or '3'.\n");
641: return;
642: }
643:
644: currprefs.cpu_level = *spec++ - '0';
645: currprefs.address_space_24 = currprefs.cpu_level < 2;
646: currprefs.cpu_compatible = 0;
647: while (*spec != '\0') {
648: switch (*spec) {
649: case 'a':
650: if (currprefs.cpu_level < 2)
651: fprintf (stderr, "In 68000/68010 emulation, the address space is always 24 bit.\n");
652: else
653: currprefs.address_space_24 = 1;
654: break;
655: case 'c':
656: if (currprefs.cpu_level != 0)
657: fprintf (stderr, "The more compatible CPU emulation is only available for 68000\n"
658: "emulation, not for 68010 upwards.\n");
659: else
660: currprefs.cpu_compatible = 1;
661: break;
662: default:
663: fprintf (stderr, "Bad CPU parameter specified - type \"uae -h\" for help.\n");
664: break;
665: }
666: spec++;
667: }
668: }
669:
670: #ifndef DONT_PARSE_CMDLINE
671:
1.1.1.4 ! root 672: void parse_cmdline (int argc, char **argv)
1.1.1.3 root 673: {
674: int c, i;
675: char getopt_str[256];
676: strcpy (getopt_str, "");
677:
678: for (i = 0; i < sizeof uaeopts / sizeof *uaeopts; i++)
679: strcat (getopt_str, uaeopts[i].getopt_str);
680:
1.1.1.2 root 681: /* Help! We're running out of letters! */
1.1.1.4 ! root 682: while (((c = getopt (argc, argv, getopt_str)) != EOF))
! 683: switch (c) {
! 684: case 'h': usage (); exit (0);
1.1 root 685:
1.1.1.3 root 686: case '0': strncpy (currprefs.df[0], optarg, 255); currprefs.df[0][255] = 0; break;
687: case '1': strncpy (currprefs.df[1], optarg, 255); currprefs.df[1][255] = 0; break;
688: case '2': strncpy (currprefs.df[2], optarg, 255); currprefs.df[2][255] = 0; break;
689: case '3': strncpy (currprefs.df[3], optarg, 255); currprefs.df[3][255] = 0; break;
690: case 'r': strncpy (romfile, optarg, 255); romfile[255] = 0; break;
691: case 'K': strncpy (keyfile, optarg, 255); keyfile[255] = 0; break;
692: case 'p': strncpy (prtname, optarg, 255); prtname[255] = 0; break;
693: case 'I': strncpy (sername, optarg, 255); sername[255] = 0; currprefs.use_serial = 1; break;
694: case 'm': case 'M': parse_filesys_spec (c == 'M', optarg); break;
695: case 'W': parse_hardfile_spec (optarg); break;
696: case 'S': parse_sound_spec (optarg); break;
697: case 'f': currprefs.framerate = atoi (optarg); break;
698: case 'A': currprefs.emul_accuracy = atoi (optarg); break;
699: case 'x': currprefs.no_xhair = 1; break;
700: case 'i': currprefs.illegal_mem = 1; break;
701: case 'J': currprefs.fake_joystick = parse_joy_spec (optarg); break;
702: case 'a': currprefs.automount_uaedev = 0; break;
703:
704: case 't': currprefs.test_drawing_speed = 1; break;
705: case 'L': currprefs.use_low_bandwidth = 1; break;
706: case 'T': currprefs.use_mitshm = 1; break;
707: case 'w': currprefs.m68k_speed = atoi (optarg); break;
1.1 root 708:
709: case 'g': use_gfxlib = 1; break;
710: case 'G': no_gui = 1; break;
1.1.1.3 root 711: case 'D': use_debugger = 1; break;
1.1.1.2 root 712:
713: case 'n':
714: if (strchr (optarg, '3') != 0)
1.1.1.3 root 715: currprefs.blits_32bit_enabled = 1;
1.1.1.2 root 716: if (strchr (optarg, 'i') != 0)
1.1.1.3 root 717: currprefs.immediate_blits = 1;
1.1.1.2 root 718: break;
719:
720: case 'C':
1.1.1.3 root 721: parse_cpu_specs (optarg);
722: break;
723:
724: case 'Z':
1.1.1.4 ! root 725: currprefs.z3fastmem_size = atoi (optarg) * 0x100000;
1.1.1.3 root 726: break;
727:
728: case 'U':
1.1.1.4 ! root 729: currprefs.gfxmem_size = atoi (optarg) * 0x100000;
1.1.1.2 root 730: break;
1.1 root 731:
732: case 'F':
1.1.1.4 ! root 733: currprefs.fastmem_size = atoi (optarg) * 0x100000;
1.1 root 734: break;
735:
736: case 's':
1.1.1.4 ! root 737: currprefs.bogomem_size = atoi (optarg) * 0x40000;
1.1 root 738: break;
739:
740: case 'c':
1.1.1.4 ! root 741: currprefs.chipmem_size = atoi (optarg) * 0x80000;
1.1 root 742: break;
743:
744: case 'l':
745: if (0 == strcasecmp(optarg, "de"))
1.1.1.3 root 746: currprefs.keyboard_lang = KBD_LANG_DE;
1.1 root 747: else if (0 == strcasecmp(optarg, "us"))
1.1.1.3 root 748: currprefs.keyboard_lang = KBD_LANG_US;
1.1 root 749: else if (0 == strcasecmp(optarg, "se"))
1.1.1.3 root 750: currprefs.keyboard_lang = KBD_LANG_SE;
1.1 root 751: else if (0 == strcasecmp(optarg, "fr"))
1.1.1.3 root 752: currprefs.keyboard_lang = KBD_LANG_FR;
1.1 root 753: else if (0 == strcasecmp(optarg, "it"))
1.1.1.3 root 754: currprefs.keyboard_lang = KBD_LANG_IT;
1.1.1.2 root 755: else if (0 == strcasecmp(optarg, "es"))
1.1.1.3 root 756: currprefs.keyboard_lang = KBD_LANG_ES;
1.1 root 757: break;
758:
1.1.1.2 root 759: case 'O': parse_gfx_specs (optarg); break;
1.1 root 760: case 'd':
1.1.1.3 root 761: if (strchr (optarg, 'S') != NULL || strchr (optarg, 's')) {
762: write_log (" Serial on demand.\n");
763: currprefs.serial_demand = 1;
764: }
765: if (strchr (optarg, 'P') != NULL || strchr (optarg, 'p')) {
766: write_log (" Parallel on demand.\n");
767: currprefs.parallel_demand = 1;
1.1 root 768: }
1.1.1.3 root 769:
1.1 root 770: break;
771:
772: case 'H':
1.1.1.3 root 773: currprefs.color_mode = atoi (optarg);
774: if (currprefs.color_mode < 0) {
775: fprintf (stderr, "Bad color mode selected. Using default.\n");
776: currprefs.color_mode = 0;
1.1 root 777: }
778: break;
779: }
780: }
781: #endif
782:
1.1.1.4 ! root 783: static void parse_cmdline_and_init_file (int argc, char **argv)
1.1 root 784: {
785: FILE *f;
1.1.1.3 root 786: char *tmp;
787: int t;
1.1 root 788: char *buffer,*tmpbuf, *token;
1.1.1.4 ! root 789: int bufsiz;
1.1 root 790: int n_args;
791: char **new_argv;
792: int new_argc;
1.1.1.3 root 793: char *home;
1.1 root 794:
1.1.1.4 ! root 795: strcpy (optionsfile,"");
1.1 root 796:
1.1.1.3 root 797: #ifdef OPTIONS_IN_HOME
1.1.1.4 ! root 798: home = getenv ("HOME");
! 799: if (home != NULL && strlen (home) < 240)
1.1 root 800: {
1.1.1.4 ! root 801: strcpy (optionsfile, home);
! 802: strcat (optionsfile, "/");
1.1 root 803: }
804: #endif
805:
1.1.1.4 ! root 806: strcat (optionsfile, OPTIONSFILENAME);
1.1 root 807:
1.1.1.4 ! root 808: f = fopen (optionsfile, "rb");
1.1.1.3 root 809: #ifdef OPTIONS_IN_HOME
810: /* sam: if not found in $HOME then look in current directory */
1.1.1.2 root 811: if (f == NULL) {
1.1.1.3 root 812: strcpy (optionsfile, OPTIONSFILENAME);
1.1.1.4 ! root 813: f = fopen (optionsfile, "rb");
1.1.1.2 root 814: }
815: #endif
816:
1.1 root 817: if (f == NULL) {
1.1.1.4 ! root 818: parse_cmdline (argc, argv);
1.1 root 819: return;
820: }
1.1.1.4 ! root 821: fseek (f, 0, SEEK_END);
! 822: bufsiz = ftell (f);
! 823: fseek (f, 0, SEEK_SET);
1.1 root 824:
1.1.1.4 ! root 825: buffer = (char *)malloc (bufsiz+1);
1.1 root 826: buffer[bufsiz] = 0;
1.1.1.3 root 827: if (fread (buffer, 1, bufsiz, f) < bufsiz) {
828: fprintf (stderr, "Error reading configuration file\n");
829: fclose (f);
830: parse_cmdline (argc, argv);
1.1 root 831: return;
832: }
833: fclose(f);
834:
1.1.1.3 root 835: /* Canonicalize the buffer */
836: while ((tmp = strchr (buffer, '\r')))
837: *tmp = ' ';
838: for (;;) {
839: tmp = strchr (buffer, '\n');
840: if (tmp == 0)
841: break;
842: if (tmp[1] == '#') {
843: char *tmp2 = strchr (tmp + 1, '\n');
844: if (tmp2 == 0)
845: *tmp = '\0';
846: else
847: memmove (tmp, tmp2, strlen (tmp2) + 1);
848: } else {
1.1 root 849: *tmp = ' ';
1.1.1.3 root 850: }
851: }
1.1.1.4 ! root 852: while ((tmp = strchr (buffer, '\t')))
1.1.1.3 root 853: *tmp = ' ';
854:
855: tmp = buffer;
856: while (*tmp == ' ')
857: tmp++;
858: t = strlen (tmp);
859: memmove (buffer, tmp, t + 1);
860:
861: while (t > 0 && buffer[t-1] == ' ')
862: buffer[--t] = '\0';
863: for (;;) {
864: tmp = strstr (buffer, " ");
865: if (tmp == 0)
866: break;
867: memmove (tmp, tmp + 1, strlen (tmp));
1.1 root 868: }
869:
870: tmpbuf = my_strdup (buffer);
871:
872: n_args = 0;
873: if (strtok(tmpbuf, "\n ") != NULL) {
874: do {
875: n_args++;
876: } while (strtok(NULL, "\n ") != NULL);
877: }
878: free (tmpbuf);
879:
880: new_argv = (char **)malloc ((1 + n_args + argc) * sizeof (char **));
881: new_argv[0] = argv[0];
882: new_argc = 1;
883:
884: token = strtok(buffer, "\n ");
885: while (token != NULL) {
886: new_argv[new_argc] = my_strdup (token);
887: new_argc++;
1.1.1.4 ! root 888: token = strtok (NULL, "\n ");
1.1 root 889: }
890: for (n_args = 1; n_args < argc; n_args++)
891: new_argv[new_argc++] = argv[n_args];
892: new_argv[new_argc] = NULL;
893: parse_cmdline(new_argc, new_argv);
894: }
895:
1.1.1.4 ! root 896: void write_log_standard (const char *fmt, ...)
! 897: {
! 898: va_list ap;
! 899: va_start (ap, fmt);
! 900: #ifdef HAVE_VFPRINTF
! 901: vfprintf (stderr, fmt, ap);
! 902: #else
! 903: /* Technique stolen from GCC. */
! 904: {
! 905: int x1, x2, x3, x4, x5, x6, x7, x8;
! 906: x1 = va_arg (ap, int);
! 907: x2 = va_arg (ap, int);
! 908: x3 = va_arg (ap, int);
! 909: x4 = va_arg (ap, int);
! 910: x5 = va_arg (ap, int);
! 911: x6 = va_arg (ap, int);
! 912: x7 = va_arg (ap, int);
! 913: x8 = va_arg (ap, int);
! 914: fprintf (stderr, fmt, x1, x2, x3, x4, x5, x6, x7, x8);
! 915: }
! 916: #endif
! 917: }
! 918:
! 919: void reset_all_systems (void)
! 920: {
! 921: filesys_reset ();
! 922: filesys_start_threads ();
! 923: }
! 924:
1.1.1.2 root 925: /* Okay, this stuff looks strange, but it is here to encourage people who
926: * port UAE to re-use as much of this code as possible. Functions that you
927: * should be using are do_start_program() and do_leave_program(), as well
928: * as real_main(). Some OSes don't call main() (which is braindamaged IMHO,
929: * but unfortunately very common), so you need to call real_main() from
930: * whatever entry point you have. You may want to write your own versions
931: * of start_program() and leave_program() if you need to do anything special.
932: * Add #ifdefs around these as appropriate.
933: */
934:
1.1.1.4 ! root 935: void do_start_program (void)
1.1.1.2 root 936: {
1.1.1.3 root 937: /* Do a reset on startup. Whether this is elegant is debatable. */
938: quit_program = 2;
1.1.1.4 ! root 939: m68k_go (1);
1.1.1.2 root 940: }
941:
1.1.1.4 ! root 942: void do_leave_program (void)
1.1.1.2 root 943: {
1.1.1.4 ! root 944: graphics_leave ();
! 945: close_joystick ();
! 946: close_sound ();
! 947: dump_counts ();
! 948: serial_exit ();
! 949: zfile_exit ();
! 950: if (! no_gui)
! 951: gui_exit ();
1.1.1.2 root 952: }
953:
1.1.1.4 ! root 954: void start_program (void)
1.1.1.2 root 955: {
1.1.1.4 ! root 956: do_start_program ();
1.1.1.2 root 957: }
958:
1.1.1.4 ! root 959: void leave_program (void)
1.1.1.2 root 960: {
1.1.1.4 ! root 961: do_leave_program ();
1.1.1.2 root 962: }
963:
1.1.1.4 ! root 964: void real_main (int argc, char **argv)
1.1 root 965: {
966: FILE *hf;
967:
1.1.1.3 root 968: default_currprefs ();
969:
1.1.1.4 ! root 970: if (! graphics_setup ()) {
! 971: exit (1);
1.1 root 972: }
1.1.1.2 root 973:
1.1 root 974: rtarea_init ();
975: hardfile_install ();
976:
1.1.1.4 ! root 977: parse_cmdline_and_init_file (argc, argv);
1.1.1.2 root 978:
1.1.1.4 ! root 979: machdep_init ();
1.1.1.3 root 980:
1.1.1.4 ! root 981: if (! setup_sound ()) {
1.1.1.3 root 982: fprintf (stderr, "Sound driver unavailable: Sound output disabled\n");
983: currprefs.produce_sound = 0;
1.1 root 984: }
1.1.1.4 ! root 985: init_joystick ();
1.1 root 986:
1.1.1.4 ! root 987: if (! no_gui) {
! 988: int err = gui_init ();
1.1.1.2 root 989: if (err == -1) {
1.1.1.3 root 990: fprintf (stderr, "Failed to initialize the GUI\n");
1.1.1.2 root 991: } else if (err == -2) {
1.1.1.4 ! root 992: exit (0);
1.1.1.2 root 993: }
1.1 root 994: }
1.1.1.4 ! root 995: if (sound_available && ! init_sound ()) {
1.1.1.3 root 996: fprintf (stderr, "Sound driver unavailable: Sound output disabled\n");
997: currprefs.produce_sound = 0;
998: }
1.1.1.2 root 999:
1.1.1.4 ! root 1000: fix_options ();
1.1.1.3 root 1001: changed_prefs = currprefs;
1002:
1.1.1.2 root 1003: /* Install resident module to get 8MB chipmem, if requested */
1.1.1.4 ! root 1004: rtarea_setup ();
1.1.1.3 root 1005:
1.1.1.4 ! root 1006: keybuf_init (); /* Must come after init_joystick */
1.1.1.3 root 1007:
1.1 root 1008: expansion_init ();
1.1.1.4 ! root 1009: memory_init ();
! 1010:
! 1011: filesys_install ();
! 1012: gfxlib_install ();
! 1013: emulib_install ();
! 1014: uaeexe_install ();
! 1015:
! 1016: custom_init (); /* Must come after memory_init */
! 1017: serial_init ();
! 1018: DISK_init ();
! 1019:
! 1020: reset_frame_rate_hack ();
! 1021: init_m68k(); /* must come after reset_frame_rate_hack (); */
1.1 root 1022:
1.1.1.4 ! root 1023: compiler_init ();
! 1024: gui_update ();
1.1.1.2 root 1025:
1.1.1.3 root 1026: if (graphics_init ()) {
1027: setup_brkhandler ();
1028: if (use_debugger && debuggable ())
1029: activate_debugger ();
1030:
1031: start_program ();
1.1 root 1032: }
1.1.1.3 root 1033: leave_program ();
1.1.1.2 root 1034: }
1035:
1.1.1.3 root 1036: #ifndef NO_MAIN_IN_MAIN_C
1.1.1.4 ! root 1037: int main (int argc, char **argv)
1.1.1.2 root 1038: {
1.1.1.4 ! root 1039: real_main (argc, argv);
1.1 root 1040: return 0;
1041: }
1.1.1.3 root 1042: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.