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