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