--- uae/src/main.c 2018/04/24 16:39:02 1.1.1.2
+++ uae/src/main.c 2018/04/24 16:39:57 1.1.1.3
@@ -1,9 +1,10 @@
/*
* UAE - The Un*x Amiga Emulator
- *
- * Main program
- *
- * (c) 1995 Bernd Schmidt, Ed Hanway
+ *
+ * Main program
+ *
+ * Copyright 1995 Ed Hanway
+ * Copyright 1995, 1996, 1997 Bernd Schmidt
*/
#include "sysconfig.h"
@@ -12,7 +13,10 @@
#include "config.h"
#include "options.h"
+#include "threaddep/penguin.h"
#include "uae.h"
+#include "gensound.h"
+#include "sounddep/sound.h"
#include "events.h"
#include "memory.h"
#include "custom.h"
@@ -22,125 +26,414 @@
#include "disk.h"
#include "debug.h"
#include "xwin.h"
-#include "os.h"
+#include "joystick.h"
#include "keybuf.h"
#include "gui.h"
#include "zfile.h"
#include "autoconf.h"
#include "osemu.h"
+#include "osdep/exectasks.h"
#include "compiler.h"
+#include "picasso96.h"
+#include "uaeexe.h"
int version = 100*UAEMAJOR + 10*UAEMINOR + UAEURSAMINOR;
-int framerate = 1;
-int use_debugger = 0;
-int illegal_mem = 0;
-int use_gfxlib = 0;
-int no_xhair = 0;
-int use_serial = 0;
-int automount_uaedev = 1;
-int produce_sound = 0;
-int fake_joystick = 0;
-KbdLang keyboard_lang = KBD_LANG_US;
-int correct_aspect = 0;
-int color_mode = 0;
-int sound_desired_bits = 16;
-#ifdef AMIGA
-int sound_desired_freq = 11025;
-#else
-int sound_desired_freq = 44100;
-#endif
-int sound_desired_bsiz = 8192;
-int allow_save = 0;
-int no_gui = 0;
-int emul_accuracy = 2;
-int test_drawing_speed = 0;
-int gfx_requested_width = 800, gfx_requested_height = 600, gfx_requested_lores = 0;
-int gfx_requested_linedbl = 0, gfx_requested_correct_aspect = 0;
-int gfx_requested_xcenter = 0, gfx_requested_ycenter = 0;
-int immediate_blits = 0, blits_32bit_enabled = 0;
-long hardfile_size = 0;
-
-ULONG fastmem_size = 0x000000;
-ULONG chipmem_size = 0x200000;
-ULONG bogomem_size = 0x000000;
-char df0[256]="df0.adf", df1[256]="df1.adf", df2[256]="df2.adf", df3[256]="df3.adf";
+
+/* Note to porters: please don't change any of these options! UAE is supposed
+ * to behave identically on all platforms if possible. */
+struct uae_prefs currprefs;
+
+static void default_currprefs (void)
+{
+ currprefs.framerate = 1;
+ currprefs.illegal_mem = 0;
+ currprefs.no_xhair = 0;
+ currprefs.use_serial = 0;
+ currprefs.serial_demand = 0;
+ currprefs.parallel_demand = 0;
+ currprefs.automount_uaedev = 1;
+
+ currprefs.fake_joystick = 2 + (0<<8);
+ currprefs.keyboard_lang = KBD_LANG_US;
+ currprefs.emul_accuracy = 2;
+ currprefs.test_drawing_speed = 0;
+
+ currprefs.produce_sound = 0;
+ currprefs.stereo = 0;
+ currprefs.sound_bits = DEFAULT_SOUND_BITS;
+ currprefs.sound_freq = DEFAULT_SOUND_FREQ;
+ currprefs.sound_minbsiz = DEFAULT_SOUND_MINB;
+ currprefs.sound_maxbsiz = DEFAULT_SOUND_MAXB;
+
+ currprefs.gfx_width = 800;
+ currprefs.gfx_height = 600;
+ currprefs.gfx_lores = 0;
+ currprefs.gfx_linedbl = 0;
+ currprefs.gfx_correct_aspect = 0;
+ currprefs.gfx_xcenter = 0;
+ currprefs.gfx_ycenter = 0;
+ currprefs.color_mode = 0;
+
+ currprefs.use_low_bandwidth = 0;
+ currprefs.use_mitshm = 0;
+
+ currprefs.immediate_blits = 0;
+ currprefs.blits_32bit_enabled = 0;
+
+ strcpy (currprefs.df[0], "df0.adf");
+ strcpy (currprefs.df[1], "df1.adf");
+ strcpy (currprefs.df[2], "df2.adf");
+ strcpy (currprefs.df[3], "df3.adf");
+
+ currprefs.m68k_speed = 4;
+ currprefs.cpu_level = 0;
+ currprefs.cpu_compatible = 0;
+ currprefs.address_space_24 = 1;
+};
+struct uae_prefs changed_prefs;
+
+int no_gui = 0, use_debugger = 0, use_gfxlib = 0;
+
+int joystickpresent = 0;
+
+int cloanto_rom = 0;
+
+char warning_buffer[256];
+
+uae_u32 fastmem_size = 0x00000000;
+uae_u32 a3000mem_size = 0x00000000;
+uae_u32 z3fastmem_size = 0x00000000;
+uae_u32 chipmem_size = 0x00200000;
+uae_u32 bogomem_size = 0x00000000;
+uae_u32 gfxmem_size = 0x00000000;
+
char romfile[256] = "kick.rom";
-#ifndef __DOS__
-char prtname[256] = "lpr ";
-#else
-char prtname[256] = "PRN";
-#endif
+char keyfile[256] = "";
+char prtname[256] = DEFPRTNAME;
char optionsfile[256];
-/* If you want to pipe Printer output to a file, put something like
+/* If you want to pipe printer output to a file, put something like
* "cat >>printerfile.tmp" above.
* The printer support was only tested with the driver "PostScript" on
* Amiga side, using apsfilter for linux to print ps-data.
*
- * Under DOS it ought to be -p LPT1: or -p PRN: but you'll need a
+ * Under DOS it ought to be -p LPT1: or -p PRN: but you'll need a
* PostScript printer or ghostscript -=SR=-
*/
/* People must provide their own name for this */
char sername[256] = "";
+/* Slightly stupid place for this... */
+/* ncurses.c might use quite a few of those. */
+char *colormodes[] = { "256 colors", "32768 colors", "65536 colors",
+ "256 colors dithered", "16 colors dithered", "16 million colors",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
+};
+
static void fix_options(void)
{
+ int err = 0;
+
+ if ((chipmem_size & (chipmem_size - 1)) != 0
+ || chipmem_size < 0x80000
+ || chipmem_size > 0x800000)
+ {
+ chipmem_size = 0x200000;
+ fprintf (stderr, "Unsupported chipmem size!\n");
+ err = 1;
+ }
+ if ((fastmem_size & (fastmem_size - 1)) != 0
+ || (fastmem_size != 0 && (fastmem_size < 0x100000 || fastmem_size > 0x800000)))
+ {
+ fastmem_size = 0;
+ fprintf (stderr, "Unsupported fastmem size!\n");
+ err = 1;
+ }
+ if ((gfxmem_size & (gfxmem_size - 1)) != 0
+ || (gfxmem_size != 0 && (gfxmem_size < 0x100000 || gfxmem_size > 0x800000)))
+ {
+ gfxmem_size = 0;
+ fprintf (stderr, "Unsupported graphics card memory size!\n");
+ err = 1;
+ }
+ if ((z3fastmem_size & (z3fastmem_size - 1)) != 0
+ || (z3fastmem_size != 0 && (z3fastmem_size < 0x100000 || z3fastmem_size > 0x4000000)))
+ {
+ z3fastmem_size = 0;
+ fprintf (stderr, "Unsupported Zorro III fastmem size!\n");
+ err = 1;
+ }
+ if (currprefs.address_space_24 && (gfxmem_size != 0 || z3fastmem_size != 0)) {
+ z3fastmem_size = gfxmem_size = 0;
+ fprintf (stderr, "Can't use a graphics card or Zorro III fastmem when using a 24 bit\n"
+ "address space - sorry.\n");
+ }
+ if ((bogomem_size & (bogomem_size - 1)) != 0
+ || (bogomem_size != 0 && (bogomem_size < 0x80000 || bogomem_size > 0x100000)))
+ {
+ bogomem_size = 0;
+ fprintf (stderr, "Unsupported bogomem size!\n");
+ err = 1;
+ }
+
+ if (chipmem_size > 0x200000 && fastmem_size != 0) {
+ fprintf (stderr, "You can't use fastmem and more than 2MB chip at the same time!\n");
+ fastmem_size = 0;
+ err = 1;
+ }
+ if (currprefs.m68k_speed < 1 || currprefs.m68k_speed > 20) {
+ fprintf (stderr, "Bad value for -w parameter: must be within 1..20.\n");
+ currprefs.m68k_speed = 4;
+ err = 1;
+ }
+ if (currprefs.produce_sound < 0 || currprefs.produce_sound > 3) {
+ fprintf (stderr, "Bad value for -S parameter: enable value must be within 0..3\n");
+ currprefs.produce_sound = 0;
+ err = 1;
+ }
+ if (currprefs.cpu_level < 2 && z3fastmem_size > 0) {
+ fprintf (stderr, "Z3 fast memory can't be used with a 68000/68010 emulation. It\n"
+ "requires a 68020 emulation. Turning off Z3 fast memory.\n");
+ z3fastmem_size = 0;
+ err = 1;
+ }
+ if (currprefs.cpu_level < 2 && gfxmem_size > 0) {
+ fprintf (stderr, "Picasso96 can't be used with a 68000/68010 emulation. It\n"
+ "requires a 68020 emulation. Turning off Picasso96.\n");
+ gfxmem_size = 0;
+ err = 1;
+ }
+
+ if (err)
+ fprintf (stderr, "Please use \"uae -h\" to get usage information.\n");
+}
+
+int quit_program = 0;
+
+void uae_reset (void)
+{
+ if (quit_program != 1 && quit_program != -1)
+ quit_program = -2;
+}
+
+void uae_quit (void)
+{
+ if (quit_program != -1)
+ quit_program = -1;
}
+/*
+ * This function is dangerous, at least if you use different versions of UAE
+ * from time to time (as I do). For example, running the SVGAlib version with
+ * "-o" will discard the keyboard language information...
+ */
+void save_options(FILE *f)
+{
+ int i;
+ if (use_debugger)
+ fprintf (f, "-D\n");
+ fprintf (f, "-r %s\n", romfile);
+ if (strlen (keyfile) > 0)
+ fprintf (f, "-K %s\n", keyfile);
+ for (i = 0; i < 4; i++)
+ if (strlen (currprefs.df[i]) > 0)
+ fprintf (f, "-%d %s\n", i, currprefs.df[i]);
+
+#ifndef UNSUPPORTED_OPTION_p
+ fprintf (f, "-p %s\n", prtname);
+#endif
+#ifndef UNSUPPORTED_OPTION_S
+ fprintf (f, "-S %d:%c:%d:%d:%d:%d\n", currprefs.produce_sound,
+ currprefs.stereo ? 's' : 'm',
+ currprefs.sound_bits,
+ currprefs.sound_freq,
+ currprefs.sound_maxbsiz,
+ currprefs.sound_minbsiz);
+#endif
+ if (currprefs.fake_joystick)
+ fprintf (f, "-J %c%c\n", "01MABC"[currprefs.fake_joystick & 255],
+ "01MABC"[(currprefs.fake_joystick >> 8) & 255]);
+ fprintf (f, "-f %d\n", currprefs.framerate);
+ fprintf (f, "-O %d:%d:", currprefs.gfx_width, currprefs.gfx_height);
+ if (currprefs.gfx_lores)
+ fprintf (f, "l");
+ switch (currprefs.gfx_xcenter) {
+ case 1: fprintf (f, "x"); break;
+ case 2: fprintf (f, "X"); break;
+ default: break;
+ }
+ switch (currprefs.gfx_ycenter) {
+ case 1: fprintf (f, "y"); break;
+ case 2: fprintf (f, "Y"); break;
+ default: break;
+ }
+ if (currprefs.gfx_linedbl)
+ fprintf (f, "d");
+ if (currprefs.gfx_correct_aspect)
+ fprintf (f, "c");
+ fprintf (f, "\n-H %d\n", currprefs.color_mode);
+ if (fastmem_size > 0)
+ fprintf (f, "-F %d\n", fastmem_size / 0x100000);
+ if (z3fastmem_size > 0)
+ fprintf (f, "-Z %d\n", z3fastmem_size / 0x100000);
+ if (bogomem_size > 0)
+ fprintf (f, "-s %d\n", bogomem_size / 0x40000);
+ if (gfxmem_size > 0)
+ fprintf (f, "-U %d\n", gfxmem_size / 0x100000);
+ fprintf (f, "-c %d\n", chipmem_size / 0x80000);
+
+ fprintf (f, "-C %d%s\n", currprefs.cpu_level,
+ (currprefs.cpu_compatible ? "c"
+ : currprefs.address_space_24 && currprefs.cpu_level > 1 ? "a"
+ : ""));
+
+ if (!currprefs.automount_uaedev)
+ fprintf (f, "-a\n");
+ if (currprefs.use_low_bandwidth)
+ fprintf (f, "-L\n");
+ if (currprefs.use_mitshm)
+ fprintf (f, "-T\n");
+ fprintf (f, "-w %d\n", currprefs.m68k_speed);
+ fprintf (f, "-A %d\n", currprefs.emul_accuracy);
+ /* We don't write "-t" - I can hardly imagine a user who wants that in his
+ * config file. */
+ write_filesys_config(f);
+#ifndef UNSUPPORTED_OPTION_l
+ fprintf (f, "-l %s\n", (currprefs.keyboard_lang == KBD_LANG_DE ? "de"
+ : currprefs.keyboard_lang == KBD_LANG_ES ? "es"
+ : currprefs.keyboard_lang == KBD_LANG_US ? "us"
+ : currprefs.keyboard_lang == KBD_LANG_SE ? "se"
+ : currprefs.keyboard_lang == KBD_LANG_FR ? "fr"
+ : currprefs.keyboard_lang == KBD_LANG_IT ? "it"
+ : "FOO"));
+#endif
+}
+
+struct optiondef {
+ const char *getopt_str;
+ const char *helpstr;
+};
+
+
+static struct optiondef uaeopts[] = {
+ { "h", " -h : Print help\n" },
+#ifndef UNSUPPORTED_OPTION_l
+ { "l:", " -l lang : Set keyboard language to lang, where lang is\n"
+ " DE, SE, US, ES, FR or IT\n" },
+#endif
+ { "m:", " -m VOL:dir : Mount directory called
as AmigaDOS volume VOL:\n" },
+ { "M:", " -M VOL:dir : like -m, but mount read-only\n" },
+ { "W:", " -W specs : Mount a hardfile. The \"specs\" parameter consists of\n"
+ " \"sectors per track:number of surfaces:filename\"\n" },
+ { "s:", " -s n : Emulate n*256 KB slow memory at 0xC00000\n" },
+ { "c:", " -c n : Emulate n*512 KB chip memory at 0x000000\n" },
+ { "F:", " -F n : Emulate n MB fast memory at 0x200000\n" },
+ { "Z:", " -Z n : Emulate n MB Zorro III fast memory\n" },
+#if defined PICASSO96
+ { "U:", " -U n : Emulate a Picasso96 compatible graphics card with n MB memory\n" },
+#endif
+ { "w:", " -w n : Set CPU speed to n (default 4)\n" },
+ { "a", " -a : Add no expansion devices (disables fastmem and\n"
+ " harddisk support\n" },
+ { "J:", " -J xy : Specify how to emulate joystick port 0 (x) and 1 (y)\n"
+ " Use 0 for joystick 0, 1 for joystick 1, M for mouse,\n"
+ " a/b/c for various keyboard replacements\n" },
+ { "f:", " -f n : Set the frame rate to 1/n (draw only every nth frame)\n" },
+#ifndef UNSUPPORTED_OPTION_D
+ { "D", " -D : Start up the built-in debugger\n" },
+#endif
+ { "i", " -i : Print illegal memory accesses\n" },
+ { "t", " -t : Test drawing speed (makes the emulator very slow)\n" },
+#ifndef UNSUPPORTED_OPTION_G
+ { "G", " -G : Disable user interface\n" },
+#endif
+ { "A:", " -A n : Set emulator accuracy to n (0, 1 or 2)\n" },
+#ifdef USE_EXECLIB
+ { "g", " -g : Turn on gfx-lib replacement (EXPERIMENTAL).\n" },
+#endif
+ { "C:", " -C parms : Set CPU parameters. '0' for 68000 emulation, '1' for\n"
+ " 68010, '2' for 68020, '3' for 68020/68881. Additionally,\n"
+ " you can specify 'c' for a slow but compatible emulation\n"
+ " and 'a' for a 24 bit address space.\n" },
+ { "n:", " -n parms : Set blitter parameters: 'i' enables immediate blits,\n"
+ " '3' enables 32 bit blits (may crash RISC machines)\n" },
+ { "0:1:2:3:", " -[0123] file : Use file instead of df[0123].adf as disk image\n" },
+ { "r:", " -r file : Use file as ROM image instead of kick.rom\n" },
+ { "K:", " -K file : Use file as ROM key file for encrypted ROMs.\n" },
+#ifndef UNSUPPORTED_OPTION_S
+ { "S:", " -S spec : Set parameters for sound emulation (see below)\n" },
+#endif
+#ifndef UNSUPPORTED_OPTION_p
+ { "p:", " -p prt : Use for printer output (default " DEFPRTNAME ").\n" },
+#endif
+#ifndef UNSUPPORTED_OPTION_I
+ { "I:", " -I device : Use for serial output (e.g. " DEFSERNAME ").\n" },
+ { "d:", " -d [s][p] : Open serial/parallel port on demand only.\n" },
+#endif
+#ifdef TARGET_SPECIAL_OPTIONS
+ TARGET_SPECIAL_OPTIONS
+#endif
+ { "O:", " -O modespec : Define graphics mode (see below)\n" },
+ { "H:", " -H mode : Set the color mode (see below)\n" }
+};
+
void usage(void)
{
- printf("UAE - The Un*x Amiga emulator\n");
- printf("Summary of command-line options:\n");
- printf(" -h : Print help\n");
- printf(" -m VOL:dir : mount directory called as AmigaDOS volume VOL:\n");
- printf(" -M VOL:dir : like -m, but mount read-only\n");
- printf(" -s n : Emulate n*256 KB slow memory at 0xC00000\n");
- printf(" -c n : Emulate n*512 KB chip memory at 0x000000\n");
- printf(" -F n : Emulate n MB fast memory at 0x200000\n");
- printf(" -a : Add no expansion devices (disables fastmem and\n"
- " harddisk support\n");
- printf(" -J : Fake joystick emulation with the numeric pad\n");
- printf(" -f n : Set the frame rate to 1/n\n");
- printf(" -D : Start up the built-in debugger\n");
- printf(" -i : Print illegal memory accesses\n");
- printf(" -o : Allow options to be saved\n");
- printf(" -G : Disable user interface\n");
- printf(" -A n : Set emulator accuracy to n (0, 1 or 2)\n");
- printf(" -[0123] file : Use file instead of df[0123].adf as disk image\n");
- printf(" -r file : Use file as ROM image instead of kick.rom\n");
- target_specific_usage();
-/* printf(" -g : Turn on gfx-lib replacement (EXPERIMENTAL).\n");*/
-/* printf(" -d mode : OBSOLETE: Use \"-O\".\n");
- printf(" -C : OBSOLETE: use \"-O\"\n"); */
- printf(" -n parms : Set blitter parameters: 'i' enables immediate blits,\n"
- " '3' enables 32 bit blits (may crash RISC machines)\n");
- printf(" -O modespec : Define graphics mode (see below).\n");
- printf(" -H mode : Set the color mode (see below).\n");
- printf("\n"
+ int i;
+
+ printf ("UAE - The Un*x Amiga emulator\n");
+ printf ("Summary of command-line options (please read the README for more details):\n");
+ for (i = 0; i < sizeof uaeopts / sizeof *uaeopts; i++)
+ printf ("%s", uaeopts[i].helpstr);
+
+ printf ("\n");
+ printf ("%s",
+ "The format for the \"-S\" sound spec parameter is as follows:\n"
+ " -S enable:stereo:bits:freq:maxbuffer:minbuffer\n"
+ " You do not need to give the full specs, you can terminate after every field.\n"
+ " enable: Either 0 (no sound), 1 (emulated, but not output), 2 (emulated), or\n"
+ " 3 (completely accurate emulation). The suggested value is 2.\n"
+ " stereo: Either 's' (stereo) or 'm' (mono).\n"
+ " bits: Number of bits to use for sound output, usually 8 or 16\n"
+ " freq: Frequency for sound output; usually 44100 or 22050\n"
+ " maxbuffer: Maximum buffer size for sound output\n"
+ " minbuffer: Minimum buffer size for sound output\n"
+ "Larger buffers need less computing power, but the sound will be delayed.\n"
+ "Some of these settings will have no effect on certain ports of UAE.\n");
+ printf ("%s",
+#ifndef COLOR_MODE_HELP_STRING
"Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
" 3 (256 colors, with dithering for better results)\n"
" 4 (16 colors, dithered); 5 (16 million colors)\n"
+#else
+ COLOR_MODE_HELP_STRING
+#endif
+ );
+ printf ("%s",
"The format for the modespec parameter of \"-O\" is as follows:\n"
" -O width:height:modifiers\n"
" \"width\" and \"height\" specify the dimensions of the picture.\n"
" \"modifiers\" is a string that contains zero or more of the following\n"
" characters:\n"
- " l: Treat the display as lores, drawing only every second pixel\n"
+ " l: Treat the display as lores, drawing only every second pixel\n"
" x, y: Center the screen horizontally or vertically.\n"
- " d: Draw every line twice unless in interlace: this doubles the height\n"
- " of the display (this is the old -C parameter).\n"
- " c: Correct aspect ratio (this is _not_ the old -C parameter).\n"
+ " d: Doubles the height of the display for better interlace emulation\n"
+ " c: Correct aspect ratio\n"
"UAE may choose to ignore the color mode setting and/or adjust the\n"
- "video mode setting to reasonable values.\n");
+ "video mode setting to reasonable values.\n");
}
static void parse_gfx_specs (char *spec)
{
char *x0 = my_strdup (spec);
char *x1, *x2;
-
+
x1 = strchr (x0, ':');
if (x1 == 0)
goto argh;
@@ -148,185 +441,318 @@ static void parse_gfx_specs (char *spec)
if (x2 == 0)
goto argh;
*x1++ = 0; *x2++ = 0;
-
- gfx_requested_width = atoi (x0);
- gfx_requested_height = atoi (x1);
- gfx_requested_lores = strchr (x2, 'l') != 0;
- gfx_requested_xcenter = strchr (x2, 'x') != 0 ? 1 : strchr (x2, 'X') != 0 ? 2 : 0;
- gfx_requested_ycenter = strchr (x2, 'y') != 0 ? 1 : strchr (x2, 'Y') != 0 ? 2 : 0;
- gfx_requested_linedbl = strchr (x2, 'd') != 0;
- gfx_requested_correct_aspect = strchr (x2, 'c') != 0;
-
+
+ currprefs.gfx_width = atoi (x0);
+ currprefs.gfx_height = atoi (x1);
+ currprefs.gfx_lores = strchr (x2, 'l') != 0;
+ currprefs.gfx_xcenter = strchr (x2, 'x') != 0 ? 1 : strchr (x2, 'X') != 0 ? 2 : 0;
+ currprefs.gfx_ycenter = strchr (x2, 'y') != 0 ? 1 : strchr (x2, 'Y') != 0 ? 2 : 0;
+ currprefs.gfx_linedbl = strchr (x2, 'd') != 0;
+ currprefs.gfx_correct_aspect = strchr (x2, 'c') != 0;
+
free (x0);
return;
-
+
argh:
fprintf (stderr, "Bad display mode specification.\n");
fprintf (stderr, "The format to use is: \"width:height:modifiers\"\n");
+ fprintf (stderr, "Type \"uae -h\" for detailed help.\n");
free (x0);
}
-#if defined(__unix)||defined(AMIGA)
+static void parse_sound_spec (char *spec)
+{
+ char *x0 = my_strdup (spec);
+ char *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL, *x5 = NULL;
-void parse_cmdline(int argc, char **argv)
+ x1 = strchr (x0, ':');
+ if (x1 != NULL) {
+ *x1++ = '\0';
+ x2 = strchr (x1 + 1, ':');
+ if (x2 != NULL) {
+ *x2++ = '\0';
+ x3 = strchr (x2 + 1, ':');
+ if (x3 != NULL) {
+ *x3++ = '\0';
+ x4 = strchr (x3 + 1, ':');
+ if (x4 != NULL) {
+ *x4++ = '\0';
+ x5 = strchr (x4 + 1, ':');
+ }
+ }
+ }
+ }
+ currprefs.produce_sound = atoi (x0);
+ if (x1) {
+ if (*x1 == 's')
+ currprefs.stereo = 1;
+ else
+ currprefs.stereo = 0;
+ }
+ if (x2)
+ currprefs.sound_bits = atoi (x2);
+ if (x3)
+ currprefs.sound_freq = atoi (x3);
+ if (x4)
+ currprefs.sound_maxbsiz = currprefs.sound_minbsiz = atoi (x4);
+ if (x5)
+ currprefs.sound_minbsiz = atoi (x5);
+ free (x0);
+ return;
+}
+
+const char *gameport_state (int nr)
{
- int c;
- extern char *optarg;
-#ifdef __BEOS__
- if (argc < 2)
- return;
+ if (JSEM_ISJOY0 (nr, currprefs.fake_joystick) && nr_joysticks > 0)
+ return "using joystick #0";
+ else if (JSEM_ISJOY1 (nr, currprefs.fake_joystick) && nr_joysticks > 1)
+ return "using joystick #1";
+ else if (JSEM_ISMOUSE (nr, currprefs.fake_joystick))
+ return "using mouse";
+ else if (JSEM_ISNUMPAD (nr, currprefs.fake_joystick))
+ return "using numeric pad as joystick";
+ else if (JSEM_ISCURSOR (nr, currprefs.fake_joystick))
+ return "using cursor keys as joystick";
+ else if (JSEM_ISSOMEWHEREELSE (nr, currprefs.fake_joystick))
+ return "using T/F/H/B/Alt as joystick";
+
+ return "not connected";
+}
+
+static int parse_joy_spec (char *spec)
+{
+ int v0 = 2, v1 = 0;
+ if (strlen(spec) != 2)
+ goto bad;
+
+ switch (spec[0]) {
+ case '0': v0 = 0; break;
+ case '1': v0 = 1; break;
+ case 'M': case 'm': v0 = 2; break;
+ case 'A': case 'a': v0 = 3; break;
+ case 'B': case 'b': v0 = 4; break;
+ case 'C': case 'c': v0 = 5; break;
+ default: goto bad;
+ }
+
+ switch (spec[1]) {
+ case '0': v1 = 0; break;
+ case '1': v1 = 1; break;
+ case 'M': case 'm': v1 = 2; break;
+ case 'A': case 'a': v1 = 3; break;
+ case 'B': case 'b': v1 = 4; break;
+ case 'C': case 'c': v1 = 5; break;
+ default: goto bad;
+ }
+ if (v0 == v1)
+ goto bad;
+ /* Let's scare Pascal programmers */
+ if (0)
+bad:
+ fprintf (stderr, "Bad joystick mode specification. Use -J xy, where x and y\n"
+ "can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n"
+ "a, b or c for different keyboard settings.\n");
+
+ return v0 + (v1 << 8);
+}
+
+static void parse_filesys_spec (int readonly, char *spec)
+{
+ char buf[256];
+ char *s2;
+
+ strncpy(buf, spec, 255); buf[255] = 0;
+ s2 = strchr(buf, ':');
+ if(s2) {
+ *s2++ = '\0';
+#ifdef __DOS__
+ {
+ char *tmp;
+
+ while ((tmp = strchr(s2, '\\')))
+ *tmp = '/';
+ }
#endif
+ s2 = add_filesys_unit(buf, s2, readonly, 0, 0, 0);
+ if (s2)
+ fprintf (stderr, "%s\n", s2);
+ } else {
+ fprintf (stderr, "Usage: [-m | -M] VOLNAME:mount_point\n");
+ }
+}
+
+static void parse_hardfile_spec (char *spec)
+{
+ char *x0 = my_strdup (spec);
+ char *x1, *x2, *x3;
+
+ x1 = strchr (x0, ':');
+ if (x1 == NULL)
+ goto argh;
+ *x1++ = '\0';
+ x2 = strchr (x1 + 1, ':');
+ if (x2 == NULL)
+ goto argh;
+ *x2++ = '\0';
+ x3 = strchr (x2 + 1, ':');
+ if (x3 == NULL)
+ goto argh;
+ *x3++ = '\0';
+ x3 = add_filesys_unit (0, x3, 0, atoi (x0), atoi (x1), atoi (x2));
+ if (x3)
+ fprintf (stderr, "%s\n", x3);
+
+ free (x0);
+ return;
+
+ argh:
+ free (x0);
+ fprintf (stderr, "Bad hardfile parameter specified - type \"uae -h\" for help.\n");
+ return;
+}
+
+static void parse_cpu_specs (char *spec)
+{
+ if (*spec < '0' || *spec > '3') {
+ fprintf (stderr, "CPU parameter string must begin with '0', '1', '2' or '3'.\n");
+ return;
+ }
+
+ currprefs.cpu_level = *spec++ - '0';
+ currprefs.address_space_24 = currprefs.cpu_level < 2;
+ currprefs.cpu_compatible = 0;
+ while (*spec != '\0') {
+ switch (*spec) {
+ case 'a':
+ if (currprefs.cpu_level < 2)
+ fprintf (stderr, "In 68000/68010 emulation, the address space is always 24 bit.\n");
+ else
+ currprefs.address_space_24 = 1;
+ break;
+ case 'c':
+ if (currprefs.cpu_level != 0)
+ fprintf (stderr, "The more compatible CPU emulation is only available for 68000\n"
+ "emulation, not for 68010 upwards.\n");
+ else
+ currprefs.cpu_compatible = 1;
+ break;
+ default:
+ fprintf (stderr, "Bad CPU parameter specified - type \"uae -h\" for help.\n");
+ break;
+ }
+ spec++;
+ }
+}
+
+#ifndef DONT_PARSE_CMDLINE
+
+void parse_cmdline(int argc, char **argv)
+{
+ int c, i;
+ char getopt_str[256];
+ strcpy (getopt_str, "");
+
+ for (i = 0; i < sizeof uaeopts / sizeof *uaeopts; i++)
+ strcat (getopt_str, uaeopts[i].getopt_str);
+
/* Help! We're running out of letters! */
- while(((c = getopt(argc, argv, "l:Dif:gd:hxF:as:c:S:Jm:M:0:1:2:3:r:H:p:C:I:b:R:B:oGA:tO:n:")) != EOF))
+ while(((c = getopt(argc, argv, getopt_str)) != EOF))
switch(c) {
case 'h': usage(); exit(0);
- case '0': strncpy(df0, optarg, 255); df0[255] = 0; break;
- case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
- case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
- case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
- case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
- case 'p': strncpy(prtname, optarg, 255); prtname[255] = 0; break;
- case 'I': strncpy(sername, optarg, 255); sername[255] = 0; use_serial = 1; break;
- case 'm':
- case 'M':
- {
- char buf[256];
- char *s2;
- int readonly = (c == 'M');
-
- strncpy(buf, optarg, 255); buf[255] = 0;
- s2 = strchr(buf, ':');
- if(s2) {
- *s2++ = '\0';
-#ifdef __DOS__
- {
- char *tmp;
+ case '0': strncpy (currprefs.df[0], optarg, 255); currprefs.df[0][255] = 0; break;
+ case '1': strncpy (currprefs.df[1], optarg, 255); currprefs.df[1][255] = 0; break;
+ case '2': strncpy (currprefs.df[2], optarg, 255); currprefs.df[2][255] = 0; break;
+ case '3': strncpy (currprefs.df[3], optarg, 255); currprefs.df[3][255] = 0; break;
+ case 'r': strncpy (romfile, optarg, 255); romfile[255] = 0; break;
+ case 'K': strncpy (keyfile, optarg, 255); keyfile[255] = 0; break;
+ case 'p': strncpy (prtname, optarg, 255); prtname[255] = 0; break;
+ case 'I': strncpy (sername, optarg, 255); sername[255] = 0; currprefs.use_serial = 1; break;
+ case 'm': case 'M': parse_filesys_spec (c == 'M', optarg); break;
+ case 'W': parse_hardfile_spec (optarg); break;
+ case 'S': parse_sound_spec (optarg); break;
+ case 'f': currprefs.framerate = atoi (optarg); break;
+ case 'A': currprefs.emul_accuracy = atoi (optarg); break;
+ case 'x': currprefs.no_xhair = 1; break;
+ case 'i': currprefs.illegal_mem = 1; break;
+ case 'J': currprefs.fake_joystick = parse_joy_spec (optarg); break;
+ case 'a': currprefs.automount_uaedev = 0; break;
+
+ case 't': currprefs.test_drawing_speed = 1; break;
+ case 'L': currprefs.use_low_bandwidth = 1; break;
+ case 'T': currprefs.use_mitshm = 1; break;
+ case 'w': currprefs.m68k_speed = atoi (optarg); break;
- while ((tmp = strchr(s2, '\\')))
- *tmp = '/';
- }
-#endif
- add_filesys_unit(buf, s2, readonly);
- } else {
- fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
- }
- }
- break;
-
- case 'S': produce_sound = atoi(optarg); break;
- case 'f': framerate = atoi(optarg); break;
- case 'A': emul_accuracy = atoi(optarg); break;
- case 'x': no_xhair = 1; break;
- case 'D': use_debugger = 1; break;
- case 'i': illegal_mem = 1; break;
- case 'J': fake_joystick = 1; break;
- case 'a': automount_uaedev = 0; break;
case 'g': use_gfxlib = 1; break;
- case 'o': allow_save = 1; break;
case 'G': no_gui = 1; break;
- case 't': test_drawing_speed = 1; break;
+ case 'D': use_debugger = 1; break;
case 'n':
if (strchr (optarg, '3') != 0)
- blits_32bit_enabled = 1;
+ currprefs.blits_32bit_enabled = 1;
if (strchr (optarg, 'i') != 0)
- immediate_blits = 0;
+ currprefs.immediate_blits = 1;
break;
case 'C':
- fprintf (stderr, "The -C option is obsolete, please use -O.\n");
- correct_aspect = atoi(optarg);
- if (correct_aspect < 0 || correct_aspect > 2) {
- fprintf(stderr, "Bad parameter for -C !\n");
- correct_aspect = 0;
- }
+ parse_cpu_specs (optarg);
+ break;
+
+ case 'Z':
+ z3fastmem_size = atoi (optarg) * 0x100000;
+ break;
+
+ case 'U':
+ gfxmem_size = atoi (optarg) * 0x100000;
break;
case 'F':
- fastmem_size = atoi(optarg) * 0x100000;
- if (fastmem_size != 0x100000 && fastmem_size != 0x200000
- && fastmem_size != 0x400000 && fastmem_size != 0x800000)
- {
- fastmem_size = 0;
- fprintf(stderr, "Unsupported fastmem size!\n");
- }
+ fastmem_size = atoi (optarg) * 0x100000;
break;
case 's':
- bogomem_size = atoi(optarg) * 0x40000;
- if (bogomem_size != 0x80000 && bogomem_size != 0x100000
- /* Braino && bogomem_size != 0x180000 && bogomem_size != 0x1C0000*/)
- {
- bogomem_size = 0;
- fprintf(stderr, "Unsupported bogomem size!\n");
- }
+ bogomem_size = atoi (optarg) * 0x40000;
break;
case 'c':
- chipmem_size = atoi(optarg) * 0x80000;
- if (chipmem_size != 0x80000 && chipmem_size != 0x100000
- && chipmem_size != 0x200000 && chipmem_size != 0x400000
- && chipmem_size != 0x800000)
- {
- chipmem_size = 0x200000;
- fprintf(stderr, "Unsupported chipmem size!\n");
- }
-
+ chipmem_size = atoi (optarg) * 0x80000;
break;
case 'l':
if (0 == strcasecmp(optarg, "de"))
- keyboard_lang = KBD_LANG_DE;
+ currprefs.keyboard_lang = KBD_LANG_DE;
else if (0 == strcasecmp(optarg, "us"))
- keyboard_lang = KBD_LANG_US;
+ currprefs.keyboard_lang = KBD_LANG_US;
else if (0 == strcasecmp(optarg, "se"))
- keyboard_lang = KBD_LANG_SE;
+ currprefs.keyboard_lang = KBD_LANG_SE;
else if (0 == strcasecmp(optarg, "fr"))
- keyboard_lang = KBD_LANG_FR;
+ currprefs.keyboard_lang = KBD_LANG_FR;
else if (0 == strcasecmp(optarg, "it"))
- keyboard_lang = KBD_LANG_IT;
+ currprefs.keyboard_lang = KBD_LANG_IT;
else if (0 == strcasecmp(optarg, "es"))
- keyboard_lang = KBD_LANG_ES;
+ currprefs.keyboard_lang = KBD_LANG_ES;
break;
case 'O': parse_gfx_specs (optarg); break;
case 'd':
- fprintf (stderr, "Note: The -d option is obsolete, please use the new -O format.\n");
- c = atoi(optarg);
- switch (c) {
- case 0:
- parse_gfx_specs("320:200:lx");
- break;
- case 1:
- parse_gfx_specs("320:240:lx");
- break;
- case 2:
- parse_gfx_specs("320:400:lx");
- break;
- case 3:
- parse_gfx_specs("640:300:x");
- break;
- default:
- fprintf(stderr, "Bad video mode selected. Using default.\n");
- /* fall through */
- case 4:
- parse_gfx_specs("800:600:");
- break;
+ if (strchr (optarg, 'S') != NULL || strchr (optarg, 's')) {
+ write_log (" Serial on demand.\n");
+ currprefs.serial_demand = 1;
+ }
+ if (strchr (optarg, 'P') != NULL || strchr (optarg, 'p')) {
+ write_log (" Parallel on demand.\n");
+ currprefs.parallel_demand = 1;
}
+
break;
case 'H':
- color_mode = atoi(optarg);
- if (color_mode < 0 || color_mode > MAX_COLOR_MODES) {
- fprintf(stderr, "Bad color mode selected. Using default.\n");
- color_mode = 0;
+ currprefs.color_mode = atoi (optarg);
+ if (currprefs.color_mode < 0) {
+ fprintf (stderr, "Bad color mode selected. Using default.\n");
+ currprefs.color_mode = 0;
}
break;
-
- case 'b': sound_desired_bits = atoi(optarg); break;
- case 'B': sound_desired_bsiz = atoi(optarg); break;
- case 'R': sound_desired_freq = atoi(optarg); break;
}
}
#endif
@@ -334,17 +760,19 @@ void parse_cmdline(int argc, char **argv
static void parse_cmdline_and_init_file(int argc, char **argv)
{
FILE *f;
- char *home;
+ char *tmp;
+ int t;
char *buffer,*tmpbuf, *token;
char smallbuf[256];
int bufsiz, result;
int n_args;
char **new_argv;
int new_argc;
+ char *home;
strcpy(optionsfile,"");
-#if !defined(__DOS__) && !defined(__mac__)
+#ifdef OPTIONS_IN_HOME
home = getenv("HOME");
if (home != NULL && strlen(home) < 240)
{
@@ -353,17 +781,14 @@ static void parse_cmdline_and_init_file(
}
#endif
-#ifndef __DOS__
- strcat(optionsfile, ".uaerc");
-#else
- strcat(optionsfile, "uae.rc");
-#endif
+ strcat(optionsfile, OPTIONSFILENAME);
- f = fopen(optionsfile,"rb");
-#ifndef __DOS__
-/* sam: if not found in $HOME then look in current directory */
+ f = fopen(optionsfile, "rb");
+#ifdef OPTIONS_IN_HOME
+ /* sam: if not found in $HOME then look in current directory */
if (f == NULL) {
- f = fopen(".uaerc","rb");
+ strcpy (optionsfile, OPTIONSFILENAME);
+ f = fopen(optionsfile, "rb");
}
#endif
@@ -377,30 +802,48 @@ static void parse_cmdline_and_init_file(
buffer = (char *)malloc(bufsiz+1);
buffer[bufsiz] = 0;
- if (fread(buffer, 1, bufsiz, f) < bufsiz) {
- fprintf(stderr, "Error reading configuration file\n");
- fclose(f);
- parse_cmdline(argc, argv);
+ if (fread (buffer, 1, bufsiz, f) < bufsiz) {
+ fprintf (stderr, "Error reading configuration file\n");
+ fclose (f);
+ parse_cmdline (argc, argv);
return;
}
fclose(f);
-#ifdef __DOS__
- {
- char *tmp;
-
- while ((tmp = strchr(buffer, 0x0d)))
- *tmp = ' ';
- while ((tmp = strchr(buffer, 0x0a)))
+ /* Canonicalize the buffer */
+ while ((tmp = strchr (buffer, '\r')))
+ *tmp = ' ';
+ for (;;) {
+ tmp = strchr (buffer, '\n');
+ if (tmp == 0)
+ break;
+ if (tmp[1] == '#') {
+ char *tmp2 = strchr (tmp + 1, '\n');
+ if (tmp2 == 0)
+ *tmp = '\0';
+ else
+ memmove (tmp, tmp2, strlen (tmp2) + 1);
+ } else {
*tmp = ' ';
- while (buffer[0] == ' ')
- strcpy(buffer, buffer+1);
- while ((strlen(buffer) > 0) && (buffer[strlen(buffer) - 1] == ' '))
- buffer[strlen(buffer) - 1] = '\0';
- while ((tmp = strstr(buffer, " ")))
- strcpy(tmp, tmp+1);
+ }
+ }
+ while ((tmp = strchr(buffer, '\t')))
+ *tmp = ' ';
+
+ tmp = buffer;
+ while (*tmp == ' ')
+ tmp++;
+ t = strlen (tmp);
+ memmove (buffer, tmp, t + 1);
+
+ while (t > 0 && buffer[t-1] == ' ')
+ buffer[--t] = '\0';
+ for (;;) {
+ tmp = strstr (buffer, " ");
+ if (tmp == 0)
+ break;
+ memmove (tmp, tmp + 1, strlen (tmp));
}
-#endif
tmpbuf = my_strdup (buffer);
@@ -428,8 +871,6 @@ static void parse_cmdline_and_init_file(
parse_cmdline(new_argc, new_argv);
}
-#define ARE_YOU_NUTS 0
-
/* Okay, this stuff looks strange, but it is here to encourage people who
* port UAE to re-use as much of this code as possible. Functions that you
* should be using are do_start_program() and do_leave_program(), as well
@@ -442,29 +883,29 @@ static void parse_cmdline_and_init_file(
void do_start_program(void)
{
-#ifdef USE_EXECLIB
- if (ARE_YOU_NUTS && use_gfxlib)
- execlib_sysinit();
- else
-#endif
- m68k_go(1);
+ /* Do a reset on startup. Whether this is elegant is debatable. */
+ quit_program = 2;
+ m68k_go(1);
}
void do_leave_program(void)
{
graphics_leave();
close_joystick();
+ close_sound();
dump_counts();
serial_exit();
zfile_exit();
if (!no_gui)
- gui_exit();
+ gui_exit();
}
+#ifndef _WIN32
void start_program(void)
{
do_start_program();
}
+#endif
void leave_program(void)
{
@@ -475,13 +916,10 @@ void real_main(int argc, char **argv)
{
FILE *hf;
- hf = fopen("hardfile", "rb");
- if (hf == NULL)
- hardfile_size = 0;
- else {
- fseek(hf, 0, SEEK_END);
- hardfile_size = ftell(hf);
- fclose(hf);
+ default_currprefs ();
+
+ if (!graphics_setup()) {
+ exit(1);
}
rtarea_init ();
@@ -489,63 +927,65 @@ void real_main(int argc, char **argv)
parse_cmdline_and_init_file(argc, argv);
- if (!init_sound()) {
- fprintf(stderr, "Sound driver unavailable: Sound output disabled\n");
- produce_sound = 0;
+ machdep_init();
+
+ if (!setup_sound()) {
+ fprintf (stderr, "Sound driver unavailable: Sound output disabled\n");
+ currprefs.produce_sound = 0;
}
init_joystick();
if (!no_gui) {
int err = gui_init();
if (err == -1) {
- fprintf(stderr, "Failed to initialize the GUI\n");
+ fprintf (stderr, "Failed to initialize the GUI\n");
} else if (err == -2) {
exit(0);
}
}
+ if (sound_available && !init_sound()) {
+ fprintf (stderr, "Sound driver unavailable: Sound output disabled\n");
+ currprefs.produce_sound = 0;
+ }
fix_options();
-
+ changed_prefs = currprefs;
+
/* Install resident module to get 8MB chipmem, if requested */
rtarea_setup();
-
- keybuf_init();
-
+
+ keybuf_init(); /* Must come after init_joystick */
+
expansion_init ();
memory_init();
filesys_install();
-#ifdef USE_EXECLIB
- execlib_install();
-#endif
gfxlib_install();
emulib_install();
- trackdisk_install();
+ uaeexe_install();
- custom_init();
+ custom_init(); /* Must come after memory_init */
serial_init();
DISK_init();
init_m68k();
compiler_init();
gui_update();
-
- if (graphics_init()) {
- customreset();
- m68k_reset();
-
- setup_brkhandler();
- if (use_debugger && debuggable())
- activate_debugger();
- start_program();
+ if (graphics_init ()) {
+ setup_brkhandler ();
+ filesys_start_threads ();
+ if (use_debugger && debuggable ())
+ activate_debugger ();
+
+ start_program ();
}
- leave_program();
+ leave_program ();
}
-#ifndef __BEOS__ /* BeOS needs its own startup code */
+#ifndef NO_MAIN_IN_MAIN_C
int main(int argc, char **argv)
{
real_main(argc, argv);
return 0;
}
-#endif /* not __BEOS__ */
+#endif