|
|
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"
1.1.1.6 ! root 38: #include "bsdsocket.h"
1.1.1.3 root 39: #include "uaeexe.h"
1.1.1.4 root 40: #include "getopt.h"
1.1 root 41:
1.1.1.4 root 42: long int version = 256*65536L*UAEMAJOR + 65536L*UAEMINOR + UAESUBREV;
1.1.1.3 root 43:
1.1.1.6 ! root 44: struct uae_prefs currprefs, changed_prefs;
1.1.1.4 root 45:
1.1.1.6 ! root 46: int no_gui = 0;
1.1.1.4 root 47: int joystickpresent = 0;
48: int cloanto_rom = 0;
49:
50: char warning_buffer[256];
51:
52: char optionsfile[256];
53:
54: /* If you want to pipe printer output to a file, put something like
55: * "cat >>printerfile.tmp" above.
56: * The printer support was only tested with the driver "PostScript" on
57: * Amiga side, using apsfilter for linux to print ps-data.
58: *
59: * Under DOS it ought to be -p LPT1: or -p PRN: but you'll need a
60: * PostScript printer or ghostscript -=SR=-
61: */
62:
63: /* People must provide their own name for this */
64: char sername[256] = "";
65:
66: /* Slightly stupid place for this... */
67: /* ncurses.c might use quite a few of those. */
68: char *colormodes[] = { "256 colors", "32768 colors", "65536 colors",
69: "256 colors dithered", "16 colors dithered", "16 million colors",
70: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
71: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
72: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
73: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
74: "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
75: };
76:
1.1.1.6 ! root 77: void discard_prefs (struct uae_prefs *p)
1.1.1.3 root 78: {
1.1.1.6 ! root 79: struct strlist **ps = &p->unknown_lines;
! 80: while (*ps) {
! 81: struct strlist *s = *ps;
! 82: *ps = s->next;
! 83: free (s->str);
! 84: free (s);
! 85: }
! 86: free_mountinfo (p->mountinfo);
! 87: }
! 88:
! 89: void default_prefs (struct uae_prefs *p)
! 90: {
! 91: strcpy (p->description, "UAE default configuration");
! 92:
! 93: p->start_gui = 1;
! 94: p->start_debugger = 0;
! 95:
! 96: p->unknown_lines = 0;
1.1.1.4 root 97: /* Note to porters: please don't change any of these options! UAE is supposed
98: * to behave identically on all platforms if possible. */
1.1.1.6 ! root 99: p->framerate = 1;
! 100: p->illegal_mem = 0;
! 101: p->no_xhair = 0;
! 102: p->use_serial = 0;
! 103: p->serial_demand = 0;
! 104: p->parallel_demand = 0;
! 105: p->automount_uaedev = 1;
! 106:
! 107: p->jport0 = 2;
! 108: p->jport1 = 0;
! 109: p->keyboard_lang = KBD_LANG_US;
! 110: p->emul_accuracy = 2;
! 111: p->test_drawing_speed = 0;
! 112:
! 113: p->produce_sound = 0;
! 114: p->stereo = 0;
! 115: p->sound_bits = DEFAULT_SOUND_BITS;
! 116: p->sound_freq = DEFAULT_SOUND_FREQ;
! 117: p->sound_minbsiz = DEFAULT_SOUND_MINB;
! 118: p->sound_maxbsiz = DEFAULT_SOUND_MAXB;
! 119:
! 120: p->gfx_width = 800;
! 121: p->gfx_height = 600;
! 122: p->gfx_lores = 0;
! 123: p->gfx_linedbl = 0;
! 124: p->gfx_afullscreen = 0;
! 125: p->gfx_pfullscreen = 0;
! 126: p->gfx_correct_aspect = 0;
! 127: p->gfx_xcenter = 0;
! 128: p->gfx_ycenter = 0;
! 129: p->color_mode = 0;
! 130:
! 131: p->x11_use_low_bandwidth = 0;
! 132: p->x11_use_mitshm = 0;
! 133: p->x11_hide_cursor = 1;
! 134:
! 135: p->immediate_blits = 0;
! 136: p->blits_32bit_enabled = 0;
! 137:
! 138: strcpy (p->df[0], "df0.adf");
! 139: strcpy (p->df[1], "df1.adf");
! 140: strcpy (p->df[2], "df2.adf");
! 141: strcpy (p->df[3], "df3.adf");
! 142:
! 143: strcpy (p->romfile, "kick.rom");
! 144: strcpy (p->keyfile, "");
! 145: strcpy (p->prtname, DEFPRTNAME);
! 146:
! 147: strcpy (p->path_rom, "./");
! 148: strcpy (p->path_floppy, "./");
! 149: strcpy (p->path_hardfile, "./");
! 150:
! 151: p->m68k_speed = 4;
! 152: p->cpu_level = 2;
! 153: p->cpu_compatible = 0;
! 154: p->address_space_24 = 0;
! 155:
! 156: p->fastmem_size = 0x00000000;
! 157: p->a3000mem_size = 0x00000000;
! 158: p->z3fastmem_size = 0x00000000;
! 159: p->chipmem_size = 0x00200000;
! 160: p->bogomem_size = 0x00000000;
! 161: p->gfxmem_size = 0x00000000;
1.1 root 162:
1.1.1.6 ! root 163: p->mountinfo = alloc_mountinfo ();
1.1.1.4 root 164: }
1.1 root 165:
1.1.1.4 root 166: void fixup_prefs_dimensions (struct uae_prefs *prefs)
167: {
168: if (prefs->gfx_width < 320)
169: prefs->gfx_width = 320;
170: if (prefs->gfx_height < 200)
171: prefs->gfx_height = 200;
172: if (prefs->gfx_height > 300 && ! prefs->gfx_linedbl)
173: prefs->gfx_height = 300;
174: if (prefs->gfx_height > 600)
175: prefs->gfx_height = 600;
1.1 root 176:
1.1.1.4 root 177: prefs->gfx_width += 7; /* X86.S wants multiples of 4 bytes, might be 8 in the future. */
178: prefs->gfx_width &= ~7;
179: }
1.1.1.3 root 180:
1.1.1.4 root 181: static void fix_options (void)
1.1.1.2 root 182: {
1.1.1.3 root 183: int err = 0;
184:
1.1.1.4 root 185: if ((currprefs.chipmem_size & (currprefs.chipmem_size - 1)) != 0
186: || currprefs.chipmem_size < 0x80000
187: || currprefs.chipmem_size > 0x800000)
1.1.1.3 root 188: {
1.1.1.4 root 189: currprefs.chipmem_size = 0x200000;
1.1.1.3 root 190: fprintf (stderr, "Unsupported chipmem size!\n");
191: err = 1;
192: }
1.1.1.4 root 193: if ((currprefs.fastmem_size & (currprefs.fastmem_size - 1)) != 0
194: || (currprefs.fastmem_size != 0 && (currprefs.fastmem_size < 0x100000 || currprefs.fastmem_size > 0x800000)))
1.1.1.3 root 195: {
1.1.1.4 root 196: currprefs.fastmem_size = 0;
1.1.1.3 root 197: fprintf (stderr, "Unsupported fastmem size!\n");
198: err = 1;
199: }
1.1.1.4 root 200: if ((currprefs.gfxmem_size & (currprefs.gfxmem_size - 1)) != 0
201: || (currprefs.gfxmem_size != 0 && (currprefs.gfxmem_size < 0x100000 || currprefs.gfxmem_size > 0x800000)))
1.1.1.3 root 202: {
1.1.1.4 root 203: currprefs.gfxmem_size = 0;
1.1.1.3 root 204: fprintf (stderr, "Unsupported graphics card memory size!\n");
205: err = 1;
206: }
1.1.1.4 root 207: if ((currprefs.z3fastmem_size & (currprefs.z3fastmem_size - 1)) != 0
208: || (currprefs.z3fastmem_size != 0 && (currprefs.z3fastmem_size < 0x100000 || currprefs.z3fastmem_size > 0x4000000)))
1.1.1.3 root 209: {
1.1.1.4 root 210: currprefs.z3fastmem_size = 0;
1.1.1.3 root 211: fprintf (stderr, "Unsupported Zorro III fastmem size!\n");
212: err = 1;
213: }
1.1.1.4 root 214: if (currprefs.address_space_24 && (currprefs.gfxmem_size != 0 || currprefs.z3fastmem_size != 0)) {
215: currprefs.z3fastmem_size = currprefs.gfxmem_size = 0;
1.1.1.3 root 216: fprintf (stderr, "Can't use a graphics card or Zorro III fastmem when using a 24 bit\n"
217: "address space - sorry.\n");
218: }
1.1.1.4 root 219: if ((currprefs.bogomem_size & (currprefs.bogomem_size - 1)) != 0
220: || (currprefs.bogomem_size != 0 && (currprefs.bogomem_size < 0x80000 || currprefs.bogomem_size > 0x100000)))
1.1.1.3 root 221: {
1.1.1.4 root 222: currprefs.bogomem_size = 0;
1.1.1.3 root 223: fprintf (stderr, "Unsupported bogomem size!\n");
224: err = 1;
225: }
226:
1.1.1.4 root 227: if (currprefs.chipmem_size > 0x200000 && currprefs.fastmem_size != 0) {
1.1.1.3 root 228: fprintf (stderr, "You can't use fastmem and more than 2MB chip at the same time!\n");
1.1.1.4 root 229: currprefs.fastmem_size = 0;
1.1.1.3 root 230: err = 1;
231: }
1.1.1.4 root 232: if (currprefs.m68k_speed < -1 || currprefs.m68k_speed > 20) {
233: fprintf (stderr, "Bad value for -w parameter: must be -1, 0, or within 1..20.\n");
1.1.1.3 root 234: currprefs.m68k_speed = 4;
235: err = 1;
236: }
237: if (currprefs.produce_sound < 0 || currprefs.produce_sound > 3) {
238: fprintf (stderr, "Bad value for -S parameter: enable value must be within 0..3\n");
239: currprefs.produce_sound = 0;
240: err = 1;
241: }
1.1.1.4 root 242: if (currprefs.cpu_level < 2 && currprefs.z3fastmem_size > 0) {
1.1.1.3 root 243: fprintf (stderr, "Z3 fast memory can't be used with a 68000/68010 emulation. It\n"
244: "requires a 68020 emulation. Turning off Z3 fast memory.\n");
1.1.1.4 root 245: currprefs.z3fastmem_size = 0;
1.1.1.3 root 246: err = 1;
247: }
1.1.1.4 root 248: if (currprefs.cpu_level < 2 && currprefs.gfxmem_size > 0) {
1.1.1.3 root 249: fprintf (stderr, "Picasso96 can't be used with a 68000/68010 emulation. It\n"
250: "requires a 68020 emulation. Turning off Picasso96.\n");
1.1.1.4 root 251: currprefs.gfxmem_size = 0;
1.1.1.3 root 252: err = 1;
253: }
254:
255: if (err)
256: fprintf (stderr, "Please use \"uae -h\" to get usage information.\n");
257: }
258:
259: int quit_program = 0;
260:
261: void uae_reset (void)
262: {
1.1.1.4 root 263: if (quit_program == 0)
1.1.1.3 root 264: quit_program = -2;
265: }
266:
267: void uae_quit (void)
268: {
269: if (quit_program != -1)
270: quit_program = -1;
1.1.1.2 root 271: }
1.1 root 272:
1.1.1.3 root 273: const char *gameport_state (int nr)
1.1 root 274: {
1.1.1.6 ! root 275: if (JSEM_ISJOY0 (nr, &currprefs) && nr_joysticks > 0)
1.1.1.3 root 276: return "using joystick #0";
1.1.1.6 ! root 277: else if (JSEM_ISJOY1 (nr, &currprefs) && nr_joysticks > 1)
1.1.1.3 root 278: return "using joystick #1";
1.1.1.6 ! root 279: else if (JSEM_ISMOUSE (nr, &currprefs))
1.1.1.3 root 280: return "using mouse";
1.1.1.6 ! root 281: else if (JSEM_ISNUMPAD (nr, &currprefs))
1.1.1.3 root 282: return "using numeric pad as joystick";
1.1.1.6 ! root 283: else if (JSEM_ISCURSOR (nr, &currprefs))
1.1.1.3 root 284: return "using cursor keys as joystick";
1.1.1.6 ! root 285: else if (JSEM_ISSOMEWHEREELSE (nr, &currprefs))
1.1.1.3 root 286: return "using T/F/H/B/Alt as joystick";
287:
288: return "not connected";
289: }
290:
1.1.1.6 ! root 291: #ifndef DONT_PARSE_CMDLINE
1.1.1.3 root 292:
1.1.1.6 ! root 293: void usage (void)
! 294: {
1.1.1.3 root 295: }
296:
1.1.1.6 ! root 297: void parse_cmdline (int argc, char **argv)
! 298: {
! 299: char *param_string;
! 300: int longind = 0, last_longind = -1, result, i = 0;
! 301: struct option longopts[] =
! 302: {
! 303: { "help", 0, 0, 'h' },
! 304: { "file", 0, 0, 'f' },
! 305: { 0, 0, 0, 0 }
! 306: };
! 307:
! 308: while ((result = getopt_long (argc, argv, "s:f:h", longopts, &longind)) != EOF) {
! 309: switch (result) {
! 310: case 's':
! 311: cfgfile_parse_line (&currprefs, optarg, 0);
1.1.1.3 root 312: break;
1.1.1.6 ! root 313: case 'f':
! 314: cfgfile_load (&currprefs, optarg);
1.1.1.3 root 315: break;
1.1.1.6 ! root 316:
! 317: case 'h':
1.1.1.3 root 318: default:
1.1.1.6 ! root 319: usage ();
! 320: exit (0);
1.1.1.3 root 321: break;
322: }
1.1 root 323: }
324: }
325: #endif
326:
1.1.1.4 root 327: static void parse_cmdline_and_init_file (int argc, char **argv)
1.1 root 328: {
1.1.1.3 root 329: char *home;
1.1 root 330:
1.1.1.6 ! root 331: strcpy (optionsfile, "");
1.1 root 332:
1.1.1.3 root 333: #ifdef OPTIONS_IN_HOME
1.1.1.4 root 334: home = getenv ("HOME");
335: if (home != NULL && strlen (home) < 240)
1.1 root 336: {
1.1.1.4 root 337: strcpy (optionsfile, home);
338: strcat (optionsfile, "/");
1.1 root 339: }
340: #endif
341:
1.1.1.4 root 342: strcat (optionsfile, OPTIONSFILENAME);
1.1 root 343:
1.1.1.6 ! root 344: if (! cfgfile_load (&currprefs, optionsfile)) {
1.1.1.3 root 345: #ifdef OPTIONS_IN_HOME
1.1.1.6 ! root 346: /* sam: if not found in $HOME then look in current directory */
1.1.1.3 root 347: strcpy (optionsfile, OPTIONSFILENAME);
1.1.1.6 ! root 348: cfgfile_load (&currprefs, optionsfile);
1.1.1.2 root 349: }
350: #endif
351:
1.1.1.6 ! root 352: parse_cmdline (argc, argv);
1.1 root 353: }
354:
1.1.1.4 root 355: void write_log_standard (const char *fmt, ...)
356: {
357: va_list ap;
358: va_start (ap, fmt);
359: #ifdef HAVE_VFPRINTF
360: vfprintf (stderr, fmt, ap);
361: #else
362: /* Technique stolen from GCC. */
363: {
364: int x1, x2, x3, x4, x5, x6, x7, x8;
365: x1 = va_arg (ap, int);
366: x2 = va_arg (ap, int);
367: x3 = va_arg (ap, int);
368: x4 = va_arg (ap, int);
369: x5 = va_arg (ap, int);
370: x6 = va_arg (ap, int);
371: x7 = va_arg (ap, int);
372: x8 = va_arg (ap, int);
373: fprintf (stderr, fmt, x1, x2, x3, x4, x5, x6, x7, x8);
374: }
375: #endif
376: }
377:
378: void reset_all_systems (void)
379: {
1.1.1.6 ! root 380: bsdlib_reset ();
1.1.1.4 root 381: filesys_reset ();
382: filesys_start_threads ();
383: }
384:
1.1.1.2 root 385: /* Okay, this stuff looks strange, but it is here to encourage people who
386: * port UAE to re-use as much of this code as possible. Functions that you
387: * should be using are do_start_program() and do_leave_program(), as well
388: * as real_main(). Some OSes don't call main() (which is braindamaged IMHO,
389: * but unfortunately very common), so you need to call real_main() from
390: * whatever entry point you have. You may want to write your own versions
391: * of start_program() and leave_program() if you need to do anything special.
392: * Add #ifdefs around these as appropriate.
393: */
394:
1.1.1.4 root 395: void do_start_program (void)
1.1.1.2 root 396: {
1.1.1.3 root 397: /* Do a reset on startup. Whether this is elegant is debatable. */
398: quit_program = 2;
1.1.1.4 root 399: m68k_go (1);
1.1.1.2 root 400: }
401:
1.1.1.4 root 402: void do_leave_program (void)
1.1.1.2 root 403: {
1.1.1.4 root 404: graphics_leave ();
405: close_joystick ();
406: close_sound ();
407: dump_counts ();
408: serial_exit ();
409: zfile_exit ();
410: if (! no_gui)
411: gui_exit ();
1.1.1.2 root 412: }
413:
1.1.1.4 root 414: void start_program (void)
1.1.1.2 root 415: {
1.1.1.4 root 416: do_start_program ();
1.1.1.2 root 417: }
418:
1.1.1.4 root 419: void leave_program (void)
1.1.1.2 root 420: {
1.1.1.4 root 421: do_leave_program ();
1.1.1.2 root 422: }
423:
1.1.1.4 root 424: void real_main (int argc, char **argv)
1.1 root 425: {
426: FILE *hf;
427:
1.1.1.6 ! root 428: default_prefs (&currprefs);
1.1.1.3 root 429:
1.1.1.4 root 430: if (! graphics_setup ()) {
431: exit (1);
1.1 root 432: }
1.1.1.2 root 433:
1.1 root 434: rtarea_init ();
435: hardfile_install ();
436:
1.1.1.4 root 437: parse_cmdline_and_init_file (argc, argv);
1.1.1.2 root 438:
1.1.1.4 root 439: machdep_init ();
1.1.1.3 root 440:
1.1.1.4 root 441: if (! setup_sound ()) {
1.1.1.3 root 442: fprintf (stderr, "Sound driver unavailable: Sound output disabled\n");
443: currprefs.produce_sound = 0;
1.1 root 444: }
1.1.1.4 root 445: init_joystick ();
1.1 root 446:
1.1.1.6 ! root 447: no_gui = ! currprefs.start_gui;
1.1.1.4 root 448: if (! no_gui) {
449: int err = gui_init ();
1.1.1.2 root 450: if (err == -1) {
1.1.1.3 root 451: fprintf (stderr, "Failed to initialize the GUI\n");
1.1.1.2 root 452: } else if (err == -2) {
1.1.1.4 root 453: exit (0);
1.1.1.2 root 454: }
1.1 root 455: }
1.1.1.5 root 456: if (sound_available && currprefs.produce_sound > 1 && ! init_sound ()) {
1.1.1.3 root 457: fprintf (stderr, "Sound driver unavailable: Sound output disabled\n");
458: currprefs.produce_sound = 0;
459: }
1.1.1.2 root 460:
1.1.1.4 root 461: fix_options ();
1.1.1.3 root 462: changed_prefs = currprefs;
463:
1.1.1.2 root 464: /* Install resident module to get 8MB chipmem, if requested */
1.1.1.4 root 465: rtarea_setup ();
1.1.1.3 root 466:
1.1.1.4 root 467: keybuf_init (); /* Must come after init_joystick */
1.1.1.3 root 468:
1.1 root 469: expansion_init ();
1.1.1.4 root 470: memory_init ();
471:
472: filesys_install ();
473: gfxlib_install ();
474: emulib_install ();
475: uaeexe_install ();
476:
477: custom_init (); /* Must come after memory_init */
478: serial_init ();
479: DISK_init ();
480:
481: reset_frame_rate_hack ();
482: init_m68k(); /* must come after reset_frame_rate_hack (); */
1.1 root 483:
1.1.1.4 root 484: compiler_init ();
485: gui_update ();
1.1.1.2 root 486:
1.1.1.3 root 487: if (graphics_init ()) {
488: setup_brkhandler ();
1.1.1.6 ! root 489: if (currprefs.start_debugger && debuggable ())
1.1.1.3 root 490: activate_debugger ();
491:
492: start_program ();
1.1 root 493: }
1.1.1.3 root 494: leave_program ();
1.1.1.2 root 495: }
496:
1.1.1.3 root 497: #ifndef NO_MAIN_IN_MAIN_C
1.1.1.4 root 498: int main (int argc, char **argv)
1.1.1.2 root 499: {
1.1.1.4 root 500: real_main (argc, argv);
1.1 root 501: return 0;
502: }
1.1.1.3 root 503: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.