Annotation of uae/src/cfgfile.c, revision 1.1.1.20

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Config file handling
                      5:   * This still needs some thought before it's complete...
                      6:   *
                      7:   * Copyright 1998 Brian King, Bernd Schmidt
                      8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: 
                     13: #include <ctype.h>
                     14: 
                     15: #include "options.h"
1.1.1.10  root       16: #include "threaddep/thread.h"
1.1       root       17: #include "uae.h"
                     18: #include "autoconf.h"
1.1.1.18  root       19: #include "filesys.h"
1.1.1.8   root       20: #include "events.h"
1.1.1.3   root       21: #include "custom.h"
1.1.1.18  root       22: #include "audio.h"
1.1.1.16  root       23: #include "inputdevice.h"
1.1.1.18  root       24: #include "romlist.h"
                     25: #include "gui.h"
1.1.1.16  root       26: 
                     27: #define cfgfile_write fprintf
1.1       root       28: 
1.1.1.20! root       29: static int config_newfilesystem;
        !            30: 
1.1       root       31: /* @@@ need to get rid of this... just cut part of the manual and print that
                     32:  * as a help text.  */
                     33: struct cfg_lines
                     34: {
                     35:     const char *config_label, *config_help;
                     36: };
                     37: 
                     38: static struct cfg_lines opttable[] =
                     39: {
                     40:     {"help", "Prints this help" },
                     41:     {"config_description", "" },
                     42:     {"use_gui", "Enable the GUI?  If no, then goes straight to emulator" },
                     43:     {"use_debugger", "Enable the debugger?" },
                     44:     {"cpu_speed", "can be max, real, or a number between 1 and 20" },
                     45:     {"cpu_type", "Can be 68000, 68010, 68020, 68020/68881" },
                     46:     {"cpu_24bit_addressing", "must be set to 'no' in order for Z3mem or P96mem to work" },
                     47:     {"log_illegal_mem", "print illegal memory access by Amiga software?" },
                     48:     {"fastmem_size", "Size in megabytes of fast-memory" },
                     49:     {"chipmem_size", "Size in megabytes of chip-memory" },
                     50:     {"bogomem_size", "Size in megabytes of bogo-memory at 0xC00000" },
                     51:     {"a3000mem_size", "Size in megabytes of A3000 memory" },
                     52:     {"gfxcard_size", "Size in megabytes of Picasso96 graphics-card memory" },
                     53:     {"z3mem_size", "Size in megabytes of Zorro-III expansion memory" },
                     54:     {"gfx_test_speed", "Test graphics speed?" },
                     55:     {"framerate", "Print every nth frame" },
                     56:     {"gfx_width", "Screen width" },
                     57:     {"gfx_height", "Screen height" },
                     58:     {"gfx_lores", "Treat display as lo-res?" },
                     59:     {"gfx_linemode", "Can be none, double, or scanlines" },
                     60:     {"gfx_fullscreen_amiga", "Amiga screens are fullscreen?" },
                     61:     {"gfx_fullscreen_picasso", "Picasso screens are fullscreen?" },
                     62:     {"gfx_correct_aspect", "Correct aspect ratio?" },
                     63:     {"gfx_center_horizontal", "Center display horizontally?" },
                     64:     {"gfx_center_vertical", "Center display vertically?" },
                     65:     {"gfx_colour_mode", "" },
                     66:     {"32bit_blits", "Enable 32 bit blitter emulation" },
                     67:     {"immediate_blits", "Perform blits immediately" },
1.1.1.15  root       68:     {"show_leds", "LED display" },
1.1       root       69:     {"sound_output", "" },
                     70:     {"sound_frequency", "" },
                     71:     {"sound_channels", "" },
                     72:     {"sound_max_buff", "" },
                     73:     {"parallel_on_demand", "" },
                     74:     {"serial_on_demand", "" },
                     75:     {"joyport0", "" },
                     76:     {"joyport1", "" },
                     77:     {"kickstart_rom_file", "Kickstart ROM image, (C) Copyright Amiga, Inc." },
1.1.1.12  root       78:     {"kickstart_ext_rom_file", "Extended Kickstart ROM image, (C) Copyright Amiga, Inc." },
1.1       root       79:     {"kickstart_key_file", "Key-file for encrypted ROM images (from Cloanto's Amiga Forever)" },
                     80:     {"floppy0", "Diskfile for drive 0" },
                     81:     {"floppy1", "Diskfile for drive 1" },
                     82:     {"floppy2", "Diskfile for drive 2" },
                     83:     {"floppy3", "Diskfile for drive 3" },
                     84:     {"hardfile", "access,sectors, surfaces, reserved, blocksize, path format" },
                     85:     {"filesystem", "access,'Amiga volume-name':'host directory path' - where 'access' can be 'read-only' or 'read-write'" }
                     86: };
                     87: 
1.1.1.10  root       88: static const char *guimode1[] = { "no", "yes", "nowait", 0 };
                     89: static const char *guimode2[] = { "false", "true", "nowait", 0 };
                     90: static const char *guimode3[] = { "0", "1", "nowait", 0 };
                     91: static const char *csmode[] = { "ocs", "ecs_agnus", "ecs_denise", "ecs", "aga", 0 };
1.1       root       92: static const char *linemode1[] = { "none", "double", "scanlines", 0 };
                     93: static const char *linemode2[] = { "n", "d", "s", 0 };
                     94: static const char *speedmode[] = { "max", "real", 0 };
1.1.1.7   root       95: static const char *cpumode[] = {
1.1.1.18  root       96:     "68000", "68010",
                     97:     "68ec020", "68ec020/68881", "68ec020/68882",
                     98:     "68020", "68020/68881", "68020/68882",
                     99:     "68030", "68030/68881", "68030/68882",
                    100:     "68040", "68060", 0
                    101: };
                    102: static int mode_to_cpumodel[] = {
                    103:     68000, 68010,
                    104:     68020, 68020, 68020,
                    105:     68020, 68020, 68020,
                    106:     68030, 68030, 68030,
                    107:     68040, 68060
                    108: };
                    109: static int mode_to_fpumodel[] = {
                    110:     0, 0,
                    111:     0, 68881, 68882,
                    112:     0, 68881, 68882,
                    113:     0, 68881, 68882,
                    114:     68040, 68060
1.1.1.7   root      115: };
1.1       root      116: static const char *colormode1[] = { "8bit", "15bit", "16bit", "8bit_dither", "4bit_dither", "32bit", 0 };
                    117: static const char *colormode2[] = { "8", "15", "16", "8d", "4d", "32", 0 };
                    118: static const char *soundmode[] = { "none", "interrupts", "normal", "exact", 0 };
1.1.1.2   root      119: static const char *centermode1[] = { "none", "simple", "smart", 0 };
                    120: static const char *centermode2[] = { "false", "true", "smart", 0 };
1.1.1.18  root      121: static const char *stereomode[] = { "mono", "stereo", "mixed", 0 };
1.1.1.19  root      122: static const char *interpolmode[] = { "none", "sinc", "anti", 0 };
1.1.1.18  root      123: static const char *soundfiltermode1[] = { "off", "emulated", "on", 0 };
                    124: static const char *soundfiltermode2[] = { "standard", "enhanced", 0 };
1.1.1.9   root      125: static const char *collmode[] = { "none", "sprites", "playfields", "full", 0 };
1.1.1.18  root      126: static const char *idemode[] = { "none", "a600/a1200", "a4000", 0 };
                    127: 
                    128: static const char *obsolete[] = {
                    129:     "accuracy", "gfx_opengl", "gfx_32bit_blits", "32bit_blits",
                    130:     "gfx_immediate_blits", "gfx_ntsc", "win32", "gfx_filter_bits",
                    131:     "sound_pri_cutoff", "sound_pri_time", "sound_min_buff", "sound_bits",
                    132:     "gfx_test_speed", "gfxlib_replacement", "enforcer", "catweasel_io",
                    133:     "fast_copper", "sound_adjust", "serial_hardware_dtrdsr", "cpu_compatible",
                    134:     0
                    135: };
1.1       root      136: 
                    137: #define UNEXPANDED "$(FILE_PATH)"
                    138: 
                    139: static int match_string (const char *table[], const char *str)
                    140: {
                    141:     int i;
                    142:     for (i = 0; table[i] != 0; i++)
                    143:        if (strcasecmp (table[i], str) == 0)
                    144:            return i;
                    145:     return -1;
                    146: }
                    147: 
                    148: char *cfgfile_subst_path (const char *path, const char *subst, const char *file)
                    149: {
                    150:     /* @@@ use strcasecmp for some targets.  */
                    151:     if (strlen (path) > 0 && strncmp (file, path, strlen (path)) == 0) {
                    152:        int l;
                    153:        char *p = xmalloc (strlen (file) + strlen (subst) + 2);
                    154:        strcpy (p, subst);
                    155:        l = strlen (p);
                    156:        while (l > 0 && p[l - 1] == '/')
                    157:            p[--l] = '\0';
                    158:        l = strlen (path);
                    159:        while (file[l] == '/')
                    160:            l++;
                    161:        strcat (p, "/"); strcat (p, file + l);
                    162:        return p;
                    163:     }
                    164:     return my_strdup (file);
                    165: }
                    166: 
1.1.1.18  root      167: static void write_gfx_params (FILE *f, const struct gfx_params *p, const char *suffix)
1.1.1.17  root      168: {
                    169:     cfgfile_write (f, "gfx_width_%s=%d\n", suffix, p->width);
                    170:     cfgfile_write (f, "gfx_height_%s=%d\n", suffix, p->height);
                    171:     cfgfile_write (f, "gfx_lores_%s=%s\n", suffix, p->lores ? "true" : "false");
                    172:     cfgfile_write (f, "gfx_linemode_%s=%s\n", suffix, linemode1[p->linedbl]);
                    173:     cfgfile_write (f, "gfx_correct_aspect_%s=%s\n", suffix, p->correct_aspect ? "true" : "false");
                    174:     cfgfile_write (f, "gfx_center_horizontal_%s=%s\n", suffix, centermode1[p->xcenter]);
                    175:     cfgfile_write (f, "gfx_center_vertical_%s=%s\n", suffix, centermode1[p->ycenter]);
1.1.1.18  root      176:     cfgfile_write (f, "gfx_show_leds_%s=%s\n", suffix, p->leds_on_screen ? "true" : "false");
1.1.1.17  root      177: }
                    178: 
1.1.1.18  root      179: void save_options (FILE *f, const struct uae_prefs *p)
1.1       root      180: {
                    181:     struct strlist *sl;
                    182:     char *str;
                    183:     int i;
                    184: 
1.1.1.16  root      185:     cfgfile_write (f, "config_description=%s\n", p->description);
1.1       root      186: 
                    187:     for (sl = p->unknown_lines; sl; sl = sl->next)
1.1.1.16  root      188:        cfgfile_write (f, "%s\n", sl->str);
1.1       root      189: 
1.1.1.16  root      190:     cfgfile_write (f, "%s.rom_path=%s\n", TARGET_NAME, p->path_rom);
                    191:     cfgfile_write (f, "%s.floppy_path=%s\n", TARGET_NAME, p->path_floppy);
                    192:     cfgfile_write (f, "%s.hardfile_path=%s\n", TARGET_NAME, p->path_hardfile);
1.1       root      193: 
1.1.1.2   root      194:     target_save_options (f, p);
                    195: 
1.1.1.16  root      196:     cfgfile_write (f, "use_gui=%s\n", guimode1[p->start_gui]);
                    197:     cfgfile_write (f, "use_debugger=%s\n", p->start_debugger ? "true" : "false");
1.1       root      198:     str = cfgfile_subst_path (p->path_rom, UNEXPANDED, p->romfile);
1.1.1.16  root      199:     cfgfile_write (f, "kickstart_rom_file=%s\n", str);
1.1       root      200:     free (str);
1.1.1.18  root      201:     if (currprefs.rom_crc32)
                    202:        cfgfile_write (f, "kickstart_rom_crc=0x%x\n", currprefs.rom_crc32);
1.1.1.12  root      203:     str = cfgfile_subst_path (p->path_rom, UNEXPANDED, p->romextfile);
1.1.1.16  root      204:     cfgfile_write (f, "kickstart_ext_rom_file=%s\n", str);
1.1.1.12  root      205:     free (str);
1.1       root      206:     str = cfgfile_subst_path (p->path_rom, UNEXPANDED, p->keyfile);
1.1.1.16  root      207:     cfgfile_write (f, "kickstart_key_file=%s\n", str);
1.1       root      208:     free (str);
1.1.1.16  root      209:     cfgfile_write (f, "kickshifter=%s\n", p->kickshifter ? "true" : "false");
1.1       root      210: 
                    211:     for (i = 0; i < 4; i++) {
                    212:        str = cfgfile_subst_path (p->path_floppy, UNEXPANDED, p->df[i]);
1.1.1.16  root      213:        cfgfile_write (f, "floppy%d=%s\n", i, str);
1.1       root      214:        free (str);
1.1.1.18  root      215:        cfgfile_write (f, "floppy%dtype=%d\n", i, p->dfxtype[i]);
1.1       root      216:     }
1.1.1.16  root      217:     cfgfile_write (f, "nr_floppies=%d\n", p->nr_floppies);
                    218:     cfgfile_write (f, "parallel_on_demand=%s\n", p->parallel_demand ? "true" : "false");
                    219:     cfgfile_write (f, "serial_on_demand=%s\n", p->serial_demand ? "true" : "false");
                    220: 
                    221:     cfgfile_write (f, "sound_output=%s\n", soundmode[p->produce_sound]);
1.1.1.18  root      222:     cfgfile_write (f, "sound_channels=%s\n", stereomode[p->sound_stereo]);
                    223:     cfgfile_write (f, "sound_stereo_separation=%d\n", p->sound_stereo_separation);
                    224:     cfgfile_write (f, "sound_stereo_mixing_delay=%d\n", p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0);
1.1.1.16  root      225:     cfgfile_write (f, "sound_max_buff=%d\n", p->sound_maxbsiz);
                    226:     cfgfile_write (f, "sound_frequency=%d\n", p->sound_freq);
                    227:     cfgfile_write (f, "sound_interpol=%s\n", interpolmode[p->sound_interpol]);
1.1.1.18  root      228:     cfgfile_write (f, "sound_filter=%s\n", soundfiltermode1[p->sound_filter]);
                    229:     cfgfile_write (f, "sound_filter_type=%s\n", soundfiltermode2[p->sound_filter_type]);
1.1.1.16  root      230: 
                    231:     for (i = 0; i < 2; i++) {
                    232:        int v = i == 0 ? p->jport0 : p->jport1;
                    233:        char tmp1[100], tmp2[50];
                    234:        if (v < JSEM_JOYS) {
                    235:            sprintf (tmp2, "kbd%d", v + 1);
                    236:        } else if (v < JSEM_MICE) {
                    237:            sprintf (tmp2, "joy%d", v - JSEM_JOYS);
                    238:        } else {
                    239:            strcpy (tmp2, "mouse");
                    240:            if (v - JSEM_MICE > 0)
                    241:                sprintf (tmp2, "mouse%d", v - JSEM_MICE);
                    242:        }
                    243:        sprintf (tmp1, "joyport%d=%s\n", i, tmp2);
                    244:        cfgfile_write (f, tmp1);
                    245:     }
                    246: 
                    247:     cfgfile_write (f, "bsdsocket_emu=%s\n", p->socket_emu ? "true" : "false");
                    248: 
                    249:     cfgfile_write (f, "gfx_framerate=%d\n", p->gfx_framerate);
1.1.1.17  root      250:     write_gfx_params (f, &p->gfx_w, "windowed");
                    251:     write_gfx_params (f, &p->gfx_f, "fullscreen");
1.1.1.16  root      252:     cfgfile_write (f, "gfx_fullscreen_amiga=%s\n", p->gfx_afullscreen ? "true" : "false");
                    253:     cfgfile_write (f, "gfx_fullscreen_picasso=%s\n", p->gfx_pfullscreen ? "true" : "false");
                    254:     cfgfile_write (f, "gfx_colour_mode=%s\n", colormode1[p->color_mode]);
                    255: 
                    256:     cfgfile_write (f, "immediate_blits=%s\n", p->immediate_blits ? "true" : "false");
                    257:     cfgfile_write (f, "ntsc=%s\n", p->ntscmode ? "true" : "false");
1.1.1.3   root      258:     if (p->chipset_mask & CSMASK_AGA)
1.1.1.16  root      259:        cfgfile_write (f, "chipset=aga\n");
1.1.1.3   root      260:     else if ((p->chipset_mask & CSMASK_ECS_AGNUS) && (p->chipset_mask & CSMASK_ECS_AGNUS))
1.1.1.16  root      261:        cfgfile_write (f, "chipset=ecs\n");
1.1.1.3   root      262:     else if (p->chipset_mask & CSMASK_ECS_AGNUS)
1.1.1.16  root      263:        cfgfile_write (f, "chipset=ecs_agnus\n");
1.1.1.3   root      264:     else if (p->chipset_mask & CSMASK_ECS_DENISE)
1.1.1.16  root      265:        cfgfile_write (f, "chipset=ecs_denise\n");
1.1.1.3   root      266:     else
1.1.1.16  root      267:        cfgfile_write (f, "chipset=ocs\n");
                    268:     cfgfile_write (f, "collision_level=%s\n", collmode[p->collision_level]);
1.1       root      269: 
1.1.1.18  root      270:     cfgfile_write (f, "ide=%s\n", p->cs_ide == 1 ? "a600/a1200" : (p->cs_ide == 2 ? "a4000" : "none"));
                    271:     cfgfile_write (f, "a1000ram=%s\n", p->cs_a1000ram ? "true" : "false");
                    272:     cfgfile_write (f, "fatgary=%d\n", p->cs_fatgaryrev);
                    273:     cfgfile_write (f, "ramsey=%d\n", p->cs_ramseyrev);
                    274: 
1.1.1.16  root      275:     cfgfile_write (f, "fastmem_size=%d\n", p->fastmem_size / 0x100000);
1.1.1.18  root      276:     cfgfile_write (f, "a3000mem_size=%d\n", p->mbresmem_low_size / 0x100000);
                    277:     cfgfile_write (f, "mbresmem_size=%d\n", p->mbresmem_high_size / 0x100000);
1.1.1.16  root      278:     cfgfile_write (f, "z3mem_size=%d\n", p->z3fastmem_size / 0x100000);
                    279:     cfgfile_write (f, "bogomem_size=%d\n", p->bogomem_size / 0x40000);
                    280:     cfgfile_write (f, "gfxcard_size=%d\n", p->gfxmem_size / 0x100000);
                    281:     cfgfile_write (f, "chipmem_size=%d\n", p->chipmem_size / 0x80000);
1.1       root      282: 
1.1.1.3   root      283:     if (p->m68k_speed > 0)
1.1.1.16  root      284:        cfgfile_write (f, "finegrain_cpu_speed=%d\n", p->m68k_speed);
1.1       root      285:     else
1.1.1.16  root      286:        cfgfile_write (f, "cpu_speed=%s\n", p->m68k_speed == -1 ? "max" : "real");
1.1       root      287: 
1.1.1.18  root      288:     for (i = 0; cpumode[i] != NULL; i++)
                    289:        if (mode_to_cpumodel[i] == p->cpu_model && mode_to_fpumodel[i] == p->fpu_model) {
                    290:            cfgfile_write (f, "cpu_type=%s\n", cpumode[i]);
                    291:            break;
                    292:        }
1.1       root      293: 
1.1.1.16  root      294:     cfgfile_write (f, "log_illegal_mem=%s\n", p->illegal_mem ? "true" : "false");
1.1       root      295: 
1.1.1.16  root      296:     cfgfile_write (f, "kbd_lang=%s\n", (p->keyboard_lang == KBD_LANG_DE ? "de"
1.1.1.18  root      297:                                        : p->keyboard_lang == KBD_LANG_DK ? "dk"
                    298:                                        : p->keyboard_lang == KBD_LANG_ES ? "es"
                    299:                                        : p->keyboard_lang == KBD_LANG_US ? "us"
                    300:                                        : p->keyboard_lang == KBD_LANG_SE ? "se"
                    301:                                        : p->keyboard_lang == KBD_LANG_FR ? "fr"
                    302:                                        : p->keyboard_lang == KBD_LANG_IT ? "it"
                    303:                                        : "FOO"));
1.1       root      304: 
                    305:     write_filesys_config (p->mountinfo, UNEXPANDED, p->path_hardfile, f);
                    306: 
                    307:     /* Don't write gfxlib/gfx_test_speed options.  */
                    308: }
                    309: 
1.1.1.18  root      310: int cfgfile_yesno (const char *option, const char *value, const char *name, int *location)
1.1       root      311: {
                    312:     if (strcmp (option, name) != 0)
                    313:        return 0;
                    314:     if (strcasecmp (value, "yes") == 0 || strcasecmp (value, "y") == 0
                    315:        || strcasecmp (value, "true") == 0 || strcasecmp (value, "t") == 0)
                    316:        *location = 1;
                    317:     else if (strcasecmp (value, "no") == 0 || strcasecmp (value, "n") == 0
                    318:        || strcasecmp (value, "false") == 0 || strcasecmp (value, "f") == 0)
                    319:        *location = 0;
                    320:     else
                    321:        write_log ("Option `%s' requires a value of either `yes' or `no'.\n", option);
                    322:     return 1;
                    323: }
                    324: 
1.1.1.18  root      325: int cfgfile_intval (const char *option, const char *value, const char *name, int *location, int scale)
1.1       root      326: {
                    327:     int base = 10;
                    328:     char *endptr;
                    329:     if (strcmp (option, name) != 0)
                    330:        return 0;
                    331:     if (value[0] == '0' && value[1] == 'x')
1.1.1.18  root      332:        base = 16;
1.1       root      333:     *location = strtol (value, &endptr, base) * scale;
                    334: 
                    335:     if (*endptr != '\0' || *value == '\0')
                    336:        write_log ("Option `%s' requires a numeric argument.\n", option);
                    337:     return 1;
                    338: }
                    339: 
1.1.1.18  root      340: int cfgfile_uintval (const char *option, const char *value, const char *name, unsigned int *location, int scale)
                    341: {
                    342:     int base = 10;
                    343:     char *endptr;
                    344:     if (strcmp (option, name) != 0)
                    345:        return 0;
                    346:     if (value[0] == '0' && value[1] == 'x')
                    347:        base = 16;
                    348:     *location = strtoul (value, &endptr, base) * scale;
                    349: 
                    350:     if (*endptr != '\0' || *value == '\0')
                    351:        write_log ("Option `%s' requires a numeric argument.\n", option);
                    352:     return 1;
                    353: }
                    354: 
                    355: int cfgfile_strval (const char *option, const char *value, const char *name, int *location, const char *table[], int more)
1.1       root      356: {
                    357:     int val;
                    358:     if (strcmp (option, name) != 0)
                    359:        return 0;
                    360:     val = match_string (table, value);
                    361:     if (val == -1) {
1.1.1.6   root      362:        if (more)
                    363:            return 0;
                    364: 
                    365:        write_log ("Unknown value for option `%s'.\n", option);
1.1       root      366:        return 1;
                    367:     }
                    368:     *location = val;
                    369:     return 1;
                    370: }
                    371: 
1.1.1.18  root      372: int cfgfile_string (const char *option, const char *value, const char *name, char *location, int maxsz)
1.1       root      373: {
                    374:     if (strcmp (option, name) != 0)
                    375:        return 0;
                    376:     strncpy (location, value, maxsz - 1);
                    377:     location[maxsz - 1] = '\0';
                    378:     return 1;
                    379: }
                    380: 
                    381: static int getintval (char **p, int *result, int delim)
                    382: {
                    383:     char *value = *p;
                    384:     int base = 10;
                    385:     char *endptr;
                    386:     char *p2 = strchr (*p, delim);
                    387: 
                    388:     if (p2 == 0)
                    389:        return 0;
                    390: 
                    391:     *p2++ = '\0';
                    392: 
                    393:     if (value[0] == '0' && value[1] == 'x')
                    394:        value += 2, base = 16;
                    395:     *result = strtol (value, &endptr, base);
                    396:     *p = p2;
                    397: 
                    398:     if (*endptr != '\0' || *value == '\0')
                    399:        return 0;
                    400: 
                    401:     return 1;
                    402: }
                    403: 
1.1.1.20! root      404: static int getintval2 (char **p, int *result, int delim)
        !           405: {
        !           406:     char *value = *p;
        !           407:     int base = 10;
        !           408:     char *endptr;
        !           409:     char *p2 = strchr (*p, delim);
        !           410: 
        !           411:     if (p2 == 0) {
        !           412:        p2 = strchr (*p, 0);
        !           413:        if (p2 == 0) {
        !           414:            *p = 0;
        !           415:            return 0;
        !           416:        }
        !           417:     }
        !           418:     if (*p2 != 0)
        !           419:        *p2++ = '\0';
        !           420: 
        !           421:     if (value[0] == '0' && value[1] == 'x')
        !           422:        value += 2, base = 16;
        !           423:     *result = strtol (value, &endptr, base);
        !           424:     *p = p2;
        !           425: 
        !           426:     if (*endptr != '\0' || *value == '\0') {
        !           427:        *p = 0;
        !           428:        return 0;
        !           429:     }
        !           430: 
        !           431:     return 1;
        !           432: }
        !           433: 
1.1.1.8   root      434: static void set_chipset_mask (struct uae_prefs *p, int val)
1.1.1.5   root      435: {
                    436:     p->chipset_mask = (val == 0 ? 0
                    437:                       : val == 1 ? CSMASK_ECS_AGNUS
                    438:                       : val == 2 ? CSMASK_ECS_DENISE
                    439:                       : val == 3 ? CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS
                    440:                       : CSMASK_AGA | CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS);
                    441: }
                    442: 
1.1.1.18  root      443: static int cfgfile_parse_host (struct uae_prefs *p, char *option, char *value)
1.1       root      444: {
1.1.1.3   root      445:     int tmpval;
1.1.1.9   root      446:     int dummy;
1.1       root      447:     char *section = 0;
                    448:     char *tmpp;
1.1.1.3   root      449: 
1.1.1.17  root      450:     if (memcmp (option, "input.", 6) == 0) {
                    451:        read_inputdevice_config (p, option, value);
                    452:        return 1;
                    453:     }
                    454: 
1.1       root      455:     for (tmpp = option; *tmpp != '\0'; tmpp++)
                    456:        if (isupper (*tmpp))
                    457:            *tmpp = tolower (*tmpp);
                    458:     tmpp = strchr (option, '.');
                    459:     if (tmpp) {
                    460:        section = option;
                    461:        option = tmpp + 1;
                    462:        *tmpp = '\0';
                    463:        if (strcmp (section, TARGET_NAME) == 0) {
                    464:            /* We special case the various path options here.  */
                    465:            if (cfgfile_string (option, value, "rom_path", p->path_rom, 256)
                    466:                || cfgfile_string (option, value, "floppy_path", p->path_floppy, 256)
                    467:                || cfgfile_string (option, value, "hardfile_path", p->path_hardfile, 256))
                    468:                return 1;
                    469:            return target_parse_option (p, option, value);
                    470:        }
                    471:        return 0;
                    472:     }
1.1.1.18  root      473: 
1.1       root      474:     if (cfgfile_yesno (option, value, "use_debugger", &p->start_debugger)
1.1.1.3   root      475:        || cfgfile_yesno (option, value, "bsdsocket_emu", &p->socket_emu)
1.1.1.18  root      476: 
1.1.1.17  root      477:        || (cfgfile_yesno (option, value, "gfx_lores", &p->gfx_w.lores)
                    478:            && cfgfile_yesno (option, value, "gfx_lores", &p->gfx_f.lores))
                    479:        || cfgfile_yesno (option, value, "gfx_lores_windowed", &p->gfx_w.lores)
                    480:        || cfgfile_yesno (option, value, "gfx_lores_fullscreen", &p->gfx_f.lores)
1.1.1.18  root      481: 
1.1.1.17  root      482:        || (cfgfile_yesno (option, value, "gfx_correct_aspect", &p->gfx_w.correct_aspect)
                    483:            && cfgfile_yesno (option, value, "gfx_correct_aspect", &p->gfx_f.correct_aspect))
                    484:        || cfgfile_yesno (option, value, "gfx_correct_aspect_windowed", &p->gfx_w.correct_aspect)
                    485:        || cfgfile_yesno (option, value, "gfx_correct_aspect_fullscreen", &p->gfx_f.correct_aspect)
1.1.1.18  root      486: 
                    487:        || (cfgfile_yesno (option, value, "show_leds", &p->gfx_w.leds_on_screen)
                    488:            && cfgfile_yesno (option, value, "show_leds", &p->gfx_f.leds_on_screen))
                    489:        || cfgfile_yesno (option, value, "gfx_show_leds_windowed", &p->gfx_w.leds_on_screen)
                    490:        || cfgfile_yesno (option, value, "gfx_show_leds_fullscreen", &p->gfx_f.leds_on_screen)
                    491: 
1.1       root      492:        || cfgfile_yesno (option, value, "gfx_fullscreen_amiga", &p->gfx_afullscreen)
                    493:        || cfgfile_yesno (option, value, "gfx_fullscreen_picasso", &p->gfx_pfullscreen)
                    494:        || cfgfile_yesno (option, value, "log_illegal_mem", &p->illegal_mem))
                    495:        return 1;
1.1.1.18  root      496:     if (cfgfile_intval (option, value, "sound_max_buff", &p->sound_maxbsiz, 1)
1.1       root      497:        || cfgfile_intval (option, value, "sound_frequency", &p->sound_freq, 1)
1.1.1.18  root      498:        || cfgfile_intval (option, value, "sound_stereo_separation", &p->sound_stereo_separation, 1)
                    499:        || cfgfile_intval (option, value, "sound_stereo_mixing_delay", &p->sound_mixed_stereo_delay, 1)
                    500: 
1.1.1.3   root      501:        || cfgfile_intval (option, value, "gfx_framerate", &p->gfx_framerate, 1)
1.1.1.17  root      502:        || (cfgfile_intval (option, value, "gfx_width", &p->gfx_w.width, 1)
                    503:            && cfgfile_intval (option, value, "gfx_width", &p->gfx_f.width, 1))
                    504:        || cfgfile_intval (option, value, "gfx_width_windowed", &p->gfx_w.width, 1)
                    505:        || cfgfile_intval (option, value, "gfx_width_fullscreen", &p->gfx_f.width, 1)
                    506:        || (cfgfile_intval (option, value, "gfx_height", &p->gfx_w.height, 1)
                    507:            && cfgfile_intval (option, value, "gfx_height", &p->gfx_f.height, 1))
                    508:        || cfgfile_intval (option, value, "gfx_height_windowed", &p->gfx_w.height, 1)
1.1.1.18  root      509:        || cfgfile_intval (option, value, "gfx_height_fullscreen", &p->gfx_f.height, 1))
1.1       root      510:        return 1;
                    511:     if (cfgfile_strval (option, value, "sound_output", &p->produce_sound, soundmode, 0)
1.1.1.4   root      512:        || cfgfile_strval (option, value, "sound_interpol", &p->sound_interpol, interpolmode, 0)
1.1.1.18  root      513:        || cfgfile_strval (option, value, "sound_filter", &p->sound_filter, soundfiltermode1, 0)
                    514:        || cfgfile_strval (option, value, "sound_filter_type", &p->sound_filter_type, soundfiltermode2, 0)
1.1.1.10  root      515:        || cfgfile_strval (option, value, "use_gui", &p->start_gui, guimode1, 1)
                    516:        || cfgfile_strval (option, value, "use_gui", &p->start_gui, guimode2, 1)
                    517:        || cfgfile_strval (option, value, "use_gui", &p->start_gui, guimode3, 0)
1.1.1.17  root      518:        || (cfgfile_strval (option, value, "gfx_linemode", &p->gfx_w.linedbl, linemode1, 1)
                    519:            && cfgfile_strval (option, value, "gfx_linemode", &p->gfx_f.linedbl, linemode1, 1))
                    520:        || (cfgfile_strval (option, value, "gfx_linemode", &p->gfx_w.linedbl, linemode2, 0)
                    521:            && cfgfile_strval (option, value, "gfx_linemode", &p->gfx_f.linedbl, linemode2, 0))
                    522:        || cfgfile_strval (option, value, "gfx_linemode_windowed", &p->gfx_w.linedbl, linemode1, 1)
                    523:        || cfgfile_strval (option, value, "gfx_linemode_windowed", &p->gfx_w.linedbl, linemode2, 0)
                    524:        || cfgfile_strval (option, value, "gfx_linemode_fullscreen", &p->gfx_f.linedbl, linemode1, 1)
                    525:        || cfgfile_strval (option, value, "gfx_linemode_fullscreen", &p->gfx_f.linedbl, linemode2, 0)
                    526:        || (cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_w.xcenter, centermode1, 1)
                    527:            && cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_f.xcenter, centermode1, 1))
                    528:        || (cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_w.xcenter, centermode2, 0)
                    529:            && cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_f.xcenter, centermode2, 0))
                    530:        || cfgfile_strval (option, value, "gfx_center_horizontal_windowed", &p->gfx_w.xcenter, centermode1, 1)
                    531:        || cfgfile_strval (option, value, "gfx_center_horizontal_windowed", &p->gfx_w.xcenter, centermode2, 0)
                    532:        || cfgfile_strval (option, value, "gfx_center_horizontal_fullscreen", &p->gfx_f.xcenter, centermode1, 1)
                    533:        || cfgfile_strval (option, value, "gfx_center_horizontal_fullscreen", &p->gfx_f.xcenter, centermode2, 0)
                    534:        || (cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_w.ycenter, centermode1, 1)
                    535:            && cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_f.ycenter, centermode1, 1))
                    536:        || (cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_w.ycenter, centermode2, 0)
                    537:            && cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_f.ycenter, centermode2, 0))
                    538:        || cfgfile_strval (option, value, "gfx_center_vertical_windowed", &p->gfx_w.ycenter, centermode1, 1)
                    539:        || cfgfile_strval (option, value, "gfx_center_vertical_windowed", &p->gfx_w.ycenter, centermode2, 0)
                    540:        || cfgfile_strval (option, value, "gfx_center_vertical_fullscreen", &p->gfx_f.ycenter, centermode1, 1)
                    541:        || cfgfile_strval (option, value, "gfx_center_vertical_fullscreen", &p->gfx_f.ycenter, centermode2, 0)
1.1       root      542:        || cfgfile_strval (option, value, "gfx_colour_mode", &p->color_mode, colormode1, 1)
                    543:        || cfgfile_strval (option, value, "gfx_colour_mode", &p->color_mode, colormode2, 0)
                    544:        || cfgfile_strval (option, value, "gfx_color_mode", &p->color_mode, colormode1, 1)
                    545:        || cfgfile_strval (option, value, "gfx_color_mode", &p->color_mode, colormode2, 0))
                    546:        return 1;
1.1.1.16  root      547: 
                    548:     if (strcmp (option, "joyport0") == 0 || strcmp (option, "joyport1") == 0) {
                    549:        int port = strcmp (option, "joyport0") == 0 ? 0 : 1;
                    550:        int start = -1;
                    551:        char *pp = 0;
                    552:        if (strncmp (value, "kbd", 3) == 0) {
                    553:            start = JSEM_KBDLAYOUT;
                    554:            pp = value + 3;
                    555:        } else if (strncmp (value, "joy", 3) == 0) {
                    556:            start = JSEM_JOYS;
                    557:            pp = value + 3;
                    558:        } else if (strncmp (value, "mouse", 5) == 0) {
                    559:            start = JSEM_MICE;
                    560:            pp = value + 5;
                    561:        }
                    562:        if (pp) {
                    563:            int v = atol (pp);
                    564:            if (start >= 0) {
                    565:                if (start == JSEM_KBDLAYOUT)
                    566:                    v--;
                    567:                if (v >= 0) {
                    568:                    start += v;
                    569:                    if (port)
                    570:                        p->jport1 = start;
                    571:                    else
                    572:                        p->jport0 = start;
                    573:                }
                    574:            }
                    575:        }
                    576:        return 1;
                    577:     }
                    578: 
1.1.1.18  root      579:     if (cfgfile_string (option, value, "config_description", p->description, 256)
                    580:        || cfgfile_string (option, value, "config_sortstr", p->sortstr, 256))
1.1       root      581:        return 1;
                    582: 
                    583:     /* Tricky ones... */
1.1.1.18  root      584:     if (cfgfile_strval (option, value, "sound_channels", &p->sound_stereo, stereomode, 1)) {
1.1.1.19  root      585:        if (p->sound_stereo == SND_MONO) {
                    586:            write_log ("Mono sound no longer supported, switching to stereo.\n");
                    587:            p->sound_stereo = SND_STEREO;
                    588:            p->sound_mixed_stereo_delay = 0;
                    589:            p->sound_stereo_separation = 15;
                    590:        }
1.1.1.18  root      591:        if (p->sound_stereo == SND_NONE) { /* "mixed stereo" compatibility hack */
                    592:            p->sound_stereo = SND_STEREO;
                    593:            p->sound_mixed_stereo_delay = 5;
                    594:            p->sound_stereo_separation = 7;
1.1.1.9   root      595:        }
1.1       root      596:        return 1;
1.1.1.9   root      597:     }
1.1       root      598: 
                    599:     if (strcmp (option, "kbd_lang") == 0) {
                    600:        KbdLang l;
                    601:        if ((l = KBD_LANG_DE, strcasecmp (value, "de") == 0)
1.1.1.9   root      602:            || (l = KBD_LANG_DK, strcasecmp (value, "dk") == 0)
1.1       root      603:            || (l = KBD_LANG_SE, strcasecmp (value, "se") == 0)
                    604:            || (l = KBD_LANG_US, strcasecmp (value, "us") == 0)
                    605:            || (l = KBD_LANG_FR, strcasecmp (value, "fr") == 0)
                    606:            || (l = KBD_LANG_IT, strcasecmp (value, "it") == 0)
                    607:            || (l = KBD_LANG_ES, strcasecmp (value, "es") == 0))
                    608:            p->keyboard_lang = l;
                    609:        else
                    610:            write_log ("Unknown keyboard language\n");
                    611:        return 1;
                    612:     }
                    613: 
                    614:     if (strcmp (option, "filesystem") == 0
                    615:        || strcmp (option, "hardfile") == 0)
                    616:     {
1.1.1.18  root      617:        int secs, heads, reserved, bs, ro, pri;
1.1.1.2   root      618:        char *aname, *root;
1.1       root      619:        char *tmpp = strchr (value, ',');
1.1.1.2   root      620:        char *str;
1.1.1.20! root      621: 
        !           622:        /* New versions of the emulator write out both types of config string,
        !           623:           with the new variant going first.  When reading in the config file,
        !           624:           we see the new variant and sest config_newfilesystem, and here we
        !           625:           proceed to ignore the old variant since it contains duplicated
        !           626:           information.  */
        !           627:        if (config_newfilesystem)
        !           628:            return 1;
        !           629: 
1.1       root      630:        if (tmpp == 0)
                    631:            goto invalid_fs;
                    632: 
                    633:        *tmpp++ = '\0';
                    634:        if (strcmp (value, "0") == 0 || strcasecmp (value, "ro") == 0
                    635:            || strcasecmp (value, "readonly") == 0
                    636:            || strcasecmp (value, "read-only") == 0)
1.1.1.2   root      637:            ro = 1;
1.1       root      638:        else if (strcmp (value, "1") == 0 || strcasecmp (value, "rw") == 0
                    639:                 || strcasecmp (value, "readwrite") == 0
                    640:                 || strcasecmp (value, "read-write") == 0)
1.1.1.2   root      641:            ro = 0;
1.1       root      642:        else
                    643:            goto invalid_fs;
1.1.1.2   root      644:        secs = 0; heads = 0; reserved = 0; bs = 0;
1.1       root      645: 
                    646:        value = tmpp;
                    647:        if (strcmp (option, "filesystem") == 0) {
                    648:            tmpp = strchr (value, ':');
                    649:            if (tmpp == 0)
                    650:                goto invalid_fs;
                    651:            *tmpp++ = '\0';
1.1.1.2   root      652:            aname = value;
                    653:            root = tmpp;
1.1       root      654:        } else {
1.1.1.2   root      655:            if (! getintval (&value, &secs, ',')
                    656:                || ! getintval (&value, &heads, ',')
                    657:                || ! getintval (&value, &reserved, ',')
                    658:                || ! getintval (&value, &bs, ','))
1.1       root      659:                goto invalid_fs;
1.1.1.2   root      660:            root = value;
                    661:            aname = 0;
1.1       root      662:        }
1.1.1.2   root      663:        str = cfgfile_subst_path (UNEXPANDED, p->path_hardfile, root);
1.1.1.18  root      664:        tmpp = add_filesys_unit (p->mountinfo, NULL, aname, str, ro, secs,
                    665:                                 heads, reserved, bs, -1);
1.1.1.2   root      666:        free (str);
                    667:        if (tmpp)
1.1.1.18  root      668:            gui_message (tmpp);
1.1       root      669:        return 1;
1.1.1.20! root      670:     }
        !           671: 
        !           672:     if (strcmp (option, "filesystem2") == 0
        !           673:        || strcmp (option, "hardfile2") == 0)
        !           674:     {
        !           675:        int secs, heads, reserved, bs, ro, bp, hdcv;
        !           676:        char *dname = NULL, *aname = "", *root = NULL, *fs = NULL, *hdc;
        !           677:        char *tmpp = strchr (value, ',');
        !           678:        char *str = NULL;
        !           679: 
        !           680:        config_newfilesystem = 1;
        !           681:        if (tmpp == 0)
        !           682:            goto invalid_fs;
        !           683: 
        !           684:        *tmpp++ = '\0';
        !           685:        if (strcasecmp (value, "ro") == 0)
        !           686:            ro = 1;
        !           687:        else if (strcasecmp (value, "rw") == 0)
        !           688:            ro = 0;
        !           689:        else
        !           690:            goto invalid_fs;
        !           691:        secs = 0; heads = 0; reserved = 0; bs = 0; bp = 0;
        !           692:        fs = 0; hdc = 0; hdcv = 0;
        !           693: 
        !           694:        value = tmpp;
        !           695:        if (strcmp (option, "filesystem2") == 0) {
        !           696:            tmpp = strchr (value, ':');
        !           697:            if (tmpp == 0)
        !           698:                goto empty_fs;
        !           699:            *tmpp++ = 0;
        !           700:            dname = value;
        !           701:            aname = tmpp;
        !           702:            tmpp = strchr (tmpp, ':');
        !           703:            if (tmpp == 0)
        !           704:                goto empty_fs;
        !           705:            *tmpp++ = 0;
        !           706:            root = tmpp;
        !           707:            tmpp = strchr (tmpp, ',');
        !           708:            if (tmpp == 0)
        !           709:                goto empty_fs;
        !           710:            *tmpp++ = 0;
        !           711:            if (! getintval (&tmpp, &bp, 0))
        !           712:                goto empty_fs;
        !           713:        } else {
        !           714:            tmpp = strchr (value, ':');
        !           715:            if (tmpp == 0)
        !           716:                goto invalid_fs;
        !           717:            *tmpp++ = '\0';
        !           718:            dname = value;
        !           719:            root = tmpp;
        !           720:            tmpp = strchr (tmpp, ',');
        !           721:            if (tmpp == 0)
        !           722:                goto invalid_fs;
        !           723:            *tmpp++ = 0;
        !           724:            aname = 0;
        !           725:            if (! getintval (&tmpp, &secs, ',')
        !           726:                || ! getintval (&tmpp, &heads, ',')
        !           727:                || ! getintval (&tmpp, &reserved, ',')
        !           728:                || ! getintval (&tmpp, &bs, ','))
        !           729:                goto invalid_fs;
        !           730:            if (getintval2 (&tmpp, &bp, ',')) {
        !           731:                fs = tmpp;
        !           732:                tmpp = strchr (tmpp, ',');
        !           733:                if (tmpp != 0) {
        !           734:                    *tmpp++ = 0;
        !           735:                    hdc = tmpp;
        !           736:                }
        !           737:            }
        !           738:        }
        !           739:       empty_fs:
        !           740:        if (root)
        !           741:            str = cfgfile_subst_path (UNEXPANDED, p->path_hardfile, root);
        !           742:        tmpp = add_filesys_unit (p->mountinfo, NULL, aname, str, ro, secs,
        !           743:                                 heads, reserved, bs, bp);
        !           744:        free (str);
        !           745:        if (tmpp)
        !           746:            gui_message (tmpp);
        !           747:        return 1;
1.1       root      748: 
                    749:       invalid_fs:
                    750:        write_log ("Invalid filesystem/hardfile specification.\n");
                    751:        return 1;
                    752:     }
                    753: 
                    754:     return 0;
                    755: }
                    756: 
1.1.1.18  root      757: static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *value)
                    758: {
                    759:     int tmpval, dummy, i;
                    760:     unsigned int crc32;
                    761: 
                    762:     if (cfgfile_yesno (option, value, "immediate_blits", &p->immediate_blits)
                    763:        || cfgfile_yesno (option, value, "a1000ram", &p->cs_a1000ram)
                    764:        || cfgfile_yesno (option, value, "kickshifter", &p->kickshifter)
                    765:        || cfgfile_yesno (option, value, "ntsc", &p->ntscmode)
                    766:        || cfgfile_yesno (option, value, "cpu_24bit_addressing", &p->address_space_24)
                    767:        || cfgfile_yesno (option, value, "parallel_on_demand", &p->parallel_demand)
                    768:        || cfgfile_yesno (option, value, "serial_on_demand", &p->serial_demand))
                    769:        return 1;
                    770:     
                    771:     if (cfgfile_intval (option, value, "fatgary", &p->cs_fatgaryrev, 1)
                    772:        || cfgfile_intval (option, value, "ramsey", &p->cs_ramseyrev, 1)
                    773:        || cfgfile_uintval (option, value, "fastmem_size", &p->fastmem_size, 0x100000)
                    774:        || cfgfile_uintval (option, value, "a3000mem_size", &p->mbresmem_low_size, 0x100000)
                    775:        || cfgfile_uintval (option, value, "mbresmem_size", &p->mbresmem_high_size, 0x100000)
                    776:        || cfgfile_uintval (option, value, "z3mem_size", &p->z3fastmem_size, 0x100000)
                    777:        || cfgfile_uintval (option, value, "bogomem_size", &p->bogomem_size, 0x40000)
                    778:        || cfgfile_uintval (option, value, "gfxcard_size", &p->gfxmem_size, 0x100000)
                    779:        || cfgfile_uintval (option, value, "chipmem_size", &p->chipmem_size, 0x80000)
                    780:        || cfgfile_uintval (option, value, "kickstart_rom_crc", &p->rom_crc32, 1)
                    781:        || cfgfile_intval (option, value, "nr_floppies", &p->nr_floppies, 1)
                    782:        || cfgfile_intval (option, value, "floppy0type", &p->dfxtype[0], 1)
                    783:        || cfgfile_intval (option, value, "floppy1type", &p->dfxtype[1], 1)
                    784:        || cfgfile_intval (option, value, "floppy2type", &p->dfxtype[2], 1)
                    785:        || cfgfile_intval (option, value, "floppy3type", &p->dfxtype[3], 1))
                    786:        return 1;
                    787: 
                    788:     /* Default configurations want to allow multiple possible ROMs.  For these,
                    789:      * we have the following option, which validates the CRC32 against the list
                    790:      * of available ROMs.
                    791:      * Config files should sort these entries so that the most desired ROM appears
                    792:      * last.  */
                    793:     if (cfgfile_uintval (option, value, "kickstart_rom_crc_attempt", &crc32, 1)) {
                    794:        for (i = 0;; i++) {
                    795:            struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1);
                    796:            if (!rl)
                    797:                break;
                    798:            if (rl->rd->crc32 == crc32) {
                    799:                p->rom_crc32 = crc32;
                    800:                break;
                    801:            }
                    802:        }
                    803:        return 1;
                    804:     }
                    805:     
                    806:     if (cfgfile_strval (option, value, "ide", &p->cs_ide, idemode, 0)
                    807:        || cfgfile_strval (option, value, "collision_level", &p->collision_level, collmode, 0))
                    808:        return 1;
                    809: 
                    810:     if (cfgfile_string (option, value, "floppy0", p->df[0], 256)
                    811:        || cfgfile_string (option, value, "floppy1", p->df[1], 256)
                    812:        || cfgfile_string (option, value, "floppy2", p->df[2], 256)
                    813:        || cfgfile_string (option, value, "floppy3", p->df[3], 256)
                    814:        || cfgfile_string (option, value, "kickstart_rom_file", p->romfile, 256)
                    815:        || cfgfile_string (option, value, "kickstart_ext_rom_file", p->romextfile, 256)
                    816:        || cfgfile_string (option, value, "kickstart_key_file", p->keyfile, 256))
                    817:        return 1;
                    818: 
                    819:     if (cfgfile_strval (option, value, "chipset", &tmpval, csmode, 0)) {
                    820:        set_chipset_mask (p, tmpval);
                    821:        return 1;
                    822:     }
                    823: 
                    824:     if (cfgfile_strval (option, value, "cpu_type", &tmpval, cpumode, 0)) {
                    825:        p->fpu_model = 0;
                    826:        p->address_space_24 = 0;
                    827:        p->cpu_model = 68000;
                    828:        switch (tmpval) {
                    829:        case 0:
                    830:            p->cpu_model = 68000;
                    831:            break;
                    832:        case 1:
                    833:            p->cpu_model = 68010;
                    834:            break;
                    835:        case 2: case 3: case 4:
                    836:        case 5: case 6: case 7:
                    837:            p->cpu_model = 68020;
                    838:            p->address_space_24 = tmpval < 5;
                    839:            p->fpu_model = (tmpval == 3 || tmpval == 6 ? 68881
                    840:                            : tmpval == 4 || tmpval == 7 ? 68882
                    841:                            : 0);
                    842:            break;
                    843:        case 8: case 9: case 10:
                    844:            p->cpu_model = 68030;
                    845:            p->fpu_model = (tmpval == 9 ? 68881 : tmpval == 10 ? 68882 : 0);
                    846:            break;
                    847:        case 11:
                    848:            p->cpu_model = 68040;
                    849:            p->fpu_model = 68040;
                    850:            break;
                    851:        case 12:
                    852:            p->cpu_model = 68060;
                    853:            p->fpu_model = 68060;
                    854:            break;
                    855:        }
                    856:        return 1;
                    857:     }
                    858: 
                    859:     if (cfgfile_strval (option, value, "cpu_speed", &p->m68k_speed, speedmode, 1)
                    860:        /* Broken earlier versions used to write this out as a string.  */
                    861:        || cfgfile_strval (option, value, "finegraincpu_speed", &p->m68k_speed, speedmode, 1))
                    862:     {
                    863:        p->m68k_speed--;
                    864:        return 1;
                    865:     }
                    866: 
                    867:     if (cfgfile_intval (option, value, "cpu_speed", &p->m68k_speed, 1)) {
                    868:        p->m68k_speed *= CYCLE_UNIT;
                    869:        return 1;
                    870:     }
                    871: 
                    872:     if (cfgfile_intval (option, value, "finegrain_cpu_speed", &p->m68k_speed, 1)) {
                    873:        if (OFFICIAL_CYCLE_UNIT > CYCLE_UNIT) {
                    874:            int factor = OFFICIAL_CYCLE_UNIT / CYCLE_UNIT;
                    875:            p->m68k_speed = (p->m68k_speed + factor - 1) / factor;
                    876:        }
                    877:        return 1;
                    878:     }
                    879: 
                    880:     return 0;
                    881: }
                    882: 
                    883: int cfgfile_parse_option (struct uae_prefs *p, char *option, char *value)
                    884: {
                    885:     if (cfgfile_parse_hardware (p, option, value))
                    886:        return 1;
                    887:     if (cfgfile_parse_host (p, option, value))
                    888:        return 1;
                    889: 
                    890:     return 0;
                    891: }
                    892: 
1.1.1.2   root      893: void cfgfile_parse_line (struct uae_prefs *p, char *line)
1.1       root      894: {
                    895:     int i;
                    896:     char *orig_line = my_strdup (line);
                    897:     char *line1, *line2;
                    898: 
                    899:     line1 = line;
                    900:     line2 = strchr (line, '=');
                    901:     if (! line2) {
                    902:        write_log ("CFGFILE: line was incomplete with only %s\n", line1);
                    903:        return;
                    904:     }
                    905: 
                    906:     *line2++ = '\0';
                    907: 
                    908:     /* Get rid of whitespace.  */
1.1.1.2   root      909:     i = strlen (line2);
                    910:     while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
                    911:                     || line2[i - 1] == '\r' || line2[i - 1] == '\n'))
                    912:        line2[--i] = '\0';
1.1       root      913:     line2 += strspn (line2, "\t \r\n");
1.1.1.2   root      914:     i = strlen (line);
                    915:     while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
                    916:                     || line[i - 1] == '\r' || line[i - 1] == '\n'))
                    917:        line[--i] = '\0';
1.1       root      918:     line += strspn (line, "\t \r\n");
                    919: 
1.1.1.2   root      920:     if (! cfgfile_parse_option (p, line, line2)) {
1.1       root      921:        struct strlist *u = xmalloc (sizeof (struct strlist));
                    922:        u->str = orig_line;
                    923:        u->next = p->unknown_lines;
                    924:        p->unknown_lines = u;
                    925:     } else
                    926:        free (orig_line);
                    927: }
                    928: 
                    929: static void subst (char *p, char *f, int n)
                    930: {
                    931:     char *str = cfgfile_subst_path (UNEXPANDED, p, f);
                    932:     strncpy (f, str, n - 1);
                    933:     f[n - 1] = '\0';
                    934:     free (str);
                    935: }
                    936: 
                    937: int cfgfile_load (struct uae_prefs *p, const char *filename)
                    938: {
                    939:     int i;
                    940: 
                    941:     FILE *fh;
                    942:     char line[256];
                    943: 
1.1.1.4   root      944:     fh = fopen (filename, "r");
1.1       root      945:     if (! fh)
                    946:        return 0;
                    947: 
                    948:     while (fgets (line, 256, fh) != 0) {
1.1.1.13  root      949:        int len = strlen (line);
                    950:        /* Delete trailing whitespace.  */
1.1.1.18  root      951:        while (len > 0 && strcspn (line + len - 1, "\t \r\n") == 0)
1.1.1.13  root      952:            line[--len] = '\0';
1.1.1.18  root      953:        if (strlen (line) > 0) {
                    954:            if (line[0] == '#' || line[0] == ';')
                    955:                continue;
1.1.1.2   root      956:            cfgfile_parse_line (p, line);
1.1.1.18  root      957:        }
1.1       root      958:     }
                    959:     fclose (fh);
                    960: 
                    961:     for (i = 0; i < 4; i++)
                    962:        subst (p->path_floppy, p->df[i], sizeof p->df[i]);
                    963:     subst (p->path_rom, p->romfile, sizeof p->romfile);
1.1.1.12  root      964:     subst (p->path_rom, p->romextfile, sizeof p->romextfile);
1.1       root      965:     subst (p->path_rom, p->keyfile, sizeof p->keyfile);
                    966: 
                    967:     return 1;
                    968: }
                    969: 
                    970: int cfgfile_save (struct uae_prefs *p, const char *filename)
                    971: {
                    972:     FILE *fh = fopen (filename, "w");
                    973:     if (! fh)
                    974:        return 0;
                    975: 
                    976:     save_options (fh, p);
                    977:     fclose (fh);
                    978:     return 1;
                    979: }
                    980: 
                    981: int cfgfile_get_description (const char *filename, char *description)
                    982: {
                    983:     int result = 0;
                    984:     struct uae_prefs p;
                    985:     default_prefs (&p);
                    986:     strcpy (p.description, "");
1.1.1.12  root      987:     if (cfgfile_load (&p, filename)) {
1.1       root      988:        result = 1;
                    989:        strcpy (description, p.description);
                    990:     }
                    991:     discard_prefs (&p);
                    992:     return result;
                    993: }
                    994: 
                    995: void cfgfile_show_usage (void)
                    996: {
                    997:     int i;
                    998:     fprintf (stderr, "UAE Configuration Help:\n" \
                    999:               "=======================\n");
                   1000:     for (i = 0; i < sizeof opttable / sizeof *opttable; i++)
                   1001:        fprintf (stderr, "%s: %s\n", opttable[i].config_label, opttable[i].config_help);
                   1002: }
1.1.1.4   root     1003: 
                   1004: /* This implements the old commandline option parsing.  I've re-added this
                   1005:    because the new way of doing things is painful for me (it requires me
                   1006:    to type a couple hundred characters when invoking UAE).  The following
                   1007:    is far less annoying to use.  */
1.1.1.16  root     1008: static void parse_gfx_specs (struct uae_prefs *p, char *spec)
1.1.1.4   root     1009: {
                   1010:     char *x0 = my_strdup (spec);
                   1011:     char *x1, *x2;
                   1012: 
                   1013:     x1 = strchr (x0, ':');
                   1014:     if (x1 == 0)
                   1015:        goto argh;
                   1016:     x2 = strchr (x1+1, ':');
                   1017:     if (x2 == 0)
                   1018:        goto argh;
                   1019:     *x1++ = 0; *x2++ = 0;
                   1020: 
1.1.1.17  root     1021:     p->gfx_w.width = atoi (x0);
                   1022:     p->gfx_w.height = atoi (x1);
                   1023:     p->gfx_w.lores = strchr (x2, 'l') != 0;
                   1024:     p->gfx_w.xcenter = strchr (x2, 'x') != 0 ? 1 : strchr (x2, 'X') != 0 ? 2 : 0;
                   1025:     p->gfx_w.ycenter = strchr (x2, 'y') != 0 ? 1 : strchr (x2, 'Y') != 0 ? 2 : 0;
                   1026:     p->gfx_w.linedbl = strchr (x2, 'd') != 0;
                   1027:     p->gfx_w.linedbl += 2 * (strchr (x2, 'D') != 0);
                   1028:     p->gfx_w.correct_aspect = strchr (x2, 'c') != 0;
                   1029: 
                   1030:     p->gfx_f = p->gfx_w;
                   1031: 
1.1.1.16  root     1032:     p->gfx_afullscreen = strchr (x2, 'a') != 0;
                   1033:     p->gfx_pfullscreen = strchr (x2, 'p') != 0;
1.1.1.4   root     1034: 
1.1.1.17  root     1035:     if (p->gfx_w.linedbl == 3) {
1.1.1.4   root     1036:        fprintf (stderr, "You can't use both 'd' and 'D' modifiers in the display mode specification.\n");
                   1037:     }
1.1.1.16  root     1038: 
1.1.1.4   root     1039:     free (x0);
                   1040:     return;
                   1041: 
                   1042:     argh:
                   1043:     fprintf (stderr, "Bad display mode specification.\n");
                   1044:     fprintf (stderr, "The format to use is: \"width:height:modifiers\"\n");
                   1045:     fprintf (stderr, "Type \"uae -h\" for detailed help.\n");
                   1046:     free (x0);
                   1047: }
                   1048: 
1.1.1.16  root     1049: static void parse_sound_spec (struct uae_prefs *p, char *spec)
1.1.1.4   root     1050: {
                   1051:     char *x0 = my_strdup (spec);
1.1.1.18  root     1052:     char *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL;
1.1.1.4   root     1053: 
                   1054:     x1 = strchr (x0, ':');
                   1055:     if (x1 != NULL) {
                   1056:        *x1++ = '\0';
                   1057:        x2 = strchr (x1 + 1, ':');
                   1058:        if (x2 != NULL) {
                   1059:            *x2++ = '\0';
                   1060:            x3 = strchr (x2 + 1, ':');
                   1061:            if (x3 != NULL) {
                   1062:                *x3++ = '\0';
                   1063:                x4 = strchr (x3 + 1, ':');
                   1064:            }
                   1065:        }
                   1066:     }
1.1.1.16  root     1067:     p->produce_sound = atoi (x0);
1.1.1.4   root     1068:     if (x1) {
1.1.1.18  root     1069:        p->sound_mixed_stereo_delay = 0;
1.1.1.19  root     1070:        p->sound_stereo = SND_STEREO;
1.1.1.18  root     1071:        if (*x1 == 'S') {
                   1072:            p->sound_stereo_separation = 7;
1.1.1.19  root     1073:        }
1.1.1.4   root     1074:     }
1.1.1.18  root     1075:     /* x2 used to be bits, now fixed at 16 bit.  */
1.1.1.4   root     1076:     if (x3)
1.1.1.16  root     1077:        p->sound_freq = atoi (x3);
1.1.1.4   root     1078:     if (x4)
1.1.1.18  root     1079:        p->sound_maxbsiz = atoi (x4);
1.1.1.4   root     1080:     free (x0);
                   1081: }
                   1082: 
                   1083: 
1.1.1.16  root     1084: static void parse_joy_spec (struct uae_prefs *p, char *spec)
1.1.1.4   root     1085: {
                   1086:     int v0 = 2, v1 = 0;
                   1087:     if (strlen(spec) != 2)
                   1088:        goto bad;
                   1089: 
                   1090:     switch (spec[0]) {
1.1.1.16  root     1091:      case '0': v0 = JSEM_JOYS; break;
                   1092:      case '1': v0 = JSEM_JOYS + 1; break;
                   1093:      case 'M': case 'm': v0 = JSEM_MICE; break;
                   1094:      case 'A': case 'a': v0 = JSEM_KBDLAYOUT; break;
                   1095:      case 'B': case 'b': v0 = JSEM_KBDLAYOUT + 1; break;
                   1096:      case 'C': case 'c': v0 = JSEM_KBDLAYOUT + 2; break;
1.1.1.4   root     1097:      default: goto bad;
                   1098:     }
                   1099: 
                   1100:     switch (spec[1]) {
1.1.1.16  root     1101:      case '0': v1 = JSEM_JOYS; break;
                   1102:      case '1': v1 = JSEM_JOYS + 1; break;
                   1103:      case 'M': case 'm': v1 = JSEM_MICE; break;
                   1104:      case 'A': case 'a': v1 = JSEM_KBDLAYOUT; break;
                   1105:      case 'B': case 'b': v1 = JSEM_KBDLAYOUT + 1; break;
                   1106:      case 'C': case 'c': v1 = JSEM_KBDLAYOUT + 2; break;
1.1.1.4   root     1107:      default: goto bad;
                   1108:     }
                   1109:     if (v0 == v1)
                   1110:        goto bad;
                   1111:     /* Let's scare Pascal programmers */
                   1112:     if (0)
                   1113: bad:
1.1.1.16  root     1114:     write_log ("Bad joystick mode specification. Use -J xy, where x and y\n"
1.1.1.4   root     1115:             "can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n"
                   1116:             "a, b or c for different keyboard settings.\n");
                   1117: 
1.1.1.16  root     1118:     p->jport0 = v0;
                   1119:     p->jport1 = v1;
1.1.1.4   root     1120: }
                   1121: 
1.1.1.18  root     1122: static void parse_filesys_spec (struct uae_prefs *p, int readonly, char *spec)
1.1.1.4   root     1123: {
                   1124:     char buf[256];
                   1125:     char *s2;
                   1126: 
                   1127:     strncpy (buf, spec, 255); buf[255] = 0;
                   1128:     s2 = strchr (buf, ':');
                   1129:     if (s2) {
                   1130:        *s2++ = '\0';
                   1131: #ifdef __DOS__
                   1132:        {
                   1133:            char *tmp;
1.1.1.16  root     1134: 
1.1.1.4   root     1135:            while ((tmp = strchr (s2, '\\')))
                   1136:                *tmp = '/';
                   1137:        }
                   1138: #endif
1.1.1.18  root     1139:        s2 = add_filesys_unit (p->mountinfo, NULL, buf, s2, readonly, 0, 0, 0, 0, -1);
1.1.1.4   root     1140:        if (s2)
                   1141:            fprintf (stderr, "%s\n", s2);
                   1142:     } else {
                   1143:        fprintf (stderr, "Usage: [-m | -M] VOLNAME:mount_point\n");
                   1144:     }
                   1145: }
1.1.1.16  root     1146: 
1.1.1.18  root     1147: static void parse_hardfile_spec (struct uae_prefs *p, char *spec)
1.1.1.4   root     1148: {
                   1149:     char *x0 = my_strdup (spec);
                   1150:     char *x1, *x2, *x3, *x4;
                   1151: 
                   1152:     x1 = strchr (x0, ':');
                   1153:     if (x1 == NULL)
                   1154:        goto argh;
                   1155:     *x1++ = '\0';
                   1156:     x2 = strchr (x1 + 1, ':');
                   1157:     if (x2 == NULL)
                   1158:        goto argh;
                   1159:     *x2++ = '\0';
                   1160:     x3 = strchr (x2 + 1, ':');
                   1161:     if (x3 == NULL)
                   1162:        goto argh;
                   1163:     *x3++ = '\0';
                   1164:     x4 = strchr (x3 + 1, ':');
                   1165:     if (x4 == NULL)
                   1166:        goto argh;
                   1167:     *x4++ = '\0';
1.1.1.18  root     1168:     x4 = add_filesys_unit (p->mountinfo, NULL, 0, x4, 0, atoi (x0), atoi (x1), atoi (x2), atoi (x3), -1);
1.1.1.4   root     1169:     if (x4)
                   1170:        fprintf (stderr, "%s\n", x4);
                   1171: 
                   1172:     free (x0);
                   1173:     return;
                   1174: 
                   1175:  argh:
                   1176:     free (x0);
                   1177:     fprintf (stderr, "Bad hardfile parameter specified - type \"uae -h\" for help.\n");
                   1178:     return;
                   1179: }
                   1180: 
1.1.1.18  root     1181: static void parse_cpu_specs (struct uae_prefs *p, char *spec)
1.1.1.4   root     1182: {
1.1.1.18  root     1183:     int lvl;
1.1.1.7   root     1184:     if (*spec < '0' || *spec > '4') {
                   1185:        fprintf (stderr, "CPU parameter string must begin with '0', '1', '2', '3' or '4'.\n");
1.1.1.4   root     1186:        return;
                   1187:     }
1.1.1.16  root     1188: 
1.1.1.18  root     1189:     lvl = *spec++ - '0';
                   1190:     p->fpu_model = 0;
                   1191:     p->cpu_model = lvl * 10 + 68000;
                   1192:     if (p->cpu_model >= 68040)
                   1193:        p->fpu_model = p->cpu_model;
                   1194:     p->address_space_24 = p->cpu_model < 68020;
1.1.1.4   root     1195:     while (*spec != '\0') {
                   1196:        switch (*spec) {
1.1.1.18  root     1197:        case 'a':
                   1198:            if (p->cpu_model < 68020)
1.1.1.4   root     1199:                fprintf (stderr, "In 68000/68010 emulation, the address space is always 24 bit.\n");
1.1.1.18  root     1200:            else if (p->cpu_model >= 68040)
1.1.1.7   root     1201:                fprintf (stderr, "In 68040 emulation, the address space is always 32 bit.\n");
1.1.1.4   root     1202:            else
1.1.1.18  root     1203:                p->address_space_24 = 1;
1.1.1.4   root     1204:            break;
1.1.1.18  root     1205:        case 'c':
                   1206:            fprintf (stderr, "Obsolete CPU type modifier 'c'.\n");
1.1.1.4   root     1207:            break;
1.1.1.18  root     1208:        default:
1.1.1.4   root     1209:            fprintf (stderr, "Bad CPU parameter specified - type \"uae -h\" for help.\n");
                   1210:            break;
                   1211:        }
                   1212:        spec++;
                   1213:     }
                   1214: }
                   1215: 
                   1216: /* Returns the number of args used up (0 or 1).  */
1.1.1.18  root     1217: int parse_cmdline_option (struct uae_prefs *p, char c, char *arg)
1.1.1.4   root     1218: {
1.1.1.5   root     1219:     const char arg_required[] = "0123rKpImWSAJwNCZUFcblOdHRv";
1.1.1.4   root     1220: 
                   1221:     if (strchr (arg_required, c) && ! arg) {
                   1222:        fprintf (stderr, "Missing argument for option `-%c'!\n", c);
                   1223:        return 0;
                   1224:     }
                   1225: 
                   1226:     switch (c) {
1.1.1.5   root     1227:     case 'h': usage (); exit (0);
1.1.1.4   root     1228: 
1.1.1.18  root     1229:     case '0': strncpy (p->df[0], arg, 255); p->df[0][255] = 0; break;
                   1230:     case '1': strncpy (p->df[1], arg, 255); p->df[1][255] = 0; break;
                   1231:     case '2': strncpy (p->df[2], arg, 255); p->df[2][255] = 0; break;
                   1232:     case '3': strncpy (p->df[3], arg, 255); p->df[3][255] = 0; break;
                   1233:     case 'r': strncpy (p->romfile, arg, 255); p->romfile[255] = 0; break;
                   1234:     case 'K': strncpy (p->keyfile, arg, 255); p->keyfile[255] = 0; break;
                   1235:     case 'p': strncpy (p->prtname, arg, 255); p->prtname[255] = 0; break;
                   1236:        /*     case 'I': strncpy (p->sername, arg, 255); p->sername[255] = 0; p->use_serial = 1; break; */
                   1237:     case 'm': case 'M': parse_filesys_spec (p, c == 'M', arg); break;
                   1238:     case 'W': parse_hardfile_spec (p, arg); break;
                   1239:     case 'S': parse_sound_spec (p, arg); break;
                   1240:     case 'R': p->gfx_framerate = atoi (arg); break;
                   1241:     case 'i': p->illegal_mem = 1; break;
                   1242:     case 'J': parse_joy_spec (p, arg); break;
                   1243: 
                   1244:     case 't': p->test_drawing_speed = 1; break;
                   1245:     case 'L': p->x11_use_low_bandwidth = 1; break;
                   1246:     case 'T': p->x11_use_mitshm = 1; break;
                   1247:     case 'w': p->m68k_speed = atoi (arg); break;
                   1248: 
                   1249:     case 'G': p->start_gui = 0; break;
                   1250:     case 'D': p->start_debugger = 1; break;
1.1.1.4   root     1251: 
1.1.1.5   root     1252:     case 'n':
1.1.1.4   root     1253:        if (strchr (arg, '3') != 0)
1.1.1.18  root     1254:            p->blits_32bit_enabled = 1;
1.1.1.4   root     1255:        if (strchr (arg, 'i') != 0)
1.1.1.18  root     1256:            p->immediate_blits = 1;
1.1.1.4   root     1257:        break;
                   1258: 
1.1.1.5   root     1259:     case 'v':
1.1.1.18  root     1260:        set_chipset_mask (p, atoi (arg));
1.1.1.5   root     1261:        break;
                   1262: 
                   1263:     case 'C':
1.1.1.18  root     1264:        parse_cpu_specs (p, arg);
1.1.1.4   root     1265:        break;
                   1266: 
1.1.1.5   root     1267:     case 'Z':
1.1.1.18  root     1268:        p->z3fastmem_size = atoi (arg) * 0x100000;
1.1.1.4   root     1269:        break;
                   1270: 
1.1.1.5   root     1271:     case 'U':
1.1.1.18  root     1272:        p->gfxmem_size = atoi (arg) * 0x100000;
1.1.1.4   root     1273:        break;
                   1274: 
1.1.1.5   root     1275:     case 'F':
1.1.1.18  root     1276:        p->fastmem_size = atoi (arg) * 0x100000;
1.1.1.4   root     1277:        break;
                   1278: 
1.1.1.5   root     1279:     case 'b':
1.1.1.18  root     1280:        p->bogomem_size = atoi (arg) * 0x40000;
1.1.1.4   root     1281:        break;
                   1282: 
1.1.1.5   root     1283:     case 'c':
1.1.1.18  root     1284:        p->chipmem_size = atoi (arg) * 0x80000;
1.1.1.4   root     1285:        break;
                   1286: 
1.1.1.5   root     1287:     case 'l':
1.1.1.18  root     1288:        if (0 == strcasecmp (arg, "de"))
                   1289:            p->keyboard_lang = KBD_LANG_DE;
                   1290:        else if (0 == strcasecmp (arg, "dk"))
                   1291:            p->keyboard_lang = KBD_LANG_DK;
                   1292:        else if (0 == strcasecmp (arg, "us"))
                   1293:            p->keyboard_lang = KBD_LANG_US;
                   1294:        else if (0 == strcasecmp (arg, "se"))
                   1295:            p->keyboard_lang = KBD_LANG_SE;
                   1296:        else if (0 == strcasecmp (arg, "fr"))
                   1297:            p->keyboard_lang = KBD_LANG_FR;
                   1298:        else if (0 == strcasecmp (arg, "it"))
                   1299:            p->keyboard_lang = KBD_LANG_IT;
                   1300:        else if (0 == strcasecmp (arg, "es"))
                   1301:            p->keyboard_lang = KBD_LANG_ES;
1.1.1.4   root     1302:        break;
                   1303: 
1.1.1.18  root     1304:     case 'O': parse_gfx_specs (p, arg); break;
1.1.1.5   root     1305:     case 'd':
1.1.1.4   root     1306:        if (strchr (arg, 'S') != NULL || strchr (arg, 's')) {
                   1307:            write_log ("  Serial on demand.\n");
1.1.1.18  root     1308:            p->serial_demand = 1;
1.1.1.4   root     1309:        }
                   1310:        if (strchr (arg, 'P') != NULL || strchr (arg, 'p')) {
                   1311:            write_log ("  Parallel on demand.\n");
1.1.1.18  root     1312:            p->parallel_demand = 1;
1.1.1.4   root     1313:        }
                   1314: 
                   1315:        break;
                   1316: 
1.1.1.5   root     1317:     case 'H':
1.1.1.18  root     1318:        p->color_mode = atoi (arg);
                   1319:        if (p->color_mode < 0) {
1.1.1.4   root     1320:            fprintf (stderr, "Bad color mode selected. Using default.\n");
1.1.1.18  root     1321:            p->color_mode = 0;
1.1.1.4   root     1322:        }
                   1323:        break;
1.1.1.5   root     1324:     default:
1.1.1.4   root     1325:        fprintf (stderr, "Unknown option `-%c'!\n", c);
                   1326:        break;
                   1327:     }
                   1328:     return !! strchr (arg_required, c);
                   1329: }
1.1.1.18  root     1330: 
                   1331: int cstype_from_prefs (struct uae_prefs *p)
                   1332: {
                   1333:     if ((p->chipset_mask & CSMASK_AGA) == 0) {
                   1334:        if (p->cs_ramseyrev == -1 && p->cs_fatgaryrev == -1) {
                   1335:            if (p->cs_ide == 0) {
                   1336:                if (p->cs_a1000ram && p->chipset_mask == CSMASK_OCS)
                   1337:                    return CP_A1000;
                   1338:                if (p->chipset_mask == CSMASK_FULL_ECS)
                   1339:                    return CP_A500P;
                   1340:                return CP_A500;
                   1341:            }
                   1342:            if (p->chipset_mask == CSMASK_FULL_ECS)
                   1343:                return CP_A600;
                   1344:            return CP_GENERIC;
                   1345:        }
                   1346:        if (p->cs_ide == 0 && p->cs_fatgaryrev == 0 && p->cs_ramseyrev == 0xd)
                   1347:            return CP_A3000;
                   1348:        return CP_GENERIC;
                   1349:     }
                   1350:     if (p->cs_ide == 1 && p->cs_ramseyrev == -1 && p->cs_fatgaryrev == -1)
                   1351:        return CP_A1200;
                   1352:     if (p->cs_ide == 2 && p->cs_ramseyrev == 0xf && p->cs_fatgaryrev == 0)
                   1353:        return CP_A4000;
                   1354:     return CP_GENERIC;
                   1355: }
                   1356: 
                   1357: void built_in_chipset_prefs (struct uae_prefs *p, int cstype)
                   1358: {
                   1359:     p->cs_a1000ram = 0;
                   1360:     p->cs_fatgaryrev = -1;
                   1361:     p->cs_ide = 0;
                   1362:     p->cs_ramseyrev = -1;
                   1363: 
                   1364:     switch (cstype)
                   1365:     {
                   1366:     case CP_GENERIC: // generic
                   1367:        p->cs_fatgaryrev = 0;
                   1368:        p->cs_ide = -1;
                   1369:        p->cs_ramseyrev = 0x0f;
                   1370:        break;
                   1371:     case CP_CDTV: // CDTV
                   1372:        break;
                   1373:     case CP_CD32: // CD32
                   1374:        break;
                   1375:     case CP_A500: // A500
                   1376:        if (p->chipset_mask & CSMASK_AGA)
                   1377:            p->chipset_mask = CSMASK_ECS_AGNUS;
                   1378:        break;
                   1379:     case CP_A500P: // A500+
                   1380:        p->chipset_mask = CSMASK_FULL_ECS;
                   1381:        break;
                   1382:     case CP_A600: // A600
                   1383:        p->cs_ide = 1;
                   1384:        p->chipset_mask = CSMASK_FULL_ECS;
                   1385:        break;
                   1386:     case CP_A1000: // A1000
                   1387:        p->cs_a1000ram = 1;
                   1388:        p->chipset_mask = CSMASK_OCS;
                   1389:        break;
                   1390:     case CP_A1200: // A1200
                   1391:        p->cs_ide = 1;
                   1392:        p->chipset_mask = CSMASK_AGA;
                   1393:        break;
                   1394:     case CP_A2000: // A2000
                   1395:        if (p->chipset_mask & CSMASK_AGA)
                   1396:            p->chipset_mask = CSMASK_ECS_AGNUS;
                   1397:        p->cs_rtc = 1;
                   1398:        break;
                   1399:     case CP_A3000: // A3000
                   1400:        p->cs_rtc = 2;
                   1401:        p->cs_fatgaryrev = 0;
                   1402:        p->cs_ramseyrev = 0x0d;
                   1403:        p->chipset_mask = CSMASK_FULL_ECS;
                   1404:        break;
                   1405:     case CP_A3000T: // A3000T
                   1406:        p->cs_rtc = 2;
                   1407:        p->cs_fatgaryrev = 0;
                   1408:        p->cs_ramseyrev = 0x0d;
                   1409:        p->chipset_mask = CSMASK_FULL_ECS;
                   1410:        break;
                   1411:     case CP_A4000: // A4000
                   1412:        p->cs_rtc = 2;
                   1413:        p->cs_fatgaryrev = 0;
                   1414:        p->cs_ramseyrev = 0x0f;
                   1415:        p->cs_ide = 2;
                   1416:        p->chipset_mask = CSMASK_AGA;
                   1417:        break;
                   1418:     case CP_A4000T: // A4000T
                   1419:        p->cs_rtc = 2;
                   1420:        p->cs_fatgaryrev = 0;
                   1421:        p->cs_ramseyrev = 0x0f;
                   1422:        p->cs_ide = 2;
                   1423:        p->chipset_mask = CSMASK_AGA;
                   1424:        break;
                   1425:     }
                   1426: }

unix.superglobalmegacorp.com

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