--- uae/src/main.c 2018/04/24 16:38:39 1.1 +++ uae/src/main.c 2018/04/24 17:21:48 1.1.1.24 @@ -1,17 +1,22 @@ /* * 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" #include "sysdeps.h" #include -#include "config.h" #include "options.h" +#include "threaddep/thread.h" +#include "uae.h" +#include "gensound.h" +#include "audio.h" +#include "sounddep/sound.h" +#include "events.h" #include "memory.h" #include "custom.h" #include "serial.h" @@ -19,383 +24,660 @@ #include "disk.h" #include "debug.h" #include "xwin.h" -#include "os.h" +#include "inputdevice.h" #include "keybuf.h" #include "gui.h" #include "zfile.h" #include "autoconf.h" -#include "compiler.h" +#include "filesys.h" +#include "osemu.h" +#include "picasso96.h" +#include "traps.h" +#include "bsdsocket.h" +#include "uaeexe.h" +#include "native2amiga.h" +#include "scsidev.h" +#include "romlist.h" + +#ifdef USE_SDL +#include "SDL.h" +#endif + +struct uae_prefs currprefs, changed_prefs; +struct gfx_params *curr_gfx; -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_lores = 0; -int use_serial = 0; -int automount_uaedev = 1; -int produce_sound = 0; -int fake_joystick = 0; -KbdLang keyboard_lang = KBD_LANG_US; -int screen_res = 4; -int correct_aspect = 0; -int color_mode = 0; -int sound_desired_bits = 16; -int sound_desired_freq = 44100; -int sound_desired_bsiz = 8192; -int allow_save = 0; int no_gui = 0; +int joystickpresent = 0; +int cloanto_rom = 0; -long hardfile_size = 0; +struct gui_info gui_data; -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"; -char romfile[256] = "kick.rom"; -#ifndef __DOS__ -char prtname[256] = "lpr "; -#else -char prtname[256] = "PRN"; -#endif +char warning_buffer[256]; 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. * - * Note for the DOS-Port: Maybe it's only neccesary to use a - * -p LPT1: or -p PRN: to print in a DOSBOX. I don't know, - * I do not use DOS... (please try) -=SR=- + * 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", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" +}; -/* And again: Serial lines work under Linux. I don't know - * how this behaves in other OSes. This is work for the porting - * people -=SR=- - */ +struct uae_rect *gfx_fullscreen_modes, *gfx_windowed_modes; +int n_fullscreen_modes, n_windowed_modes; -void usage(void) +static struct uae_rect default_windowed_modes[] = { - printf("UAE - The Un*x Amiga emulator\n"); - printf("Summary of command-line options:\n"); - printf(" -h : Print help\n"); - printf(" -m VOLNAME:mount_point : mount file system at as AmigaDOS\n" - " volume VOLNAME:\n"); - printf(" -M VOLNAME:mount_point : 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(" -[0123] file : Use file instead of df[0123].adf as disk image.e\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 : Select resolution with the mode parameter.\n"); - printf(" -H mode : Set the number of colors with the mode parameter.\n"); - printf(" -C : Use correct aspect display mode.\n"); - printf("\n"); - printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (640x480);\n" - " 4 (800x600)\n" - "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" - "UAE may choose to ignore the color mode/resolution setting.\n"); -} - -#ifdef __unix - -void parse_cmdline(int argc, char **argv) -{ - int c; - extern char *optarg; - - while(((c = getopt(argc, argv, "l:Dif:gd:hxF:as:c:S:Jm:M:0:1:2:3:r:H:p:CI:b:R:B:oG")) != 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; - - while ((tmp = strchr(s2, '\\'))) - *tmp = '/'; - } -#endif - add_filesys_unit(buf, s2, readonly); - } else { - fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n"); + { 320, 256 }, + { 400, 300 }, + { 640, 512 }, + { 800, 600 } +}; + +struct config_list *predef_configs; +int n_predef_configs; +int predef_configs_space; + +static int sortfn (const void *a, const void *b) +{ + struct config_list *pa = (struct config_list *)a; + struct config_list *pb = (struct config_list *)b; + return strcmp (pa->sortstr, pb->sortstr); +} + +static void scan_configs (const char *path) +{ + DIR *dir; + int pathlen = strlen (path); + int bufsz = pathlen + 256; + char *buffer; + uae_u8 *data; + + predef_configs_space = 20; + predef_configs = malloc (sizeof (struct config_list) * 20); + n_predef_configs = 0; + + dir = opendir (path); + if (!dir) + return; + + buffer = malloc (bufsz); + if (!buffer) + goto out; + data = malloc (1024 * 1024); + if (!data) + goto out1; + + strcpy (buffer, path); + buffer[pathlen++] = '/'; + buffer[pathlen] = '\0'; + for (;;) { + struct uae_prefs p; + struct zfile *f; + struct dirent *ent = readdir (dir); + int len; + struct romdata *rd; + long size; + + if (!ent) + break; + + len = strlen (ent->d_name); + if (len + pathlen + 1 >= bufsz) { + bufsz = len + pathlen + 200; + buffer = realloc (buffer, bufsz); + if (!buffer) { + free (data); + goto out; } } - break; - - case 'S': produce_sound = atoi(optarg); break; - case 'f': framerate = 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 'C': correct_aspect = 1; break; - case 'o': allow_save = 1; break; - case 'G': no_gui = 1; 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"); - } - 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"); - } - break; + strcpy (buffer + pathlen, ent->d_name); - case 'c': - chipmem_size = atoi(optarg) * 0x80000; - if (chipmem_size != 0x80000 && chipmem_size != 0x100000 - && chipmem_size != 0x200000) - { - chipmem_size = 0x200000; - fprintf(stderr, "Unsupported chipmem size!\n"); + if (n_predef_configs >= predef_configs_space) { + predef_configs_space += 20; + predef_configs = realloc (predef_configs, + sizeof (struct config_list) * predef_configs_space); } - - break; - - case 'l': - if (0 == strcasecmp(optarg, "de")) - keyboard_lang = KBD_LANG_DE; - else if (0 == strcasecmp(optarg, "us")) - keyboard_lang = KBD_LANG_US; - else if (0 == strcasecmp(optarg, "se")) - keyboard_lang = KBD_LANG_SE; - else if (0 == strcasecmp(optarg, "fr")) - keyboard_lang = KBD_LANG_FR; - else if (0 == strcasecmp(optarg, "it")) - keyboard_lang = KBD_LANG_IT; - break; - - case 'd': - screen_res = atoi(optarg); - if (screen_res < 0 || screen_res > MAX_SCREEN_MODES) { - fprintf(stderr, "Bad video mode selected. Using default.\n"); - screen_res = 3; + default_prefs (&p); + strcpy (p.description, ""); + strcpy (p.sortstr, ""); + cfgfile_load (&p, buffer); + if (strlen (p.description) > 0) { + predef_configs[n_predef_configs].filename = strdup (buffer); + predef_configs[n_predef_configs].description = strdup (p.description); + predef_configs[n_predef_configs++].sortstr = strdup (p.sortstr); } - break; + } + qsort (predef_configs, n_predef_configs, sizeof *predef_configs, sortfn); + free (data); + out1: + free (buffer); + out: + closedir (dir); +} - 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; - } - break; +void discard_prefs (struct uae_prefs *p) +{ + struct strlist **ps = &p->unknown_lines; + while (*ps) { + struct strlist *s = *ps; + *ps = s->next; + free (s->str); + free (s); + } + free_mountinfo (p->mountinfo); +} + +void default_prefs (struct uae_prefs *p) +{ + strcpy (p->description, "UAE default configuration"); - case 'b': sound_desired_bits = atoi(optarg); break; - case 'B': sound_desired_bsiz = atoi(optarg); break; - case 'R': sound_desired_freq = atoi(optarg); break; + p->start_gui = 1; + p->start_debugger = 0; + + p->unknown_lines = 0; + /* Note to porters: please don't change any of these options! UAE is supposed + * to behave identically on all platforms if possible. */ + p->illegal_mem = 0; + p->use_serial = 0; + p->serial_demand = 0; + p->parallel_demand = 0; + + p->jport0 = JSEM_MICE; + p->jport1 = JSEM_JOYS; + + p->keyboard_lang = KBD_LANG_US; + p->emul_accuracy = 2; + p->test_drawing_speed = 0; + + p->produce_sound = 3; + p->sound_stereo = 0; + p->sound_stereo_separation = 7; + p->sound_mixed_stereo_delay = 0; + p->sound_freq = DEFAULT_SOUND_FREQ; + p->sound_maxbsiz = DEFAULT_SOUND_MAXB; + p->sound_interpol = 2; + p->sound_filter = FILTER_SOUND_OFF; + p->sound_filter_type = FILTER_SOUND_TYPE_A500; + + p->gfx_framerate = 1; + p->gfx_w.width = 800; + p->gfx_w.height = 600; + p->gfx_w.lores = 0; + p->gfx_w.linedbl = 2; + p->gfx_w.correct_aspect = 0; + p->gfx_w.xcenter = 0; + p->gfx_w.ycenter = 0; + p->gfx_f = p->gfx_w; + p->gfx_w.leds_on_screen = 0; + p->gfx_f.leds_on_screen = 1; + p->gfx_afullscreen = 0; + p->gfx_pfullscreen = 0; + p->color_mode = 0; + + p->x11_use_low_bandwidth = 0; + p->x11_use_mitshm = 0; + p->x11_hide_cursor = 1; + + p->svga_no_linear = 0; + + p->curses_reverse_video = 0; + + p->win32_middle_mouse = 0; + p->win32_logfile = 0; + p->win32_iconified_nospeed = 0; + p->win32_iconified_nosound = 0; + p->win32_no_overlay = 0; + + p->immediate_blits = 0; + p->collision_level = 1; + + p->chipset_mask = CSMASK_ECS_AGNUS; + p->cs_rtc = 2; + p->cs_a1000ram = 0; + p->cs_fatgaryrev = -1; + p->cs_ramseyrev = -1; + p->cs_ide = 0; + + strcpy (p->df[0], "df0.adf"); + strcpy (p->df[1], "df1.adf"); + strcpy (p->df[2], "df2.adf"); + strcpy (p->df[3], "df3.adf"); + + strcpy (p->romfile, "kick.rom"); + strcpy (p->keyfile, ""); + strcpy (p->prtname, DEFPRTNAME); + p->rom_crc32 = 0; + + strcpy (p->path_rom, "./"); + strcpy (p->path_floppy, "./"); + strcpy (p->path_hardfile, "./"); + + strcpy (p->prtname, ""); + strcpy (p->sername, ""); + + p->nr_floppies = 2; + p->dfxtype[0] = DRV_35_DD; + p->dfxtype[1] = DRV_35_DD; + p->dfxtype[2] = DRV_NONE; + p->dfxtype[3] = DRV_NONE; + + p->m68k_speed = 0; + p->cpu_model = 68020; + p->fpu_model = 0; + p->address_space_24 = 0; + + p->fastmem_size = 0x00000000; + p->mbresmem_low_size = 0x00000000; + p->mbresmem_high_size = 0x00000000; + p->z3fastmem_size = 0x00000000; + p->chipmem_size = 0x00200000; + p->bogomem_size = 0x00000000; + p->gfxmem_size = 0x00000000; + + p->mountinfo = alloc_mountinfo (); + inputdevice_default_prefs (p); + p->bootrom = 1; +} + +int fixup_prefs_dimensions (struct gfx_params *p, struct uae_rect *modes, int n_modes) +{ + int i; + if (p->width < 320) + p->width = 320; + if (p->height < 200) + p->height = 200; + for (i = 0; i < n_modes; i++) { + if ((modes[i].w >= p->width && modes[i].h >= p->height) + || i == n_modes - 1) + { + p->width = modes[i].w; + p->height = modes[i].h; + p->lores = p->width <= 512; + if (p->height > 300 && !p->linedbl) + p->linedbl = 1; + return i; + } } + return n_modes - 1; } -#endif -#ifndef __bebox__ /* BeOS needs its own startup code */ +static void fixup_sound (struct uae_prefs *p) +{ + if (p->sound_stereo_separation < 0) + p->sound_stereo_separation = 0; + if (p->sound_stereo_separation > MIXED_STEREO_MAX) + p->sound_stereo_separation = MIXED_STEREO_MAX; +} -static void parse_cmdline_and_init_file(int argc, char **argv) +static void fixup_prefs (struct uae_prefs *p) { - FILE *f; - char *home; - char *buffer,*tmpbuf, *token; - char smallbuf[256]; - int bufsiz, result; - int n_args; - char **new_argv; - int new_argc; - - strcpy(optionsfile,""); - -#if !defined(__DOS__) && !defined(__mac__) - home = getenv("HOME"); - if (home != NULL && strlen(home) < 240) + int err = 0; + + if ((p->chipmem_size & (p->chipmem_size - 1)) != 0 + || p->chipmem_size < 0x80000 + || p->chipmem_size > 0x800000) + { + p->chipmem_size = 0x200000; + write_log ("Unsupported chipmem size!\n"); + err = 1; + } + if ((p->fastmem_size & (p->fastmem_size - 1)) != 0 + || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000))) + { + p->fastmem_size = 0; + write_log ("Unsupported fastmem size!\n"); + err = 1; + } + if ((p->gfxmem_size & (p->gfxmem_size - 1)) != 0 + || (p->gfxmem_size != 0 && (p->gfxmem_size < 0x100000 || p->gfxmem_size > 0x2000000))) + { + write_log ("Unsupported graphics card memory size %lx!\n", p->gfxmem_size); + p->gfxmem_size = 0; + err = 1; + } + if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0 + || (p->z3fastmem_size != 0 && (p->z3fastmem_size < 0x100000 || p->z3fastmem_size > 0x10000000))) + { + p->z3fastmem_size = 0; + write_log ("Unsupported Zorro III fastmem size!\n"); + err = 1; + } + if (p->address_space_24 && (p->gfxmem_size != 0 || p->z3fastmem_size != 0)) { + p->z3fastmem_size = p->gfxmem_size = 0; + write_log ("Can't use a graphics card or Zorro III fastmem when using a 24 bit\n" + "address space - sorry.\n"); + } + if ((p->bogomem_size & (p->bogomem_size - 1)) != 0 + || (p->bogomem_size != 0 && (p->bogomem_size < 0x80000 || p->bogomem_size > 0x100000))) { - strcpy(optionsfile, home); - strcat(optionsfile, "/"); + p->bogomem_size = 0; + write_log ("Unsupported bogomem size!\n"); + err = 1; + } + + if (p->chipmem_size > 0x200000 && p->fastmem_size != 0) { + write_log ("You can't use fastmem and more than 2MB chip at the same time!\n"); + p->fastmem_size = 0; + err = 1; + } +#if 0 + if (p->m68k_speed < -1 || p->m68k_speed > 20) { + write_log ("Bad value for -w parameter: must be -1, 0, or within 1..20.\n"); + p->m68k_speed = 4; + err = 1; } #endif -#ifndef __DOS__ - strcat(optionsfile, ".uaerc"); -#else - strcat(optionsfile, "uae.rc"); + if (p->produce_sound < 0 || p->produce_sound > 3) { + write_log ("Bad value for -S parameter: enable value must be within 0..3\n"); + p->produce_sound = 0; + err = 1; + } + if (p->cpu_model < 68020 && p->z3fastmem_size > 0) { + write_log ("Z3 fast memory can't be used with a 68000/68010 emulation. It\n" + "requires a 68020 emulation. Turning off Z3 fast memory.\n"); + p->z3fastmem_size = 0; + err = 1; + } + if (p->gfxmem_size > 0 && (p->cpu_model < 68020 || p->address_space_24)) { + write_log ("Picasso96 can't be used with a 68000/68010 or 68EC020 emulation. It\n" + "requires a 68020 emulation. Turning off Picasso96.\n"); + p->gfxmem_size = 0; + err = 1; + } +#ifndef BSDSOCKET + if (p->socket_emu) { + write_log ("Compile-time option of BSDSOCKET_SUPPORTED was not enabled. You can't use bsd-socket emulation.\n"); + p->socket_emu = 0; + err = 1; + } #endif - f = fopen(optionsfile,"r"); - if (f == NULL) { - parse_cmdline(argc, argv); - return; + if (p->nr_floppies < 1 || p->nr_floppies > 4) { + write_log ("Invalid number of floppies. Using 4.\n"); + p->nr_floppies = 4; + err = 1; } - fseek(f, 0, SEEK_END); - bufsiz = ftell(f); - fseek(f, 0, SEEK_SET); - - 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); - return; + if (p->collision_level < 0 || p->collision_level > 3) { + write_log ("Invalid collision support level. Using 1.\n"); + p->collision_level = 1; + err = 1; } - fclose(f); -#ifdef __DOS__ - { - char *tmp; + fixup_sound (p); + + if (err) + write_log ("Please use \"uae -h\" to get usage information.\n"); +} + +int quit_program = 0; + +void uae_reset (int hardreset) +{ + if (quit_program == 0) { + quit_program = -2; + if (hardreset) + quit_program = -3; + } +} + +void uae_quit (void) +{ + if (quit_program != -1) + quit_program = -1; +} - while ((tmp = strchr(buffer, 0x0d))) - *tmp = ' '; - while ((tmp = strchr(buffer, 0x0a))) - *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); +#ifndef DONT_PARSE_CMDLINE + +void usage (void) +{ +} + +void parse_cmdline (int argc, char **argv) +{ + int i; + for (i = 1; i < argc; i++) { + if (strncmp (argv[i], "-config=", 8) == 0) + cfgfile_load (&currprefs, argv[i] + 8); + /* Check for new-style "-f xxx" argument, where xxx is config-file */ + else if (strcmp (argv[i], "-f") == 0) { + if (i + 1 == argc) + write_log ("Missing argument for '-f' option.\n"); + else + cfgfile_load (&currprefs, argv[++i]); + } else if (strcmp (argv[i], "-s") == 0) { + if (i + 1 == argc) + write_log ("Missing argument for '-s' option.\n"); + else + cfgfile_parse_line (&currprefs, argv[++i]); + } else if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "-help") == 0) { + usage (); + exit (0); + } else { + if (argv[i][0] == '-' && argv[i][1] != '\0') { + const char *arg = argv[i] + 2; + int extra_arg = *arg == '\0'; + if (extra_arg) + arg = i + 1 < argc ? argv[i + 1] : 0; + if (parse_cmdline_option (&currprefs, argv[i][1], arg) && extra_arg) + i++; + } + } } +} #endif - tmpbuf = my_strdup (buffer); +static void parse_cmdline_and_init_file (int argc, char **argv) +{ + char *home; - n_args = 0; - if (strtok(tmpbuf, "\n ") != NULL) { - do { - n_args++; - } while (strtok(NULL, "\n ") != NULL); + strcpy (optionsfile, ""); + +#ifdef OPTIONS_IN_HOME + home = getenv ("HOME"); + if (home != NULL && strlen (home) < 240) + { + strcpy (optionsfile, home); + strcat (optionsfile, "/"); } - free (tmpbuf); +#endif - new_argv = (char **)malloc ((1 + n_args + argc) * sizeof (char **)); - new_argv[0] = argv[0]; - new_argc = 1; + strcat (optionsfile, OPTIONSFILENAME); - token = strtok(buffer, "\n "); - while (token != NULL) { - new_argv[new_argc] = my_strdup (token); - new_argc++; - token = strtok(NULL, "\n "); + if (! cfgfile_load (&currprefs, optionsfile)) { +#ifdef OPTIONS_IN_HOME + /* If not found in $HOME then look in current directory. However, + * don't use the optionsfile variable, so that we will save changes + * to the home directory. */ + char pwd_optionsfile[256]; + strcpy (optionsfile, OPTIONSFILENAME); + cfgfile_load (&currprefs, optionsfile); +#endif } - for (n_args = 1; n_args < argc; n_args++) - new_argv[new_argc++] = argv[n_args]; - new_argv[new_argc] = NULL; - parse_cmdline(new_argc, new_argv); + + parse_cmdline (argc, argv); +} + +void reset_all_systems (void) +{ + init_eventtab (); + + memory_reset (); + bsdlib_reset (); + filesys_reset (); + filesys_start_threads (); + scsidev_reset (); + scsidev_start_threads (); +} + +/* 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 + * as real_main(). Some OSes don't call main() (which is braindamaged IMHO, + * but unfortunately very common), so you need to call real_main() from + * whatever entry point you have. You may want to write your own versions + * of start_program() and leave_program() if you need to do anything special. + * Add #ifdefs around these as appropriate. + */ + +void do_start_program (void) +{ + if (quit_program == -1) + return; + inputdevice_updateconfig (&currprefs); + + /* Do a reset on startup. Whether this is elegant is debatable. */ + if (quit_program >= 0) + quit_program = 2; + m68k_go (1); +} + +void do_leave_program (void) +{ + graphics_leave (); + inputdevice_close (); + close_sound (); + dump_counts (); + serial_exit (); + zfile_exit (); + if (! no_gui) + gui_exit (); +#ifdef USE_SDL + SDL_Quit (); +#endif + expansion_cleanup (); + memory_cleanup (); } -static int ARE_YOU_NUTS = 0; +void start_program (void) +{ + do_start_program (); +} -int main(int argc, char **argv) +void leave_program (void) +{ + do_leave_program (); +} + +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); +#ifdef USE_SDL + SDL_Init (SDL_INIT_EVERYTHING | SDL_INIT_NOPARACHUTE); +#endif + + default_prefs (&currprefs); + +#ifdef SYSTEM_CFGDIR + scan_configs (SYSTEM_CFGDIR); +#endif + + /* Can be overriden in graphics_setup, although there's not much of a + point. Fullscreen modes are filled in by graphics_setup. */ + gfx_windowed_modes = default_windowed_modes; + n_windowed_modes = sizeof default_windowed_modes / sizeof *default_windowed_modes; + + if (! graphics_setup ()) { + exit (1); } + rtarea_init (); hardfile_install (); + scsidev_install (); + + parse_cmdline_and_init_file (argc, argv); + + machdep_init (); + init_gtod (); - parse_cmdline_and_init_file(argc, argv); - if (!init_sound()) { - fprintf(stderr, "Sound driver unavailable: Sound output disabled\n"); - produce_sound = 0; + if (! setup_sound ()) { + write_log ("Sound driver unavailable: Sound output disabled\n"); + currprefs.produce_sound = 0; + } + inputdevice_init (); + + changed_prefs = currprefs; + no_gui = ! currprefs.start_gui; + if (! no_gui) { + int err = gui_init (1); + currprefs = changed_prefs; + if (err == -1) { + write_log ("Failed to initialize the GUI\n"); + } else if (err == -2) { + exit (0); + } + } + if (sound_available && currprefs.produce_sound > 1 && ! init_audio ()) { + write_log ("Sound driver unavailable: Sound output disabled\n"); + currprefs.produce_sound = 0; } - if (!no_gui && gui_init() < 0) { - fprintf(stderr, "Failed to initialize the GUI\n"); - /* abort()? Maybe. */ - } - init_joystick(); - keybuf_init(); - + fixup_prefs (&currprefs); + changed_prefs = currprefs; + +#ifdef SYSTEM_ROMDIR + scan_roms (SYSTEM_ROMDIR, ROMLOC_SYSTEM); +#endif + scan_roms (currprefs.path_rom, ROMLOC_USER); + /* Install resident module to get 8MB chipmem, if requested */ + rtarea_setup (); + + keybuf_init (); /* Must come after init_joystick */ + expansion_init (); - memory_init(); + memory_init (); + + filesys_install (); + bsdlib_install (); + emulib_install (); + uaeexe_install (); + native2amiga_install (); + + custom_init (); /* Must come after memory_init */ + serial_init (); + DISK_init (); - filesys_install(); - execlib_install(); - gfxlib_install(); - emulib_install(); - - custom_init(); - serial_init(); - DISK_init(); - init_m68k(); - compiler_init(); - - /* We ought to know this by now */ - use_lores = screen_res < 3; - - if (graphics_init()) { - m68k_reset(); - - setup_brkhandler(); - if (use_debugger && debuggable()) - activate_debugger(); - if (ARE_YOU_NUTS) - execlib_sysinit(); - else - m68k_go(1); - - graphics_leave(); - close_joystick(); - } - dump_counts(); - serial_exit(); - zfile_exit(); - if (!no_gui) - gui_exit(); + reset_frame_rate_hack (); + init_m68k(); /* must come after reset_frame_rate_hack (); */ + + gui_update (); + + if (graphics_init ()) { + reset_drawing (); + setup_brkhandler (); + if (currprefs.start_debugger && debuggable ()) + activate_debugger (); + + start_program (); + } + leave_program (); +} + +void uae_abort (const char *msg) +{ + write_log ("%s", msg); + abort (); +} + +#ifndef NO_MAIN_IN_MAIN_C +int main (int argc, char **argv) +{ + real_main (argc, argv); return 0; } -#endif /* not __bebox__ */ +#endif