Annotation of uae/src/main.c, revision 1.1.1.7

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':
1.1.1.7 ! root      311:            cfgfile_parse_line (&currprefs, optarg);
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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.