Annotation of hatari/src/options.c, revision 1.1.1.16

1.1       root        1: /*
                      2:   Hatari - options.c
                      3: 
1.1.1.11  root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   Functions for showing and parsing all of Hatari's command line options.
                      8:   
                      9:   To add a new option:
                     10:   - Add option ID to the enum
1.1.1.2   root       11:   - Add the option information to HatariOptions[]
1.1       root       12:   - Add required actions for that ID to switch in Opt_ParseParameters()
                     13: */
1.1.1.5   root       14: const char Options_fileid[] = "Hatari options.c : " __DATE__ " " __TIME__;
1.1.1.2   root       15: 
                     16: #include <ctype.h>
1.1       root       17: #include <stdio.h>
                     18: #include <stdlib.h>
                     19: #include <string.h>
                     20: #include <assert.h>
1.1.1.7   root       21: #include <SDL.h>
1.1       root       22: 
                     23: #include "main.h"
1.1.1.11  root       24: #include "version.h"
1.1       root       25: #include "options.h"
                     26: #include "configuration.h"
1.1.1.4   root       27: #include "control.h"
1.1.1.6   root       28: #include "debugui.h"
1.1       root       29: #include "file.h"
1.1.1.4   root       30: #include "floppy.h"
1.1.1.12  root       31: #include "fdc.h"
1.1       root       32: #include "screen.h"
1.1.1.13  root       33: #include "statusbar.h"
1.1.1.8   root       34: #include "sound.h"
1.1       root       35: #include "video.h"
                     36: #include "vdi.h"
                     37: #include "joy.h"
1.1.1.4   root       38: #include "log.h"
1.1.1.15  root       39: #include "inffile.h"
1.1.1.8   root       40: #include "paths.h"
1.1.1.7   root       41: #include "avi_record.h"
1.1.1.2   root       42: #include "hatari-glue.h"
1.1.1.11  root       43: #include "68kDisass.h"
1.1.1.12  root       44: #include "xbios.h"
1.1.1.15  root       45: #include "stMemory.h"
1.1.1.16! root       46: #include "tos.h"
1.1.1.15  root       47: 
1.1       root       48: 
1.1.1.4   root       49: bool bLoadAutoSave;        /* Load autosave memory snapshot at startup */
                     50: bool bLoadMemorySave;      /* Load memory snapshot provided via option at startup */
1.1.1.7   root       51: bool AviRecordOnStartup;   /* Start avi recording at startup */
1.1.1.15  root       52: bool BenchmarkMode;       /* Start in benchmark mode (try to run at maximum emulation */
                     53:                           /* speed allowed by the CPU). Disable audio/video for best results */
1.1       root       54: 
1.1.1.11  root       55: int ConOutDevice = CONOUT_DEVICE_NONE; /* device number for xconout device to track */
                     56: 
1.1.1.16! root       57: static bool bNoSDLParachute, bBiosIntercept;
1.1       root       58: 
                     59: /*  List of supported options. */
                     60: enum {
1.1.1.2   root       61:        OPT_HEADER,     /* options section header */
                     62:        OPT_HELP,               /* general options */
1.1       root       63:        OPT_VERSION,
1.1.1.2   root       64:        OPT_CONFIRMQUIT,
                     65:        OPT_CONFIGFILE,
1.1.1.8   root       66:        OPT_KEYMAPFILE,
1.1.1.4   root       67:        OPT_FASTFORWARD,
1.1.1.15  root       68:        OPT_AUTOSTART,
1.1.1.8   root       69:        OPT_MONO,               /* common display options */
1.1.1.2   root       70:        OPT_MONITOR,
1.1.1.15  root       71:        OPT_TOS_RESOLUTION,
1.1       root       72:        OPT_FULLSCREEN,
                     73:        OPT_WINDOW,
1.1.1.6   root       74:        OPT_GRAB,
1.1.1.15  root       75:        OPT_RESIZABLE,
1.1.1.7   root       76:        OPT_FRAMESKIPS,
1.1.1.12  root       77:        OPT_SLOWDOWN,
1.1.1.13  root       78:        OPT_MOUSE_WARP,
1.1.1.4   root       79:        OPT_STATUSBAR,
                     80:        OPT_DRIVE_LED,
1.1.1.12  root       81:        OPT_MAXWIDTH,
                     82:        OPT_MAXHEIGHT,
1.1.1.2   root       83:        OPT_FORCEBPP,
1.1.1.15  root       84:        OPT_DISABLE_VIDEO,
1.1.1.8   root       85:        OPT_BORDERS,            /* ST/STE display options */
1.1.1.9   root       86:        OPT_RESOLUTION_ST,
1.1.1.8   root       87:        OPT_SPEC512,
                     88:        OPT_ZOOM,
1.1.1.14  root       89:        OPT_VIDEO_TIMING,
1.1.1.12  root       90:        OPT_RESOLUTION,         /* TT/Falcon display options */
1.1.1.9   root       91:        OPT_FORCE_MAX,
1.1.1.8   root       92:        OPT_ASPECT,
1.1.1.4   root       93:        OPT_VDI,                /* VDI options */
                     94:        OPT_VDI_PLANES,
1.1.1.2   root       95:        OPT_VDI_WIDTH,
                     96:        OPT_VDI_HEIGHT,
1.1.1.8   root       97:        OPT_SCREEN_CROP,        /* screen capture options */
                     98:        OPT_AVIRECORD,
1.1.1.7   root       99:        OPT_AVIRECORD_VCODEC,
1.1.1.13  root      100:        OPT_AVI_PNG_LEVEL,
1.1.1.7   root      101:        OPT_AVIRECORD_FPS,
                    102:        OPT_AVIRECORD_FILE,
1.1.1.2   root      103:        OPT_JOYSTICK,           /* device options */
1.1.1.4   root      104:        OPT_JOYSTICK0,
                    105:        OPT_JOYSTICK1,
                    106:        OPT_JOYSTICK2,
                    107:        OPT_JOYSTICK3,
                    108:        OPT_JOYSTICK4,
                    109:        OPT_JOYSTICK5,
1.1       root      110:        OPT_PRINTER,
1.1.1.15  root      111: #ifdef HAVE_PORTMIDI
                    112:        OPT_MIDI,
                    113: #else
1.1.1.5   root      114:        OPT_MIDI_IN,
                    115:        OPT_MIDI_OUT,
1.1.1.15  root      116: #endif
1.1.1.5   root      117:        OPT_RS232_IN,
                    118:        OPT_RS232_OUT,
1.1.1.16! root      119:        // OPT_SCCB,
        !           120:        // OPT_SCCBIN,
        !           121:        OPT_SCCBOUT,
1.1.1.12  root      122:        OPT_DRIVEA,             /* disk options */
                    123:        OPT_DRIVEB,
                    124:        OPT_DRIVEA_HEADS,
                    125:        OPT_DRIVEB_HEADS,
                    126:        OPT_DISKA,
1.1.1.4   root      127:        OPT_DISKB,
1.1.1.9   root      128:        OPT_FASTFLOPPY,
1.1.1.7   root      129:        OPT_WRITEPROT_FLOPPY,
1.1.1.13  root      130:        OPT_HARDDRIVE,
1.1.1.7   root      131:        OPT_WRITEPROT_HD,
1.1.1.11  root      132:        OPT_GEMDOS_CASE,
1.1.1.15  root      133:        OPT_GEMDOS_HOSTTIME,
1.1.1.13  root      134:        OPT_GEMDOS_CONVERT,
                    135:        OPT_GEMDOS_DRIVE,
1.1.1.2   root      136:        OPT_ACSIHDIMAGE,
1.1.1.16! root      137:        OPT_SCSIHDIMAGE,
1.1.1.7   root      138:        OPT_IDEMASTERHDIMAGE,
                    139:        OPT_IDESLAVEHDIMAGE,
1.1.1.16! root      140:        OPT_IDEBYTESWAP,
1.1.1.2   root      141:        OPT_MEMSIZE,            /* memory options */
1.1.1.13  root      142: #if ENABLE_WINUAE_CPU
                    143:        OPT_TT_RAM,
                    144: #endif
1.1.1.2   root      145:        OPT_MEMSTATE,
1.1.1.9   root      146:        OPT_TOS,                /* ROM options */
                    147:        OPT_PATCHTOS,
                    148:        OPT_CARTRIDGE,
1.1.1.2   root      149:        OPT_CPULEVEL,           /* CPU options */
                    150:        OPT_CPUCLOCK,
1.1       root      151:        OPT_COMPATIBLE,
1.1.1.8   root      152: #if ENABLE_WINUAE_CPU
                    153:        OPT_CPU_CYCLE_EXACT,    /* WinUAE CPU/FPU/bus options */
                    154:        OPT_CPU_ADDR24,
                    155:        OPT_FPU_TYPE,
1.1.1.14  root      156: /*     OPT_FPU_JIT_COMPAT, */
1.1.1.15  root      157:        OPT_FPU_SOFTFLOAT,
1.1.1.8   root      158:        OPT_MMU,
                    159: #endif
1.1.1.2   root      160:        OPT_MACHINE,            /* system options */
1.1       root      161:        OPT_BLITTER,
1.1.1.2   root      162:        OPT_DSP,
1.1.1.9   root      163:        OPT_TIMERD,
                    164:        OPT_FASTBOOT,
                    165:        OPT_MICROPHONE,         /* sound options */
1.1.1.2   root      166:        OPT_SOUND,
1.1.1.7   root      167:        OPT_SOUNDBUFFERSIZE,
1.1.1.10  root      168:        OPT_SOUNDSYNC,
1.1.1.8   root      169:        OPT_YM_MIXING,
1.1.1.11  root      170: #ifdef WIN32
                    171:        OPT_WINCON,             /* debug options */
                    172: #endif
                    173:        OPT_DEBUG,
1.1.1.12  root      174:        OPT_EXCEPTIONS,
1.1.1.4   root      175:        OPT_BIOSINTERCEPT,
1.1.1.11  root      176:        OPT_CONOUT,
                    177:        OPT_DISASM,
                    178:        OPT_NATFEATS,
1.1.1.2   root      179:        OPT_TRACE,
1.1.1.4   root      180:        OPT_TRACEFILE,
1.1.1.7   root      181:        OPT_PARSE,
                    182:        OPT_SAVECONFIG,
                    183:        OPT_PARACHUTE,
1.1.1.4   root      184:        OPT_CONTROLSOCKET,
1.1.1.16! root      185:        OPT_CMDFIFO,
1.1.1.4   root      186:        OPT_LOGFILE,
                    187:        OPT_LOGLEVEL,
                    188:        OPT_ALERTLEVEL,
1.1.1.6   root      189:        OPT_RUNVBLS,
1.1.1.15  root      190:        OPT_BENCHMARK,
1.1.1.4   root      191:        OPT_ERROR,
                    192:        OPT_CONTINUE
1.1       root      193: };
                    194: 
                    195: typedef struct {
                    196:        unsigned int id;        /* option ID */
                    197:        const char *chr;        /* short option */
                    198:        const char *str;        /* long option */
1.1.1.2   root      199:        const char *arg;        /* type name for argument, if any */
1.1       root      200:        const char *desc;       /* option description */
                    201: } opt_t;
                    202: 
1.1.1.2   root      203: /* it's easier to edit these if they are kept in the same order as the enums */
1.1       root      204: static const opt_t HatariOptions[] = {
1.1.1.2   root      205:        
                    206:        { OPT_HEADER, NULL, NULL, NULL, "General" },
1.1       root      207:        { OPT_HELP,      "-h", "--help",
                    208:          NULL, "Print this help text and exit" },
                    209:        { OPT_VERSION,   "-v", "--version",
1.1.1.2   root      210:          NULL, "Print version number and exit" },
1.1.1.4   root      211:        { OPT_CONFIRMQUIT, NULL, "--confirm-quit",
1.1.1.2   root      212:          "<bool>", "Whether Hatari confirms quit" },
1.1.1.4   root      213:        { OPT_CONFIGFILE, "-c", "--configfile",
1.1.1.11  root      214:          "<file>", "Read (additional) configuration values from <file>" },
1.1.1.8   root      215:        { OPT_KEYMAPFILE, "-k", "--keymap",
                    216:          "<file>", "Read (additional) keyboard mappings from <file>" },
1.1.1.4   root      217:        { OPT_FASTFORWARD, NULL, "--fast-forward",
                    218:          "<bool>", "Help skipping stuff on fast machine" },
1.1.1.15  root      219:        { OPT_AUTOSTART, NULL, "--auto",
                    220:          "<x>", "Atari program autostarting with Atari path" },
1.1.1.4   root      221: 
1.1.1.8   root      222:        { OPT_HEADER, NULL, NULL, NULL, "Common display" },
1.1       root      223:        { OPT_MONO,      "-m", "--mono",
                    224:          NULL, "Start in monochrome mode instead of color" },
1.1.1.2   root      225:        { OPT_MONITOR,      NULL, "--monitor",
                    226:          "<x>", "Select monitor type (x = mono/rgb/vga/tv)" },
1.1.1.15  root      227:        { OPT_TOS_RESOLUTION,   NULL, "--tos-res",
                    228:          "<x>", "TOS resolution (x = low/med/high/ttlow/ttmed)" },
1.1       root      229:        { OPT_FULLSCREEN,"-f", "--fullscreen",
                    230:          NULL, "Start emulator in fullscreen mode" },
                    231:        { OPT_WINDOW,    "-w", "--window",
1.1.1.12  root      232:          NULL, "Start emulator in windowed mode" },
1.1.1.6   root      233:        { OPT_GRAB, NULL, "--grab",
1.1.1.12  root      234:          NULL, "Grab mouse (also) in windowed mode" },
1.1.1.15  root      235:        { OPT_RESIZABLE,    NULL, "--resizable",
                    236:          "<bool>", "Allow window resizing" },
1.1.1.2   root      237:        { OPT_FRAMESKIPS, NULL, "--frameskips",
1.1.1.4   root      238:          "<x>", "Skip <x> frames after each shown frame (0=off, >4=auto/max)" },
1.1.1.12  root      239:        { OPT_SLOWDOWN, NULL, "--slowdown",
1.1.1.16! root      240:          "<x>", "VBL wait time multiplier (1-30, default 1)" },
1.1.1.13  root      241:        { OPT_MOUSE_WARP, NULL, "--mousewarp",
                    242:          "<bool>", "Center host mouse on reset & resolution changes" },
1.1.1.4   root      243:        { OPT_STATUSBAR, NULL, "--statusbar",
                    244:          "<bool>", "Show statusbar (floppy leds etc)" },
                    245:        { OPT_DRIVE_LED,   NULL, "--drive-led",
                    246:          "<bool>", "Show overlay drive led when statusbar isn't shown" },
1.1.1.12  root      247:        { OPT_MAXWIDTH, NULL, "--max-width",
                    248:          "<x>", "Maximum window width for borders & zooming" },
                    249:        { OPT_MAXHEIGHT, NULL, "--max-height",
                    250:          "<x>", "Maximum window height for borders & zooming" },
1.1.1.2   root      251:        { OPT_FORCEBPP, NULL, "--bpp",
1.1.1.14  root      252:          "<x>", "Force internal bitdepth (x = 15/16/32, 0=disable)" },
1.1.1.15  root      253:        { OPT_DISABLE_VIDEO,   NULL, "--disable-video",
                    254:          "<bool>", "Run emulation without displaying video (audio only)" },
1.1.1.7   root      255: 
1.1.1.8   root      256:        { OPT_HEADER, NULL, NULL, NULL, "ST/STE specific display" },
                    257:        { OPT_BORDERS, NULL, "--borders",
                    258:          "<bool>", "Show screen borders (for overscan demos etc)" },
1.1.1.9   root      259:        { OPT_RESOLUTION_ST, NULL, "--desktop-st",
1.1.1.12  root      260:          "<bool>", "Keep desktop resolution on fullscreen" },
1.1.1.8   root      261:        { OPT_SPEC512, NULL, "--spec512",
                    262:          "<x>", "Spec512 palette threshold (0 <= x <= 512, 0=disable)" },
                    263:        { OPT_ZOOM, "-z", "--zoom",
                    264:          "<x>", "Double small resolutions (1=no, 2=yes)" },
1.1.1.14  root      265:        { OPT_VIDEO_TIMING,   NULL, "--video-timing",
                    266:          "<x>", "Wakeup State for MMU/GLUE (x=ws1/ws2/ws3/ws4/random, default ws3)" },
1.1.1.8   root      267: 
1.1.1.12  root      268:        { OPT_HEADER, NULL, NULL, NULL, "TT/Falcon specific display" },
1.1.1.8   root      269:        { OPT_RESOLUTION, NULL, "--desktop",
                    270:          "<bool>", "Keep desktop resolution on fullscreen" },
1.1.1.9   root      271:        { OPT_FORCE_MAX, NULL, "--force-max",
                    272:          "<bool>", "Resolution fixed to given max values" },
1.1.1.8   root      273:        { OPT_ASPECT, NULL, "--aspect",
                    274:          "<bool>", "Monitor aspect ratio correction" },
                    275: 
1.1.1.2   root      276:        { OPT_HEADER, NULL, NULL, NULL, "VDI" },
1.1.1.4   root      277:        { OPT_VDI,      NULL, "--vdi",
                    278:          "<bool>", "Whether to use VDI screen mode" },
1.1.1.2   root      279:        { OPT_VDI_PLANES,NULL, "--vdi-planes",
1.1.1.4   root      280:          "<x>", "VDI mode bit-depth (x = 1/2/4)" },
1.1.1.2   root      281:        { OPT_VDI_WIDTH,     NULL, "--vdi-width",
1.1.1.16! root      282:          "<w>", "VDI mode width (320 < w <= 2048)" },
1.1.1.2   root      283:        { OPT_VDI_HEIGHT,     NULL, "--vdi-height",
1.1.1.16! root      284:          "<h>", "VDI mode height (200 < h <= 1280)" },
1.1.1.7   root      285: 
1.1.1.8   root      286:        { OPT_HEADER, NULL, NULL, NULL, "Screen capture" },
                    287:        { OPT_SCREEN_CROP, NULL, "--crop",
                    288:          "<bool>", "Remove statusbar from screen capture" },
1.1.1.7   root      289:        { OPT_AVIRECORD, NULL, "--avirecord",
                    290:          NULL, "Start AVI recording" },
                    291:        { OPT_AVIRECORD_VCODEC, NULL, "--avi-vcodec",
1.1.1.13  root      292:          "<x>", "Select AVI video codec (x = bmp/png)" },
                    293:        { OPT_AVI_PNG_LEVEL, NULL, "--png-level",
                    294:          "<x>", "Select AVI PNG compression level (x = 0-9)" },
1.1.1.7   root      295:        { OPT_AVIRECORD_FPS, NULL, "--avi-fps",
1.1.1.13  root      296:          "<x>", "Force AVI frame rate (x = 50/60/71/...)" },
1.1.1.7   root      297:        { OPT_AVIRECORD_FILE, NULL, "--avi-file",
1.1.1.13  root      298:          "<file>", "Use <file> to record AVI" },
1.1.1.7   root      299: 
1.1.1.2   root      300:        { OPT_HEADER, NULL, NULL, NULL, "Devices" },
1.1       root      301:        { OPT_JOYSTICK,  "-j", "--joystick",
1.1.1.2   root      302:          "<port>", "Emulate joystick with cursor keys in given port (0-5)" },
1.1.1.4   root      303:        /* these have to be exactly the same as I'm relying compiler giving
                    304:         * them the same same string pointer when strings are identical
1.1.1.7   root      305:         * (Opt_ShowHelpSection() skips successive options with same help
                    306:         * pointer).
1.1.1.4   root      307:         */
                    308:        { OPT_JOYSTICK0, NULL, "--joy<port>",
                    309:          "<type>", "Set joystick type (none/keys/real) for given port" },
                    310:        { OPT_JOYSTICK1, NULL, "--joy<port>",
                    311:          "<type>", "Set joystick type (none/keys/real) for given port" },
                    312:        { OPT_JOYSTICK2, NULL, "--joy<port>",
                    313:          "<type>", "Set joystick type (none/keys/real) for given port" },
                    314:        { OPT_JOYSTICK3, NULL, "--joy<port>",
                    315:          "<type>", "Set joystick type (none/keys/real) for given port" },
                    316:        { OPT_JOYSTICK4, NULL, "--joy<port>",
                    317:          "<type>", "Set joystick type (none/keys/real) for given port" },
                    318:        { OPT_JOYSTICK5, NULL, "--joy<port>",
                    319:          "<type>", "Set joystick type (none/keys/real) for given port" },
1.1       root      320:        { OPT_PRINTER,   NULL, "--printer",
1.1.1.2   root      321:          "<file>", "Enable printer support and write data to <file>" },
1.1.1.15  root      322: #ifdef HAVE_PORTMIDI
                    323:        { OPT_MIDI,   NULL, "--midi",
                    324:          "<bool>", "Whether to use MIDI (with PortMidi devices)" },
                    325: #else
1.1.1.5   root      326:        { OPT_MIDI_IN,   NULL, "--midi-in",
                    327:          "<file>", "Enable MIDI and use <file> as the input device" },
                    328:        { OPT_MIDI_OUT,  NULL, "--midi-out",
                    329:          "<file>", "Enable MIDI and use <file> as the output device" },
1.1.1.15  root      330: #endif
1.1.1.5   root      331:        { OPT_RS232_IN,  NULL, "--rs232-in",
                    332:          "<file>", "Enable serial port and use <file> as the input device" },
                    333:        { OPT_RS232_OUT, NULL, "--rs232-out",
                    334:          "<file>", "Enable serial port and use <file> as the output device" },
1.1.1.16! root      335:        //{ OPT_SCCB, NULL, "--scc-b",
        !           336:        //  "<file>", "Enable SCC channel B and use <file> as the device" },
        !           337:        //{ OPT_SCCBIN, NULL, "--scc-b-in",
        !           338:        //  "<file>", "Enable SCC channel B and use <file> as the input" },
        !           339:        { OPT_SCCBOUT, NULL, "--scc-b-out",
        !           340:          "<file>", "Enable SCC channel B and use <file> as the output" },
        !           341: 
1.1.1.13  root      342:        { OPT_HEADER, NULL, NULL, NULL, "Floppy drive" },
1.1.1.12  root      343:        { OPT_DRIVEA, NULL, "--drive-a",
                    344:          "<bool>", "Enable/disable drive A (default is on)" },
                    345:        { OPT_DRIVEB, NULL, "--drive-b",
                    346:          "<bool>", "Enable/disable drive B (default is on)" },
                    347:        { OPT_DRIVEA_HEADS, NULL, "--drive-a-heads",
                    348:          "<x>", "Set number of heads for drive A (1=single sided, 2=double sided)" },
                    349:        { OPT_DRIVEB_HEADS, NULL, "--drive-b-heads",
                    350:          "<x>", "Set number of heads for drive B (1=single sided, 2=double sided)" },
1.1.1.4   root      351:        { OPT_DISKA, NULL, "--disk-a",
                    352:          "<file>", "Set disk image for floppy drive A" },
                    353:        { OPT_DISKB, NULL, "--disk-b",
                    354:          "<file>", "Set disk image for floppy drive B" },
1.1.1.9   root      355:        { OPT_FASTFLOPPY,   NULL, "--fastfdc",
                    356:          "<bool>", "Speed up floppy disk access emulation (can break some programs)" },
1.1.1.7   root      357:        { OPT_WRITEPROT_FLOPPY, NULL, "--protect-floppy",
                    358:          "<x>", "Write protect floppy image contents (on/off/auto)" },
1.1.1.13  root      359: 
                    360:        { OPT_HEADER, NULL, NULL, NULL, "Hard drive" },
                    361:        { OPT_HARDDRIVE, "-d", "--harddrive",
                    362:          "<dir>", "Emulate harddrive partition(s) with <dir> contents" },
1.1.1.7   root      363:        { OPT_WRITEPROT_HD, NULL, "--protect-hd",
                    364:          "<x>", "Write protect harddrive <dir> contents (on/off/auto)" },
1.1.1.11  root      365:        { OPT_GEMDOS_CASE, NULL, "--gemdos-case",
                    366:          "<x>", "Forcibly up/lowercase new GEMDOS dir/filenames (off/upper/lower)" },
1.1.1.15  root      367:        { OPT_GEMDOS_HOSTTIME, NULL, "--gemdos-time",
                    368:          "<x>", "Which timestamps to use for GEMDOS files (atari/host)" },
1.1.1.13  root      369:        { OPT_GEMDOS_CONVERT, NULL, "--gemdos-conv",
                    370:          "<bool>", "Atari GEMDOS <-> host (UTF-8) file name conversion" },
                    371:        { OPT_GEMDOS_DRIVE, NULL, "--gemdos-drive",
                    372:          "<drive>", "Assign GEMDOS HD <dir> to drive letter <drive> (C-Z, skip)" },
1.1.1.2   root      373:        { OPT_ACSIHDIMAGE,   NULL, "--acsi",
1.1.1.13  root      374:          "<id>=<file>", "Emulate an ACSI harddrive (0-7) with an image <file>" },
1.1.1.16! root      375:        { OPT_SCSIHDIMAGE,   NULL, "--scsi",
        !           376:          "<id>=<file>", "Emulate a SCSI harddrive (0-7) with an image <file>" },
1.1.1.7   root      377:        { OPT_IDEMASTERHDIMAGE,   NULL, "--ide-master",
1.1.1.16! root      378:          "<file>", "Emulate an IDE 0 (master) harddrive with an image <file>" },
1.1.1.7   root      379:        { OPT_IDESLAVEHDIMAGE,   NULL, "--ide-slave",
1.1.1.16! root      380:          "<file>", "Emulate an IDE 1 (slave) harddrive with an image <file>" },
        !           381:        { OPT_IDEBYTESWAP,   NULL, "--ide-swap",
        !           382:          "<id>=<x>", "Set IDE (0/1) byte-swap option (off/on/auto)" },
        !           383: 
1.1.1.2   root      384:        { OPT_HEADER, NULL, NULL, NULL, "Memory" },
                    385:        { OPT_MEMSIZE,   "-s", "--memsize",
1.1.1.15  root      386:          "<x>", "ST RAM size (x = size in MiB from 0 to 14, 0 = 512KiB ; else size in KiB)" },
1.1.1.13  root      387: #if ENABLE_WINUAE_CPU
                    388:        { OPT_TT_RAM,   NULL, "--ttram",
                    389:          "<x>", "TT RAM size (x = size in MiB from 0 to 256)" },
                    390: #endif
1.1.1.9   root      391:        { OPT_MEMSTATE,   NULL, "--memstate",
                    392:          "<file>", "Load memory snap-shot <file>" },
                    393: 
                    394:        { OPT_HEADER, NULL, NULL, NULL, "ROM" },
1.1       root      395:        { OPT_TOS,       "-t", "--tos",
                    396:          "<file>", "Use TOS image <file>" },
1.1.1.9   root      397:        { OPT_PATCHTOS, NULL, "--patch-tos",
                    398:          "<bool>", "Apply TOS patches (experts only, leave it enabled!)" },
1.1       root      399:        { OPT_CARTRIDGE, NULL, "--cartridge",
                    400:          "<file>", "Use ROM cartridge image <file>" },
1.1.1.9   root      401: 
1.1.1.14  root      402: #if ENABLE_WINUAE_CPU
                    403:        { OPT_HEADER, NULL, NULL, NULL, "CPU/FPU/bus" },
                    404: #else
1.1.1.2   root      405:        { OPT_HEADER, NULL, NULL, NULL, "CPU" },
1.1.1.14  root      406: #endif
1.1       root      407:        { OPT_CPULEVEL,  NULL, "--cpulevel",
1.1.1.2   root      408:          "<x>", "Set the CPU type (x => 680x0) (EmuTOS/TOS 2.06 only!)" },
                    409:        { OPT_CPUCLOCK,  NULL, "--cpuclock",
1.1.1.4   root      410:          "<x>", "Set the CPU clock (x = 8/16/32)" },
                    411:        { OPT_COMPATIBLE, NULL, "--compatible",
1.1.1.16! root      412:          "<bool>", "Use a more compatible (but slower) prefetch mode for CPU" },
1.1.1.8   root      413: #if ENABLE_WINUAE_CPU
                    414:        { OPT_CPU_CYCLE_EXACT, NULL, "--cpu-exact",
                    415:          "<bool>", "Use cycle exact CPU emulation" },
                    416:        { OPT_CPU_ADDR24, NULL, "--addr24",
                    417:          "<bool>", "Use 24-bit instead of 32-bit addressing mode" },
1.1.1.14  root      418:        { OPT_FPU_TYPE, NULL, "--fpu",
1.1.1.8   root      419:          "<x>", "FPU type (x=none/68881/68882/internal)" },
1.1.1.14  root      420:        /*{ OPT_FPU_JIT_COMPAT, NULL, "--fpu-compatible",
                    421:          "<bool>", "Use more compatible, but slower FPU JIT emulation" },*/
1.1.1.15  root      422:        { OPT_FPU_SOFTFLOAT, NULL, "--fpu-softfloat",
                    423:          "<bool>", "Use full software FPU emulation" },
1.1.1.8   root      424:        { OPT_MMU, NULL, "--mmu",
                    425:          "<bool>", "Use MMU emulation" },
                    426: #endif
                    427: 
1.1.1.2   root      428:        { OPT_HEADER, NULL, NULL, NULL, "Misc system" },
                    429:        { OPT_MACHINE,   NULL, "--machine",
1.1.1.14  root      430:          "<x>", "Select machine type (x = st/megast/ste/megaste/tt/falcon)" },
1.1       root      431:        { OPT_BLITTER,   NULL, "--blitter",
1.1.1.2   root      432:          "<bool>", "Use blitter emulation (ST only)" },
                    433:        { OPT_DSP,       NULL, "--dsp",
1.1.1.4   root      434:          "<x>", "DSP emulation (x = none/dummy/emu, Falcon only)" },
1.1.1.9   root      435:        { OPT_TIMERD,    NULL, "--timer-d",
                    436:          "<bool>", "Patch Timer-D (about doubles ST emulation speed)" },
                    437:        { OPT_FASTBOOT, NULL, "--fast-boot",
                    438:          "<bool>", "Patch TOS and memvalid system variables for faster boot" },
                    439: 
                    440:        { OPT_HEADER, NULL, NULL, NULL, "Sound" },
1.1.1.8   root      441:        { OPT_MICROPHONE,   NULL, "--mic",
                    442:          "<bool>", "Enable/disable (Falcon only) microphone" },
1.1.1.2   root      443:        { OPT_SOUND,   NULL, "--sound",
1.1.1.6   root      444:          "<x>", "Sound frequency (x=off/6000-50066, off=fastest)" },
1.1.1.7   root      445:        { OPT_SOUNDBUFFERSIZE,   NULL, "--sound-buffer-size",
1.1.1.9   root      446:          "<x>", "Sound buffer size in ms (x=0/10-100, 0=default)" },
1.1.1.10  root      447:        { OPT_SOUNDSYNC,   NULL, "--sound-sync",
                    448:          "<bool>", "Sound synchronized emulation (on|off, off=default)" },
1.1.1.8   root      449:        { OPT_YM_MIXING,   NULL, "--ym-mixing",
1.1.1.9   root      450:          "<x>", "YM sound mixing method (x=linear/table/model)" },
1.1.1.8   root      451: 
1.1.1.2   root      452:        { OPT_HEADER, NULL, NULL, NULL, "Debug" },
1.1.1.11  root      453: #ifdef WIN32
                    454:        { OPT_WINCON, "-W", "--wincon",
                    455:          NULL, "Open console window (Windows only)" },
                    456: #endif
1.1.1.2   root      457:        { OPT_DEBUG,     "-D", "--debug",
1.1.1.6   root      458:          NULL, "Toggle whether CPU exceptions invoke debugger" },
1.1.1.12  root      459:        { OPT_EXCEPTIONS, NULL, "--debug-except",
                    460:          "<flags>", "Exceptions invoking debugger, see '--debug-except help'" },
1.1.1.4   root      461:        { OPT_BIOSINTERCEPT, NULL, "--bios-intercept",
1.1.1.16! root      462:          "<bool>", "Enable/disable XBIOS command parsing support" },
1.1.1.11  root      463:        { OPT_CONOUT,   NULL, "--conout",
                    464:          "<device>", "Show console output (0-7, 2=VT-52 terminal)" },
                    465:        { OPT_DISASM,   NULL, "--disasm",
                    466:          "<x>", "Set disassembly options (help/uae/ext/<bitmask>)" },
                    467:        { OPT_NATFEATS, NULL, "--natfeats",
                    468:          "<bool>", "Whether Native Features support is enabled" },
1.1.1.2   root      469:        { OPT_TRACE,   NULL, "--trace",
1.1.1.12  root      470:          "<flags>", "Activate emulation tracing, see '--trace help'" },
1.1.1.4   root      471:        { OPT_TRACEFILE, NULL, "--trace-file",
                    472:          "<file>", "Save trace output to <file> (default=stderr)" },
1.1.1.7   root      473:        { OPT_PARSE, NULL, "--parse",
                    474:          "<file>", "Parse/execute debugger commands from <file>" },
                    475:        { OPT_SAVECONFIG, NULL, "--saveconfig",
                    476:          NULL, "Save current Hatari configuration and exit" },
                    477:        { OPT_PARACHUTE, NULL, "--no-parachute",
                    478:          NULL, "Disable SDL parachute to get Hatari core dumps" },
1.1.1.4   root      479: #if HAVE_UNIX_DOMAIN_SOCKETS
                    480:        { OPT_CONTROLSOCKET, NULL, "--control-socket",
1.1.1.16! root      481:          "<file>", "Hatari connects to given socket for commands" },
        !           482:        { OPT_CMDFIFO, NULL, "--cmd-fifo",
        !           483:          "<file>", "Hatari creates & reads commands from given fifo" },
1.1.1.4   root      484: #endif
                    485:        { OPT_LOGFILE, NULL, "--log-file",
                    486:          "<file>", "Save log output to <file> (default=stderr)" },
                    487:        { OPT_LOGLEVEL, NULL, "--log-level",
                    488:          "<x>", "Log output level (x=debug/todo/info/warn/error/fatal)" },
                    489:        { OPT_ALERTLEVEL, NULL, "--alert-level",
                    490:          "<x>", "Show dialog for log messages above given level" },
1.1.1.6   root      491:        { OPT_RUNVBLS, NULL, "--run-vbls",
                    492:          "<x>", "Exit after x VBLs" },
1.1.1.15  root      493:        { OPT_BENCHMARK, NULL, "--benchmark",
                    494:          NULL, "Start in benchmark mode (use with --run-vbls)" },
1.1.1.4   root      495: 
                    496:        { OPT_ERROR, NULL, NULL, NULL, NULL }
1.1       root      497: };
                    498: 
1.1.1.2   root      499: 
                    500: /**
                    501:  * Show version string and license.
1.1       root      502:  */
1.1.1.2   root      503: static void Opt_ShowVersion(void)
                    504: {
1.1.1.4   root      505:        printf("\n" PROG_NAME
                    506:               " - the Atari ST, STE, TT and Falcon emulator.\n\n");
1.1.1.2   root      507:        printf("Hatari is free software licensed under the GNU General"
                    508:               " Public License.\n\n");
                    509: }
                    510: 
                    511: 
                    512: /**
                    513:  * Calculate option + value len
                    514:  */
                    515: static unsigned int Opt_OptionLen(const opt_t *opt)
                    516: {
                    517:        unsigned int len;
                    518:        len = strlen(opt->str);
                    519:        if (opt->arg)
                    520:        {
                    521:                len += strlen(opt->arg);
                    522:                len += 1;
                    523:                /* with arg, short options go to another line */
                    524:        }
                    525:        else
                    526:        {
                    527:                if (opt->chr)
                    528:                {
                    529:                        /* ' or -c' */
                    530:                        len += 6;
                    531:                }
                    532:        }
                    533:        return len;
                    534: }
                    535: 
                    536: 
                    537: /**
                    538:  * Show single option
                    539:  */
                    540: static void Opt_ShowOption(const opt_t *opt, unsigned int maxlen)
1.1       root      541: {
                    542:        char buf[64];
1.1.1.2   root      543:        if (!maxlen)
                    544:        {
                    545:                maxlen = Opt_OptionLen(opt);
                    546:        }
                    547:        assert(maxlen < sizeof(buf));
                    548:        if (opt->arg)
                    549:        {
                    550:                sprintf(buf, "%s %s", opt->str, opt->arg);
                    551:                printf("  %-*s %s\n", maxlen, buf, opt->desc);
                    552:                if (opt->chr)
                    553:                {
                    554:                        printf("    or %s %s\n", opt->chr, opt->arg);
                    555:                }
                    556:        }
                    557:        else
                    558:        {
                    559:                if (opt->chr)
                    560:                {
                    561:                        sprintf(buf, "%s or %s", opt->str, opt->chr);
                    562:                        printf("  %-*s %s\n", maxlen, buf, opt->desc);
1.1       root      563:                }
1.1.1.2   root      564:                else
                    565:                {
                    566:                        printf("  %-*s %s\n", maxlen, opt->str, opt->desc);
                    567:                }
                    568:        }
                    569: }
                    570: 
                    571: /**
                    572:  * Show options for section starting from 'start_opt',
                    573:  * return next option after this section.
                    574:  */
                    575: static const opt_t *Opt_ShowHelpSection(const opt_t *start_opt)
                    576: {
                    577:        const opt_t *opt, *last;
                    578:        unsigned int len, maxlen = 0;
1.1.1.4   root      579:        const char *previous = NULL;
1.1.1.2   root      580: 
                    581:        /* find longest option name and check option IDs */
1.1.1.4   root      582:        for (opt = start_opt; opt->id != OPT_HEADER && opt->id != OPT_ERROR; opt++)
1.1.1.2   root      583:        {
                    584:                len = Opt_OptionLen(opt);
                    585:                if (len > maxlen)
                    586:                {
1.1       root      587:                        maxlen = len;
                    588:                }
                    589:        }
1.1.1.2   root      590:        last = opt;
1.1       root      591:        
                    592:        /* output all options */
1.1.1.2   root      593:        for (opt = start_opt; opt != last; opt++)
                    594:        {
1.1.1.4   root      595:                if (previous != opt->str)
                    596:                {
                    597:                        Opt_ShowOption(opt, maxlen);
                    598:                }
                    599:                previous = opt->str;
1.1.1.2   root      600:        }
                    601:        return last;
                    602: }
                    603: 
                    604: 
                    605: /**
                    606:  * Show help text.
                    607:  */
                    608: static void Opt_ShowHelp(void)
                    609: {
                    610:        const opt_t *opt = HatariOptions;
                    611: 
                    612:        Opt_ShowVersion();
1.1.1.8   root      613:        printf("Usage:\n hatari [options] [directory|disk image|Atari program]\n");
1.1.1.2   root      614: 
1.1.1.4   root      615:        while(opt->id != OPT_ERROR)
1.1.1.2   root      616:        {
                    617:                if (opt->id == OPT_HEADER)
                    618:                {
                    619:                        assert(opt->desc);
                    620:                        printf("\n%s options:\n", opt->desc);
                    621:                        opt++;
1.1       root      622:                }
1.1.1.2   root      623:                opt = Opt_ShowHelpSection(opt);
1.1       root      624:        }
1.1.1.2   root      625:        printf("\nSpecial option values:\n");
                    626:        printf("<bool>\tDisable by using 'n', 'no', 'off', 'false', or '0'\n");
                    627:        printf("\tEnable by using 'y', 'yes', 'on', 'true' or '1'\n");
                    628:        printf("<file>\tDevices accept also special 'stdout' and 'stderr' file names\n");
                    629:        printf("\t(if you use stdout for midi or printer, set log to stderr).\n");
                    630:        printf("\tSetting the file to 'none', disables given device or disk\n");
                    631: }
                    632: 
                    633: 
                    634: /**
1.1.1.4   root      635:  * Show Hatari version and usage.
1.1.1.2   root      636:  * If 'error' given, show that error message.
1.1.1.4   root      637:  * If 'optid' != OPT_ERROR, tells for which option the error is,
1.1.1.2   root      638:  * otherwise 'value' is show as the option user gave.
1.1.1.6   root      639:  * Return false if error string was given, otherwise true
1.1.1.2   root      640:  */
1.1.1.15  root      641: bool Opt_ShowError(unsigned int optid, const char *value, const char *error)
1.1.1.2   root      642: {
                    643:        const opt_t *opt;
                    644: 
                    645:        Opt_ShowVersion();
                    646:        printf("Usage:\n hatari [options] [disk image name]\n\n"
                    647:               "Try option \"-h\" or \"--help\" to display more information.\n");
                    648: 
                    649:        if (error)
                    650:        {
1.1.1.4   root      651:                if (optid == OPT_ERROR)
1.1.1.2   root      652:                {
1.1       root      653:                        fprintf(stderr, "\nError: %s (%s)\n", error, value);
                    654:                }
1.1.1.2   root      655:                else
                    656:                {
1.1.1.4   root      657:                        for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2   root      658:                        {
                    659:                                if (optid == opt->id)
                    660:                                        break;
                    661:                        }
                    662:                        if (value != NULL)
                    663:                        {
1.1.1.6   root      664:                                fprintf(stderr,
                    665:                                        "\nError while parsing argument \"%s\" for option \"%s\":\n"
                    666:                                        "  %s\n", value, opt->str, error);
1.1.1.2   root      667:                        }
                    668:                        else
                    669:                        {
                    670:                                fprintf(stderr, "\nError (%s): %s\n", opt->str, error);
                    671:                        }
1.1.1.6   root      672:                        fprintf(stderr, "\nOption usage:\n");
1.1.1.2   root      673:                        Opt_ShowOption(opt, 0);
                    674:                }
1.1.1.6   root      675:                return false;
1.1       root      676:        }
1.1.1.6   root      677:        return true;
1.1       root      678: }
                    679: 
1.1.1.2   root      680: 
                    681: /**
1.1.1.13  root      682:  * Return given value after constraining it within "min" and "max" values
                    683:  * and making it evenly divisable by "align"
                    684:  */
                    685: int Opt_ValueAlignMinMax(int value, int align, int min, int max)
                    686: {
                    687:        value = (value/align)*align;
                    688:        if (value > max)
                    689:        {
                    690:                /* align down */
                    691:                return (max/align)*align;
                    692:        }
                    693:        if (value < min)
                    694:        {
                    695:                /* align up */
                    696:                min += align-1;
                    697:                return (min/align)*align;
                    698:        }
                    699:        return value;
                    700: }
                    701: 
                    702: 
                    703: /**
1.1.1.4   root      704:  * If 'conf' given, set it:
1.1.1.6   root      705:  * - true if given option 'arg' is y/yes/on/true/1
                    706:  * - false if given option 'arg' is n/no/off/false/0
                    707:  * Return false for any other value, otherwise true
1.1.1.2   root      708:  */
1.1.1.4   root      709: static bool Opt_Bool(const char *arg, int optid, bool *conf)
1.1.1.2   root      710: {
                    711:        const char *enablers[] = { "y", "yes", "on", "true", "1", NULL };
                    712:        const char *disablers[] = { "n", "no", "off", "false", "0", NULL };
                    713:        const char **bool_str, *orig = arg;
                    714:        char *input, *str;
                    715: 
                    716:        input = strdup(arg);
                    717:        str = input;
                    718:        while (*str)
                    719:        {
1.1.1.12  root      720:                *str++ = tolower((unsigned char)*arg++);
1.1.1.2   root      721:        }
                    722:        for (bool_str = enablers; *bool_str; bool_str++)
                    723:        {
                    724:                if (strcmp(input, *bool_str) == 0)
                    725:                {
                    726:                        free(input);
1.1.1.4   root      727:                        if (conf)
                    728:                        {
1.1.1.6   root      729:                                *conf = true;
1.1.1.4   root      730:                        }
1.1.1.6   root      731:                        return true;
1.1.1.2   root      732:                }
                    733:        }
                    734:        for (bool_str = disablers; *bool_str; bool_str++)
                    735:        {
                    736:                if (strcmp(input, *bool_str) == 0)
                    737:                {
                    738:                        free(input);
1.1.1.4   root      739:                        if (conf)
                    740:                        {
1.1.1.6   root      741:                                *conf = false;
1.1.1.4   root      742:                        }
1.1.1.6   root      743:                        return true;
1.1.1.2   root      744:                }
                    745:        }
                    746:        free(input);
1.1.1.4   root      747:        return Opt_ShowError(optid, orig, "Not a <bool> value");
                    748: }
                    749: 
                    750: 
                    751: /**
                    752:  * checks str argument agaist options of type "--option<digit>".
                    753:  * If match is found, returns ID for that, otherwise OPT_CONTINUE
                    754:  * and OPT_ERROR for errors.
                    755:  */
                    756: static int Opt_CheckBracketValue(const opt_t *opt, const char *str)
                    757: {
                    758:        const char *bracket, *optstr;
                    759:        size_t offset;
                    760:        int digit, i;
                    761: 
                    762:        if (!opt->str)
                    763:        {
                    764:                return OPT_CONTINUE;
                    765:        }
                    766:        bracket = strchr(opt->str, '<');
                    767:        if (!bracket)
                    768:        {
                    769:                return OPT_CONTINUE;
                    770:        }
                    771:        offset = bracket - opt->str;
1.1.1.7   root      772:        if (strncmp(opt->str, str, offset) != 0)
1.1.1.4   root      773:        {
                    774:                return OPT_CONTINUE;
                    775:        }
                    776:        digit = str[offset] - '0';
                    777:        if (digit < 0 || digit > 9)
                    778:        {
                    779:                return OPT_CONTINUE;
                    780:        }
1.1.1.13  root      781:        if (str[offset+1])
                    782:        {
                    783:                return OPT_CONTINUE;
                    784:        }
1.1.1.4   root      785:        optstr = opt->str;
                    786:        for (i = 0; opt->str == optstr; opt++, i++)
                    787:        {
                    788:                if (i == digit)
                    789:                {
                    790:                        return opt->id;
                    791:                }
                    792:        }
                    793:        /* fprintf(stderr, "opt: %s (%d), str: %s (%d), digit: %d\n",
                    794:                opt->str, offset+1, str, strlen(str), digit);
                    795:         */
                    796:        return OPT_ERROR;
1.1.1.2   root      797: }
                    798: 
                    799: 
                    800: /**
1.1       root      801:  * matches string under given index in the argv against all Hatari
                    802:  * short and long options. If match is found, returns ID for that,
1.1.1.4   root      803:  * otherwise shows help and returns OPT_ERROR.
1.1       root      804:  * 
                    805:  * Checks also that if option is supposed to have argument,
                    806:  * whether there's one.
                    807:  */
1.1.1.8   root      808: static int Opt_WhichOption(int argc, const char * const argv[], int idx)
1.1       root      809: {
                    810:        const opt_t *opt;
                    811:        const char *str = argv[idx];
1.1.1.4   root      812:        int id;
1.1       root      813: 
1.1.1.4   root      814:        for (opt = HatariOptions; opt->id != OPT_ERROR; opt++)
1.1.1.2   root      815:        {       
1.1.1.7   root      816:                /* exact option name matches? */
                    817:                if (!((opt->str && !strcmp(str, opt->str)) ||
                    818:                      (opt->chr && !strcmp(str, opt->chr))))
1.1.1.2   root      819:                {
1.1.1.7   root      820:                        /* no, maybe name<digit> matches? */
                    821:                        id = Opt_CheckBracketValue(opt, str);
                    822:                        if (id == OPT_CONTINUE)
                    823:                        {
                    824:                                continue;
                    825:                        }
                    826:                        if (id == OPT_ERROR)
                    827:                        {
                    828:                                break;
                    829:                        }
                    830:                }
                    831:                /* matched, check args */
                    832:                if (opt->arg)
                    833:                {
                    834:                        if (idx+1 >= argc)
                    835:                        {
                    836:                                Opt_ShowError(opt->id, NULL, "Missing argument");
                    837:                                return OPT_ERROR;
                    838:                        }
                    839:                        /* early check for bools */
                    840:                        if (strcmp(opt->arg, "<bool>") == 0)
1.1.1.2   root      841:                        {
1.1.1.7   root      842:                                if (!Opt_Bool(argv[idx+1], opt->id, NULL))
1.1.1.2   root      843:                                {
1.1.1.4   root      844:                                        return OPT_ERROR;
1.1.1.2   root      845:                                }
1.1       root      846:                        }
1.1.1.4   root      847:                }
1.1.1.7   root      848:                return opt->id;
1.1       root      849:        }
1.1.1.4   root      850:        Opt_ShowError(OPT_ERROR, argv[idx], "Unrecognized option");
                    851:        return OPT_ERROR;
1.1       root      852: }
                    853: 
1.1.1.2   root      854: 
                    855: /**
1.1.1.6   root      856:  * If 'checkexits' is true, assume 'src' is a file and check whether it
1.1.1.4   root      857:  * exists before copying 'src' to 'dst'. Otherwise just copy option src
                    858:  * string to dst.
1.1.1.6   root      859:  * If a pointer to (bool) 'option' is given, set that option to true.
                    860:  * - However, if src is "none", leave dst unmodified & set option to false.
1.1.1.4   root      861:  *   ("none" is used to disable options related to file arguments)
1.1.1.6   root      862:  * Return false if there were errors, otherwise true
1.1.1.2   root      863:  */
1.1.1.4   root      864: static bool Opt_StrCpy(int optid, bool checkexist, char *dst, const char *src, size_t dstlen, bool *option)
1.1.1.2   root      865: {
1.1.1.7   root      866:        if (option)
                    867:        {
                    868:                *option = false;
                    869:                if(strcasecmp(src, "none") == 0)
                    870:                {
                    871:                        return true;
                    872:                }
                    873:        }
1.1.1.4   root      874:        if (strlen(src) >= dstlen)
                    875:        {
                    876:                return Opt_ShowError(optid, src, "File name too long!");
                    877:        }
                    878:        if (checkexist && !File_Exists(src))
                    879:        {
1.1.1.13  root      880:                return Opt_ShowError(optid, src, "Given file doesn't exist or permissions prevent access to it!");
1.1.1.4   root      881:        }
1.1.1.2   root      882:        if (option)
                    883:        {
1.1.1.7   root      884:                *option = true;
1.1.1.2   root      885:        }
1.1.1.4   root      886:        strcpy(dst, src);
1.1.1.6   root      887:        return true;
1.1.1.2   root      888: }
                    889: 
                    890: 
                    891: /**
1.1.1.7   root      892:  * Return SDL_INIT_NOPARACHUTE flag if user requested SDL parachute
                    893:  * to be disabled to get proper Hatari core dumps.  By default returns
                    894:  * zero so that SDL parachute will be used to restore video mode on
                    895:  * unclean Hatari termination.
                    896:  */
                    897: Uint32 Opt_GetNoParachuteFlag(void)
                    898: {
1.1.1.16! root      899:        if (bNoSDLParachute)
1.1.1.7   root      900:                return SDL_INIT_NOPARACHUTE;
1.1.1.16! root      901: 
1.1.1.7   root      902:        return 0;
                    903: }
                    904: 
                    905: 
                    906: /**
1.1.1.15  root      907:  * Do final validation for the earlier + parsed options
                    908:  *
                    909:  * Return false if they fail validation.
                    910:  */
                    911: static bool Opt_ValidateOptions(void)
                    912: {
                    913:        const char *err, *val;
                    914:        int opt_id;
                    915: 
                    916:        if ((opt_id = INF_ValidateAutoStart(&val, &err)))
                    917:        {
                    918:                return Opt_ShowError(opt_id, val, err);
                    919:        }
                    920:        return true;
                    921: }
                    922: 
                    923: 
                    924: /**
1.1.1.13  root      925:  * Return true if given path points to an Atari program, false otherwise.
1.1.1.8   root      926:  */
1.1.1.13  root      927: bool Opt_IsAtariProgram(const char *path)
1.1.1.8   root      928: {
1.1.1.13  root      929:        bool ret = false;
1.1.1.8   root      930:        Uint8 test[2];
                    931:        FILE *fp;
                    932: 
1.1.1.16! root      933:        if (File_Exists(path) && (fp = fopen(path, "rb")))
        !           934:        {
1.1.1.8   root      935:                /* file starts with GEMDOS magic? */
                    936:                if (fread(test, 1, 2, fp) == 2 &&
1.1.1.16! root      937:                    test[0] == 0x60 && test[1] == 0x1A)
        !           938:                {
1.1.1.13  root      939:                        ret = true;
1.1.1.8   root      940:                }
                    941:                fclose(fp);
                    942:        }
1.1.1.13  root      943:        return ret;
                    944: }
                    945: 
                    946: /**
                    947:  * Handle last (non-option) argument.  It can be a path or filename.
                    948:  * Filename can be a disk image or Atari program.
                    949:  * Return false if it's none of these.
                    950:  */
                    951: static bool Opt_HandleArgument(const char *path)
                    952: {
                    953:        char *dir = NULL;
                    954: 
                    955:        /* Atari program? */
1.1.1.16! root      956:        if (Opt_IsAtariProgram(path))
        !           957:        {
1.1.1.13  root      958:                const char *prgname = strrchr(path, PATHSEP);
1.1.1.16! root      959:                if (prgname)
        !           960:                {
1.1.1.13  root      961:                        dir = strdup(path);
                    962:                        dir[prgname-path] = '\0';
                    963:                        prgname++;
1.1.1.16! root      964:                }
        !           965:                else
        !           966:                {
1.1.1.13  root      967:                        dir = strdup(Paths_GetWorkingDir());
                    968:                        prgname = path;
                    969:                }
1.1.1.16! root      970:                Log_Printf(LOG_DEBUG, "ARG = autostart program: %s\n", prgname);
1.1.1.14  root      971: 
1.1.1.13  root      972:                /* after above, dir should point to valid dir,
                    973:                 * then make sure that given program from that
                    974:                 * dir will be started.
                    975:                 */
1.1.1.16! root      976:                if (bUseTos)
        !           977:                {
        !           978:                        INF_SetAutoStart(prgname, OPT_AUTOSTART);
        !           979:                }
        !           980:                else
        !           981:                {
        !           982:                        TOS_SetTestPrgName(path);
        !           983:                }
1.1.1.13  root      984:        }
1.1.1.16! root      985:        if (dir)
        !           986:        {
1.1.1.8   root      987:                path = dir;
                    988:        }
                    989: 
                    990:        /* GEMDOS HDD directory (as argument, or for the Atari program)? */
1.1.1.16! root      991:        if (File_DirExists(path))
        !           992:        {
        !           993:                Log_Printf(LOG_DEBUG, "ARG = GEMDOS HD dir: %s\n", path);
1.1.1.8   root      994:                if (Opt_StrCpy(OPT_HARDDRIVE, false, ConfigureParams.HardDisk.szHardDiskDirectories[0],
                    995:                               path, sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
                    996:                               &ConfigureParams.HardDisk.bUseHardDiskDirectories)
                    997:                    && ConfigureParams.HardDisk.bUseHardDiskDirectories)
                    998:                {
                    999:                        ConfigureParams.HardDisk.bBootFromHardDisk = true;
                   1000:                }
                   1001:                bLoadAutoSave = false;
1.1.1.16! root     1002:                if (dir)
        !          1003:                {
1.1.1.8   root     1004:                        free(dir);
                   1005:                }
                   1006:                return true;
1.1.1.16! root     1007:        }
        !          1008:        else
        !          1009:        {
        !          1010:                if (dir)
        !          1011:                {
1.1.1.8   root     1012:                        /* if dir is set, it should be valid... */
                   1013:                        Log_Printf(LOG_ERROR, "Given atari program path '%s' doesn't exist (anymore?)!\n", dir);
                   1014:                        free(dir);
                   1015:                        exit(1);
                   1016:                }
                   1017:        }
                   1018: 
                   1019:        /* disk image? */
                   1020:        if (Floppy_SetDiskFileName(0, path, NULL))
                   1021:        {
1.1.1.16! root     1022:                Log_Printf(LOG_DEBUG, "ARG = floppy image: %s\n", path);
1.1.1.8   root     1023:                ConfigureParams.HardDisk.bBootFromHardDisk = false;
                   1024:                bLoadAutoSave = false;
                   1025:                return true;
                   1026:        }
                   1027: 
                   1028:        return Opt_ShowError(OPT_ERROR, path, "Not a disk image, Atari program or directory");
                   1029: }
                   1030: 
                   1031: /**
1.1.1.4   root     1032:  * parse all Hatari command line options and set Hatari state accordingly.
1.1.1.6   root     1033:  * Returns true if everything was OK, false otherwise.
1.1.1.2   root     1034:  */
1.1.1.8   root     1035: bool Opt_ParseParameters(int argc, const char * const argv[])
1.1       root     1036: {
1.1.1.13  root     1037:        int ncpu, skips, zoom, planes, cpuclock, threshold, memsize, port, freq, temp, drive;
                   1038:        const char *errstr, *str;
1.1.1.6   root     1039:        int i, ok = true;
1.1.1.7   root     1040:        int val;
1.1.1.2   root     1041: 
                   1042:        /* Defaults for loading initial memory snap-shots */
1.1.1.6   root     1043:        bLoadMemorySave = false;
1.1.1.2   root     1044:        bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
                   1045: 
                   1046:        for(i = 1; i < argc; i++)
1.1.1.4   root     1047:        {
1.1.1.8   root     1048:                /* last argument can be a non-option */
                   1049:                if (argv[i][0] != '-' && i+1 == argc)
1.1.1.15  root     1050:                        return Opt_HandleArgument(argv[i]) && Opt_ValidateOptions();
1.1.1.9   root     1051: 
1.1       root     1052:                /* WhichOption() checks also that there is an argument,
                   1053:                 * so we don't need to check that below
                   1054:                 */
1.1.1.2   root     1055:                switch(Opt_WhichOption(argc, argv, i))
                   1056:                {
1.1.1.9   root     1057: 
1.1.1.2   root     1058:                        /* general options */
1.1       root     1059:                case OPT_HELP:
1.1.1.2   root     1060:                        Opt_ShowHelp();
1.1.1.6   root     1061:                        return false;
1.1.1.9   root     1062: 
1.1       root     1063:                case OPT_VERSION:
1.1.1.2   root     1064:                        Opt_ShowVersion();
1.1.1.6   root     1065:                        return false;
1.1.1.2   root     1066: 
                   1067:                case OPT_CONFIRMQUIT:
1.1.1.4   root     1068:                        ok = Opt_Bool(argv[++i], OPT_CONFIRMQUIT, &ConfigureParams.Log.bConfirmQuit);
                   1069:                        break;
                   1070: 
                   1071:                case OPT_FASTFORWARD:
                   1072:                        ok = Opt_Bool(argv[++i], OPT_FASTFORWARD, &ConfigureParams.System.bFastForward);
1.1       root     1073:                        break;
1.1.1.9   root     1074: 
1.1.1.15  root     1075:                case OPT_AUTOSTART:
                   1076:                        if (!(ok = INF_SetAutoStart(argv[++i], OPT_AUTOSTART)))
                   1077:                        {
                   1078:                                return Opt_ShowError(OPT_AUTOSTART, argv[i], "Invalid drive and/or path specified for autostart program");
                   1079:                        }
                   1080:                        break;
                   1081: 
1.1.1.2   root     1082:                case OPT_CONFIGFILE:
                   1083:                        i += 1;
1.1.1.7   root     1084:                        /* true -> file needs to exist */
1.1.1.6   root     1085:                        ok = Opt_StrCpy(OPT_CONFIGFILE, true, sConfigFileName,
1.1.1.4   root     1086:                                        argv[i], sizeof(sConfigFileName), NULL);
                   1087:                        if (ok)
                   1088:                        {
                   1089:                                Configuration_Load(NULL);
                   1090:                                bLoadAutoSave = ConfigureParams.Memory.bAutoSave;
                   1091:                        }
1.1.1.2   root     1092:                        break;
1.1.1.9   root     1093: 
1.1.1.8   root     1094:                        /* common display options */
1.1       root     1095:                case OPT_MONO:
1.1.1.4   root     1096:                        ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.6   root     1097:                        bLoadAutoSave = false;
1.1.1.2   root     1098:                        break;
                   1099: 
                   1100:                case OPT_MONITOR:
                   1101:                        i += 1;
                   1102:                        if (strcasecmp(argv[i], "mono") == 0)
                   1103:                        {
1.1.1.4   root     1104:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_MONO;
1.1.1.2   root     1105:                        }
                   1106:                        else if (strcasecmp(argv[i], "rgb") == 0)
                   1107:                        {
1.1.1.4   root     1108:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_RGB;
1.1.1.2   root     1109:                        }
                   1110:                        else if (strcasecmp(argv[i], "vga") == 0)
                   1111:                        {
1.1.1.4   root     1112:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_VGA;
1.1.1.2   root     1113:                        }
                   1114:                        else if (strcasecmp(argv[i], "tv") == 0)
                   1115:                        {
1.1.1.4   root     1116:                                ConfigureParams.Screen.nMonitorType = MONITOR_TYPE_TV;
1.1.1.2   root     1117:                        }
                   1118:                        else
                   1119:                        {
1.1.1.4   root     1120:                                return Opt_ShowError(OPT_MONITOR, argv[i], "Unknown monitor type");
1.1.1.2   root     1121:                        }
1.1.1.6   root     1122:                        bLoadAutoSave = false;
1.1       root     1123:                        break;
1.1.1.9   root     1124: 
1.1.1.15  root     1125:                case OPT_TOS_RESOLUTION:
                   1126:                        i += 1;
                   1127:                        if (!INF_SetResolution(argv[i], OPT_TOS_RESOLUTION))
                   1128:                        {
                   1129:                                return Opt_ShowError(OPT_TOS_RESOLUTION, argv[i], "Invalid resolution");
                   1130:                        }
                   1131:                        break;
                   1132: 
1.1       root     1133:                case OPT_FULLSCREEN:
1.1.1.6   root     1134:                        ConfigureParams.Screen.bFullScreen = true;
1.1       root     1135:                        break;
1.1.1.9   root     1136: 
1.1       root     1137:                case OPT_WINDOW:
1.1.1.6   root     1138:                        ConfigureParams.Screen.bFullScreen = false;
                   1139:                        break;
                   1140: 
                   1141:                case OPT_GRAB:
                   1142:                        bGrabMouse = true;
1.1       root     1143:                        break;
1.1.1.9   root     1144: 
1.1.1.15  root     1145:                case OPT_RESIZABLE:
                   1146: #if WITH_SDL2
                   1147:                        ok = Opt_Bool(argv[++i], OPT_RESIZABLE, &ConfigureParams.Screen.bResizable);
                   1148: #else
                   1149:                        fprintf(stderr, "The --resizable option is supported only in SDL2 build!\n");
                   1150:                        i++;
                   1151: #endif
                   1152:                        break;
                   1153: 
1.1.1.2   root     1154:                case OPT_FRAMESKIPS:
                   1155:                        skips = atoi(argv[++i]);
1.1.1.6   root     1156:                        if (skips < 0)
1.1.1.2   root     1157:                        {
1.1.1.4   root     1158:                                return Opt_ShowError(OPT_FRAMESKIPS, argv[i],
                   1159:                                                     "Invalid frame skip value");
1.1.1.2   root     1160:                        }
1.1.1.6   root     1161:                        else if (skips > 8)
                   1162:                        {
                   1163:                                Log_Printf(LOG_WARN, "Extravagant frame skip value %d!\n", skips);
                   1164:                        }
1.1.1.4   root     1165:                        ConfigureParams.Screen.nFrameSkips = skips;
1.1       root     1166:                        break;
1.1.1.9   root     1167: 
1.1.1.12  root     1168:                case OPT_SLOWDOWN:
1.1.1.16! root     1169:                        val = atoi(argv[++i]);
        !          1170:                        errstr = Main_SetVBLSlowdown(val);
        !          1171:                        if (errstr)
1.1.1.12  root     1172:                        {
1.1.1.16! root     1173:                                return Opt_ShowError(OPT_SLOWDOWN, argv[i], errstr);
1.1.1.12  root     1174:                        }
1.1.1.16! root     1175:                        Log_Printf(LOG_DEBUG, "Slow down host VBL wait by factor of %d.\n", val);
1.1.1.12  root     1176:                        break;
                   1177: 
1.1.1.13  root     1178:                case OPT_MOUSE_WARP:
                   1179:                        ok = Opt_Bool(argv[++i], OPT_MOUSE_WARP, &ConfigureParams.Screen.bMouseWarp);
                   1180:                        break;
                   1181: 
1.1.1.4   root     1182:                case OPT_STATUSBAR:
                   1183:                        ok = Opt_Bool(argv[++i], OPT_STATUSBAR, &ConfigureParams.Screen.bShowStatusbar);
                   1184:                        break;
1.1.1.9   root     1185: 
1.1.1.4   root     1186:                case OPT_DRIVE_LED:
                   1187:                        ok = Opt_Bool(argv[++i], OPT_DRIVE_LED, &ConfigureParams.Screen.bShowDriveLed);
1.1       root     1188:                        break;
1.1.1.9   root     1189: 
1.1.1.2   root     1190:                case OPT_FORCEBPP:
                   1191:                        planes = atoi(argv[++i]);
1.1.1.3   root     1192:                        switch(planes)
1.1.1.2   root     1193:                        {
1.1.1.3   root     1194:                        case 32:
                   1195:                        case 16:
                   1196:                        case 15:
                   1197:                                break;       /* supported */
                   1198:                        case 24:
                   1199:                                planes = 32; /* We do not support 24 bpp (yet) */
                   1200:                                break;
                   1201:                        default:
1.1.1.4   root     1202:                                return Opt_ShowError(OPT_FORCEBPP, argv[i], "Invalid bit depth");
1.1.1.2   root     1203:                        }
1.1.1.16! root     1204:                        Log_Printf(LOG_DEBUG, "Hatari window BPP = %d.\n", planes);
1.1.1.2   root     1205:                        ConfigureParams.Screen.nForceBpp = planes;
                   1206:                        break;
1.1.1.9   root     1207: 
1.1.1.15  root     1208:                case OPT_DISABLE_VIDEO:
                   1209:                        ok = Opt_Bool(argv[++i], OPT_DISABLE_VIDEO, &ConfigureParams.Screen.DisableVideo);
                   1210:                        break;
                   1211: 
1.1.1.8   root     1212:                        /* ST/STE display options */
                   1213:                case OPT_BORDERS:
                   1214:                        ok = Opt_Bool(argv[++i], OPT_BORDERS, &ConfigureParams.Screen.bAllowOverscan);
                   1215:                        break;
1.1.1.9   root     1216: 
                   1217:                case OPT_RESOLUTION_ST:
1.1.1.14  root     1218: #if WITH_SDL2
1.1.1.15  root     1219:                        fprintf(stderr, "The --desktop-st option is not supported in SDL2 build!\n");
1.1.1.14  root     1220:                        i++;
                   1221: #else
1.1.1.9   root     1222:                        ok = Opt_Bool(argv[++i], OPT_RESOLUTION_ST, &ConfigureParams.Screen.bKeepResolutionST);
1.1.1.14  root     1223: #endif
1.1.1.9   root     1224:                        break;
1.1.1.8   root     1225:                        
                   1226:                case OPT_SPEC512:
                   1227:                        threshold = atoi(argv[++i]);
                   1228:                        if (threshold < 0 || threshold > 512)
                   1229:                        {
                   1230:                                return Opt_ShowError(OPT_SPEC512, argv[i],
                   1231:                                                     "Invalid palette writes per line threshold for Spec512");
                   1232:                        }
1.1.1.16! root     1233:                        Log_Printf(LOG_DEBUG, "Spec512 threshold = %d palette writes per line.\n", threshold);
1.1.1.8   root     1234:                        ConfigureParams.Screen.nSpec512Threshold = threshold;
                   1235:                        break;
                   1236: 
                   1237:                case OPT_ZOOM:
                   1238:                        zoom = atoi(argv[++i]);
                   1239:                        if (zoom < 1)
                   1240:                        {
                   1241:                                return Opt_ShowError(OPT_ZOOM, argv[i], "Invalid zoom value");
                   1242:                        }
1.1.1.13  root     1243:                        ConfigureParams.Screen.nMaxWidth = NUM_VISIBLE_LINE_PIXELS;
                   1244:                        ConfigureParams.Screen.nMaxHeight = NUM_VISIBLE_LINES;
1.1.1.8   root     1245:                        if (zoom > 1)
                   1246:                        {
1.1.1.13  root     1247:                                ConfigureParams.Screen.nMaxWidth *= 2;
                   1248:                                ConfigureParams.Screen.nMaxHeight *= 2;
1.1.1.8   root     1249:                        }
1.1.1.13  root     1250:                        ConfigureParams.Screen.nMaxHeight += STATUSBAR_MAX_HEIGHT;
1.1.1.8   root     1251:                        break;
                   1252: 
1.1.1.14  root     1253:                case OPT_VIDEO_TIMING:
                   1254:                        i += 1;
                   1255:                        if (strcasecmp(argv[i], "random") == 0)
                   1256:                                ConfigureParams.System.VideoTimingMode = VIDEO_TIMING_MODE_RANDOM;
                   1257:                        else if (strcasecmp(argv[i], "ws1") == 0)
                   1258:                                ConfigureParams.System.VideoTimingMode = VIDEO_TIMING_MODE_WS1;
                   1259:                        else if (strcasecmp(argv[i], "ws2") == 0)
                   1260:                                ConfigureParams.System.VideoTimingMode = VIDEO_TIMING_MODE_WS2;
                   1261:                        else if (strcasecmp(argv[i], "ws3") == 0)
                   1262:                                ConfigureParams.System.VideoTimingMode = VIDEO_TIMING_MODE_WS3;
                   1263:                        else if (strcasecmp(argv[i], "ws4") == 0)
                   1264:                                ConfigureParams.System.VideoTimingMode = VIDEO_TIMING_MODE_WS4;
                   1265:                        else
                   1266:                                return Opt_ShowError(OPT_VIDEO_TIMING, argv[i], "Unknown video timing mode");
                   1267:                        break;
                   1268: 
1.1.1.8   root     1269:                        /* Falcon/TT display options */
                   1270:                case OPT_RESOLUTION:
                   1271:                        ok = Opt_Bool(argv[++i], OPT_RESOLUTION, &ConfigureParams.Screen.bKeepResolution);
                   1272:                        break;
                   1273:                        
                   1274:                case OPT_MAXWIDTH:
                   1275:                        ConfigureParams.Screen.nMaxWidth = atoi(argv[++i]);
                   1276:                        break;
                   1277: 
                   1278:                case OPT_MAXHEIGHT:
                   1279:                        ConfigureParams.Screen.nMaxHeight = atoi(argv[++i]);
                   1280:                        break;
1.1.1.9   root     1281: 
                   1282:                case OPT_FORCE_MAX:
                   1283:                        ok = Opt_Bool(argv[++i], OPT_FORCE_MAX, &ConfigureParams.Screen.bForceMax);
                   1284:                        break;
1.1.1.8   root     1285:                        
                   1286:                case OPT_ASPECT:
                   1287:                        ok = Opt_Bool(argv[++i], OPT_ASPECT, &ConfigureParams.Screen.bAspectCorrect);
                   1288:                        break;
                   1289: 
                   1290:                        /* screen capture options */
                   1291:                case OPT_SCREEN_CROP:
                   1292:                        ok = Opt_Bool(argv[++i], OPT_SCREEN_CROP, &ConfigureParams.Screen.bCrop);
                   1293:                        break;
1.1.1.2   root     1294: 
1.1.1.7   root     1295:                case OPT_AVIRECORD:
                   1296:                        AviRecordOnStartup = true;
                   1297:                        break;
                   1298: 
                   1299:                case OPT_AVIRECORD_VCODEC:
                   1300:                        i += 1;
                   1301:                        if (strcasecmp(argv[i], "bmp") == 0)
                   1302:                        {
1.1.1.8   root     1303:                                ConfigureParams.Video.AviRecordVcodec = AVI_RECORD_VIDEO_CODEC_BMP;
1.1.1.7   root     1304:                        }
                   1305:                        else if (strcasecmp(argv[i], "png") == 0)
                   1306:                        {
1.1.1.8   root     1307:                                ConfigureParams.Video.AviRecordVcodec = AVI_RECORD_VIDEO_CODEC_PNG;
1.1.1.7   root     1308:                        }
                   1309:                        else
                   1310:                        {
                   1311:                                return Opt_ShowError(OPT_AVIRECORD_VCODEC, argv[i], "Unknown video codec");
                   1312:                        }
                   1313:                        break;
                   1314: 
1.1.1.13  root     1315:                case OPT_AVI_PNG_LEVEL:
                   1316:                        i += 1;
                   1317:                        if (!Avi_SetCompressionLevel(argv[i]))
                   1318:                                return Opt_ShowError(OPT_AVI_PNG_LEVEL, argv[i], "Invalid compression level");
                   1319:                        break;
                   1320: 
1.1.1.7   root     1321:                case OPT_AVIRECORD_FPS:
                   1322:                        val = atoi(argv[++i]);
                   1323:                        if (val < 0 || val > 100)
                   1324:                        {
                   1325:                                return Opt_ShowError(OPT_AVIRECORD_FPS, argv[i],
                   1326:                                                        "Invalid frame rate for avi recording");
                   1327:                        }
1.1.1.16! root     1328:                        Log_Printf(LOG_DEBUG, "AVI recording FPS = %d.\n", val);
1.1.1.8   root     1329:                        ConfigureParams.Video.AviRecordFps = val;
1.1.1.7   root     1330:                        break;
                   1331: 
                   1332:                case OPT_AVIRECORD_FILE:
                   1333:                        i += 1;
                   1334:                        /* false -> file is created if it doesn't exist */
1.1.1.8   root     1335:                        ok = Opt_StrCpy(OPT_AVIRECORD_FILE, false, ConfigureParams.Video.AviRecordFile,
                   1336:                                        argv[i], sizeof(ConfigureParams.Video.AviRecordFile), NULL);
1.1.1.7   root     1337:                        break;
                   1338: 
1.1.1.4   root     1339:                        /* VDI options */
                   1340:                case OPT_VDI:
                   1341:                        ok = Opt_Bool(argv[++i], OPT_VDI, &ConfigureParams.Screen.bUseExtVdiResolutions);
                   1342:                        if (ok)
                   1343:                        {
1.1.1.6   root     1344:                                bLoadAutoSave = false;
1.1.1.4   root     1345:                        }
                   1346:                        break;
                   1347: 
1.1.1.2   root     1348:                case OPT_VDI_PLANES:
                   1349:                        planes = atoi(argv[++i]);
                   1350:                        switch(planes)
                   1351:                        {
                   1352:                         case 1:
                   1353:                                ConfigureParams.Screen.nVdiColors = GEMCOLOR_2;
                   1354:                                break;
                   1355:                         case 2:
                   1356:                                ConfigureParams.Screen.nVdiColors = GEMCOLOR_4;
                   1357:                                break;
                   1358:                         case 4:
                   1359:                                ConfigureParams.Screen.nVdiColors = GEMCOLOR_16;
                   1360:                                break;
                   1361:                         default:
1.1.1.4   root     1362:                                return Opt_ShowError(OPT_VDI_PLANES, argv[i], "Unsupported VDI bit-depth");
1.1.1.2   root     1363:                        }
1.1.1.6   root     1364:                        ConfigureParams.Screen.bUseExtVdiResolutions = true;
                   1365:                        bLoadAutoSave = false;
1.1.1.2   root     1366:                        break;
                   1367: 
                   1368:                case OPT_VDI_WIDTH:
                   1369:                        ConfigureParams.Screen.nVdiWidth = atoi(argv[++i]);
1.1.1.6   root     1370:                        ConfigureParams.Screen.bUseExtVdiResolutions = true;
                   1371:                        bLoadAutoSave = false;
1.1.1.2   root     1372:                        break;
                   1373: 
                   1374:                case OPT_VDI_HEIGHT:
                   1375:                        ConfigureParams.Screen.nVdiHeight = atoi(argv[++i]);
1.1.1.6   root     1376:                        ConfigureParams.Screen.bUseExtVdiResolutions = true;
                   1377:                        bLoadAutoSave = false;
1.1.1.2   root     1378:                        break;
1.1.1.7   root     1379: 
1.1.1.2   root     1380:                        /* devices options */
                   1381:                case OPT_JOYSTICK:
                   1382:                        i++;
                   1383:                        if (strlen(argv[i]) != 1 ||
                   1384:                            !Joy_SetCursorEmulation(argv[i][0] - '0'))
                   1385:                        {
1.1.1.4   root     1386:                                return Opt_ShowError(OPT_JOYSTICK, argv[i], "Invalid joystick port");
                   1387:                        }
                   1388:                        break;
                   1389: 
                   1390:                case OPT_JOYSTICK0:
                   1391:                case OPT_JOYSTICK1:
                   1392:                case OPT_JOYSTICK2:
                   1393:                case OPT_JOYSTICK3:
                   1394:                case OPT_JOYSTICK4:
                   1395:                case OPT_JOYSTICK5:
                   1396:                        port = argv[i][strlen(argv[i])-1] - '0';
1.1.1.13  root     1397:                        if (port < 0 || port >= JOYSTICK_COUNT)
                   1398:                        {
                   1399:                                return Opt_ShowError(OPT_JOYSTICK0, argv[i], "Invalid joystick port");
                   1400:                        }
1.1.1.4   root     1401:                        i += 1;
                   1402:                        if (strcasecmp(argv[i], "none") == 0)
                   1403:                        {
                   1404:                                ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_DISABLED;
                   1405:                        }
                   1406:                        else if (strcasecmp(argv[i], "keys") == 0)
                   1407:                        {
                   1408:                                ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_KEYBOARD;
                   1409:                        }
                   1410:                        else if (strcasecmp(argv[i], "real") == 0)
                   1411:                        {
                   1412:                                ConfigureParams.Joysticks.Joy[port].nJoystickMode = JOYSTICK_REALSTICK;
                   1413:                        }
                   1414:                        else
                   1415:                        {
                   1416:                                return Opt_ShowError(OPT_JOYSTICK0+port, argv[i], "Invalid joystick type");
1.1.1.2   root     1417:                        }
1.1       root     1418:                        break;
1.1.1.9   root     1419: 
1.1       root     1420:                case OPT_PRINTER:
1.1.1.2   root     1421:                        i += 1;
1.1.1.7   root     1422:                        /* "none" can be used to disable printer */
1.1.1.6   root     1423:                        ok = Opt_StrCpy(OPT_PRINTER, false, ConfigureParams.Printer.szPrintToFileName,
1.1.1.4   root     1424:                                        argv[i], sizeof(ConfigureParams.Printer.szPrintToFileName),
                   1425:                                        &ConfigureParams.Printer.bEnablePrinting);
1.1       root     1426:                        break;
1.1.1.9   root     1427: 
1.1.1.15  root     1428: #ifdef HAVE_PORTMIDI
                   1429:                case OPT_MIDI:
                   1430:                        ok = Opt_Bool(argv[++i], OPT_MIDI, &ConfigureParams.Midi.bEnableMidi);
                   1431:                        break;
                   1432: #else
1.1.1.5   root     1433:                case OPT_MIDI_IN:
                   1434:                        i += 1;
1.1.1.7   root     1435:                        ok = Opt_StrCpy(OPT_MIDI_IN, true, ConfigureParams.Midi.sMidiInFileName,
1.1.1.5   root     1436:                                        argv[i], sizeof(ConfigureParams.Midi.sMidiInFileName),
                   1437:                                        &ConfigureParams.Midi.bEnableMidi);
                   1438:                        break;
                   1439:                        
                   1440:                case OPT_MIDI_OUT:
1.1       root     1441:                        i += 1;
1.1.1.7   root     1442:                        ok = Opt_StrCpy(OPT_MIDI_OUT, false, ConfigureParams.Midi.sMidiOutFileName,
1.1.1.5   root     1443:                                        argv[i], sizeof(ConfigureParams.Midi.sMidiOutFileName),
1.1.1.4   root     1444:                                        &ConfigureParams.Midi.bEnableMidi);
1.1       root     1445:                        break;
1.1.1.15  root     1446: #endif
                   1447: 
1.1.1.5   root     1448:                case OPT_RS232_IN:
1.1       root     1449:                        i += 1;
1.1.1.6   root     1450:                        ok = Opt_StrCpy(OPT_RS232_IN, true, ConfigureParams.RS232.szInFileName,
1.1.1.4   root     1451:                                        argv[i], sizeof(ConfigureParams.RS232.szInFileName),
                   1452:                                        &ConfigureParams.RS232.bEnableRS232);
1.1.1.5   root     1453:                        break;
1.1.1.16! root     1454: 
1.1.1.5   root     1455:                case OPT_RS232_OUT:
                   1456:                        i += 1;
1.1.1.7   root     1457:                        ok = Opt_StrCpy(OPT_RS232_OUT, false, ConfigureParams.RS232.szOutFileName,
1.1.1.5   root     1458:                                        argv[i], sizeof(ConfigureParams.RS232.szOutFileName),
                   1459:                                        &ConfigureParams.RS232.bEnableRS232);
1.1       root     1460:                        break;
1.1.1.2   root     1461: 
1.1.1.16! root     1462:                /*
        !          1463:                case OPT_SCCB:
        !          1464:                        i += 1;
        !          1465:                        ok = Opt_StrCpy(OPT_SCCB, true, ConfigureParams.RS232.sSccBInFileName,
        !          1466:                                        argv[i], sizeof(ConfigureParams.RS232.sSccBInFileName),
        !          1467:                                        &ConfigureParams.RS232.bEnableSccB);
        !          1468:                        strcpy(ConfigureParams.RS232.sSccBOutFileName, ConfigureParams.RS232.sSccBInFileName);
        !          1469:                        break;
        !          1470:                case OPT_SCCBIN:
        !          1471:                        i += 1;
        !          1472:                        ok = Opt_StrCpy(OPT_SCCBIN, true, ConfigureParams.RS232.sSccBInFileName,
        !          1473:                                        argv[i], sizeof(ConfigureParams.RS232.sSccBInFileName),
        !          1474:                                        &ConfigureParams.RS232.bEnableSccB);
        !          1475:                        break;
        !          1476:                */
        !          1477:                case OPT_SCCBOUT:
        !          1478:                        i += 1;
        !          1479:                        ok = Opt_StrCpy(OPT_SCCBOUT, false, ConfigureParams.RS232.sSccBOutFileName,
        !          1480:                                        argv[i], sizeof(ConfigureParams.RS232.sSccBOutFileName),
        !          1481:                                        &ConfigureParams.RS232.bEnableSccB);
        !          1482:                        break;
        !          1483: 
1.1.1.2   root     1484:                        /* disk options */
1.1.1.12  root     1485:                case OPT_DRIVEA:
                   1486:                        ok = Opt_Bool(argv[++i], OPT_DRIVEA, &ConfigureParams.DiskImage.EnableDriveA);
                   1487:                        break;
                   1488: 
                   1489:                case OPT_DRIVEB:
                   1490:                        ok = Opt_Bool(argv[++i], OPT_DRIVEB, &ConfigureParams.DiskImage.EnableDriveB);
                   1491:                        break;
                   1492: 
                   1493:                case OPT_DRIVEA_HEADS:
                   1494:                        val = atoi(argv[++i]);
                   1495:                        if(val != 1 && val != 2)
                   1496:                        {
                   1497:                                return Opt_ShowError(OPT_DRIVEA_HEADS, argv[i], "Invalid number of heads");
                   1498:                        }
                   1499:                        ConfigureParams.DiskImage.DriveA_NumberOfHeads = val;
                   1500:                        break;
                   1501: 
                   1502:                case OPT_DRIVEB_HEADS:
                   1503:                        val = atoi(argv[++i]);
                   1504:                        if(val != 1 && val != 2)
                   1505:                        {
                   1506:                                return Opt_ShowError(OPT_DRIVEB_HEADS, argv[i], "Invalid number of heads");
                   1507:                        }
                   1508:                        ConfigureParams.DiskImage.DriveB_NumberOfHeads = val;
                   1509:                        break;
                   1510: 
1.1.1.4   root     1511:                case OPT_DISKA:
                   1512:                        i += 1;
                   1513:                        if (Floppy_SetDiskFileName(0, argv[i], NULL))
                   1514:                        {
1.1.1.6   root     1515:                                ConfigureParams.HardDisk.bBootFromHardDisk = false;
                   1516:                                bLoadAutoSave = false;
1.1.1.4   root     1517:                        }
                   1518:                        else
                   1519:                                return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
                   1520:                        break;
                   1521: 
                   1522:                case OPT_DISKB:
                   1523:                        i += 1;
                   1524:                        if (Floppy_SetDiskFileName(1, argv[i], NULL))
1.1.1.6   root     1525:                                bLoadAutoSave = false;
1.1.1.4   root     1526:                        else
                   1527:                                return Opt_ShowError(OPT_ERROR, argv[i], "Not a disk image");
                   1528:                        break;
                   1529: 
1.1.1.9   root     1530:                case OPT_FASTFLOPPY:
                   1531:                        ok = Opt_Bool(argv[++i], OPT_FASTFLOPPY, &ConfigureParams.DiskImage.FastFloppy);
1.1.1.7   root     1532:                        break;
                   1533: 
                   1534:                case OPT_WRITEPROT_FLOPPY:
                   1535:                        i += 1;
                   1536:                        if (strcasecmp(argv[i], "off") == 0)
                   1537:                                ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_OFF;
                   1538:                        else if (strcasecmp(argv[i], "on") == 0)
                   1539:                                ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_ON;
                   1540:                        else if (strcasecmp(argv[i], "auto") == 0)
                   1541:                                ConfigureParams.DiskImage.nWriteProtection = WRITEPROT_AUTO;
                   1542:                        else
                   1543:                                return Opt_ShowError(OPT_WRITEPROT_FLOPPY, argv[i], "Unknown option value");
                   1544:                        break;
                   1545: 
                   1546:                case OPT_WRITEPROT_HD:
                   1547:                        i += 1;
                   1548:                        if (strcasecmp(argv[i], "off") == 0)
                   1549:                                ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_OFF;
                   1550:                        else if (strcasecmp(argv[i], "on") == 0)
                   1551:                                ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_ON;
                   1552:                        else if (strcasecmp(argv[i], "auto") == 0)
                   1553:                                ConfigureParams.HardDisk.nWriteProtection = WRITEPROT_AUTO;
                   1554:                        else
                   1555:                                return Opt_ShowError(OPT_WRITEPROT_HD, argv[i], "Unknown option value");
                   1556:                        break;
                   1557: 
1.1.1.11  root     1558:                case OPT_GEMDOS_CASE:
                   1559:                        i += 1;
                   1560:                        if (strcasecmp(argv[i], "off") == 0)
                   1561:                                ConfigureParams.HardDisk.nGemdosCase = GEMDOS_NOP;
                   1562:                        else if (strcasecmp(argv[i], "upper") == 0)
                   1563:                                ConfigureParams.HardDisk.nGemdosCase = GEMDOS_UPPER;
                   1564:                        else if (strcasecmp(argv[i], "lower") == 0)
                   1565:                                ConfigureParams.HardDisk.nGemdosCase = GEMDOS_LOWER;
                   1566:                        else
                   1567:                                return Opt_ShowError(OPT_GEMDOS_CASE, argv[i], "Unknown option value");
                   1568:                        break;
                   1569: 
1.1.1.15  root     1570:                case OPT_GEMDOS_HOSTTIME:
                   1571:                        i += 1;
                   1572:                        if (strcasecmp(argv[i], "atari") == 0)
                   1573:                                ConfigureParams.HardDisk.bGemdosHostTime = false;
                   1574:                        else if (strcasecmp(argv[i], "host") == 0)
                   1575:                                ConfigureParams.HardDisk.bGemdosHostTime = true;
                   1576:                        else
                   1577:                                return Opt_ShowError(OPT_GEMDOS_HOSTTIME, argv[i], "Unknown option value");
                   1578:                        break;
                   1579: 
1.1.1.13  root     1580:                case OPT_GEMDOS_CONVERT:
                   1581:                        ok = Opt_Bool(argv[++i], OPT_GEMDOS_CONVERT, &ConfigureParams.HardDisk.bFilenameConversion);
                   1582:                        break;
                   1583: 
                   1584:                case OPT_GEMDOS_DRIVE:
                   1585:                        i += 1;
                   1586:                        if (strcasecmp(argv[i], "skip") == 0)
                   1587:                        {
                   1588:                                ConfigureParams.HardDisk.nGemdosDrive = DRIVE_SKIP;
                   1589:                                break;
                   1590:                        }
                   1591:                        else if (strlen(argv[i]) == 1)
                   1592:                        {
1.1.1.14  root     1593:                                drive = toupper(argv[i][0]);
1.1.1.13  root     1594:                                if (drive >= 'C' && drive <= 'Z')
                   1595:                                {
                   1596:                                        drive = drive - 'C' + DRIVE_C;
                   1597:                                        ConfigureParams.HardDisk.nGemdosDrive = drive;
                   1598:                                        break;
                   1599:                                }
                   1600:                        }
                   1601:                        return Opt_ShowError(OPT_GEMDOS_DRIVE, argv[i], "Invalid <drive>");
                   1602: 
1.1       root     1603:                case OPT_HARDDRIVE:
                   1604:                        i += 1;
1.1.1.6   root     1605:                        ok = Opt_StrCpy(OPT_HARDDRIVE, false, ConfigureParams.HardDisk.szHardDiskDirectories[0],
1.1.1.4   root     1606:                                        argv[i], sizeof(ConfigureParams.HardDisk.szHardDiskDirectories[0]),
                   1607:                                        &ConfigureParams.HardDisk.bUseHardDiskDirectories);
1.1.1.11  root     1608:                        if (ok && ConfigureParams.HardDisk.bUseHardDiskDirectories &&
                   1609:                            ConfigureParams.HardDisk.szHardDiskDirectories[0][0])
1.1.1.2   root     1610:                        {
1.1.1.6   root     1611:                                ConfigureParams.HardDisk.bBootFromHardDisk = true;
1.1       root     1612:                        }
1.1.1.11  root     1613:                        else
                   1614:                        {
                   1615:                                ConfigureParams.HardDisk.bUseHardDiskDirectories = false;
                   1616:                                ConfigureParams.HardDisk.bBootFromHardDisk = false;
                   1617:                        }
1.1.1.6   root     1618:                        bLoadAutoSave = false;
1.1.1.2   root     1619:                        break;
                   1620: 
                   1621:                case OPT_ACSIHDIMAGE:
                   1622:                        i += 1;
1.1.1.13  root     1623:                        str = argv[i];
                   1624:                        if (strlen(str) > 2 && isdigit(str[0]) && str[1] == '=')
                   1625:                        {
                   1626:                                drive = str[0] - '0';
1.1.1.15  root     1627:                                if (drive < 0 || drive >= MAX_ACSI_DEVS)
1.1.1.13  root     1628:                                        return Opt_ShowError(OPT_ACSIHDIMAGE, str, "Invalid ACSI drive <id>, must be 0-7");
                   1629:                                str += 2;
                   1630:                        }
                   1631:                        else
                   1632:                        {
                   1633:                                drive = 0;
                   1634:                        }
                   1635:                        ok = Opt_StrCpy(OPT_ACSIHDIMAGE, true, ConfigureParams.Acsi[drive].sDeviceFile,
                   1636:                                        str, sizeof(ConfigureParams.Acsi[drive].sDeviceFile),
                   1637:                                        &ConfigureParams.Acsi[drive].bUseDevice);
1.1.1.4   root     1638:                        if (ok)
                   1639:                        {
1.1.1.6   root     1640:                                bLoadAutoSave = false;
1.1.1.4   root     1641:                        }
1.1       root     1642:                        break;
1.1.1.9   root     1643: 
1.1.1.16! root     1644:                case OPT_SCSIHDIMAGE:
        !          1645:                        i += 1;
        !          1646:                        str = argv[i];
        !          1647:                        if (strlen(str) > 2 && isdigit(str[0]) && str[1] == '=')
        !          1648:                        {
        !          1649:                                drive = str[0] - '0';
        !          1650:                                if (drive < 0 || drive >= MAX_SCSI_DEVS)
        !          1651:                                        return Opt_ShowError(OPT_SCSIHDIMAGE, str, "Invalid SCSI drive <id>, must be 0-7");
        !          1652:                                str += 2;
        !          1653:                        }
        !          1654:                        else
        !          1655:                        {
        !          1656:                                drive = 0;
        !          1657:                        }
        !          1658:                        ok = Opt_StrCpy(OPT_SCSIHDIMAGE, true, ConfigureParams.Scsi[drive].sDeviceFile,
        !          1659:                                        str, sizeof(ConfigureParams.Scsi[drive].sDeviceFile),
        !          1660:                                        &ConfigureParams.Scsi[drive].bUseDevice);
        !          1661:                        if (ok)
        !          1662:                        {
        !          1663:                                bLoadAutoSave = false;
        !          1664:                        }
        !          1665:                        break;
        !          1666: 
1.1.1.7   root     1667:                case OPT_IDEMASTERHDIMAGE:
1.1       root     1668:                        i += 1;
1.1.1.16! root     1669:                        ok = Opt_StrCpy(OPT_IDEMASTERHDIMAGE, true, ConfigureParams.Ide[0].sDeviceFile,
        !          1670:                                        argv[i], sizeof(ConfigureParams.Ide[0].sDeviceFile),
        !          1671:                                        &ConfigureParams.Ide[0].bUseDevice);
1.1.1.4   root     1672:                        if (ok)
                   1673:                        {
1.1.1.6   root     1674:                                bLoadAutoSave = false;
1.1.1.4   root     1675:                        }
1.1.1.2   root     1676:                        break;
1.1.1.6   root     1677: 
1.1.1.7   root     1678:                case OPT_IDESLAVEHDIMAGE:
                   1679:                        i += 1;
1.1.1.16! root     1680:                        ok = Opt_StrCpy(OPT_IDESLAVEHDIMAGE, true, ConfigureParams.Ide[1].sDeviceFile,
        !          1681:                                        argv[i], sizeof(ConfigureParams.Ide[1].sDeviceFile),
        !          1682:                                        &ConfigureParams.Ide[1].bUseDevice);
1.1.1.7   root     1683:                        if (ok)
                   1684:                        {
                   1685:                                bLoadAutoSave = false;
                   1686:                        }
1.1.1.2   root     1687:                        break;
1.1.1.9   root     1688: 
1.1.1.16! root     1689:                case OPT_IDEBYTESWAP:
        !          1690:                        i += 1;
        !          1691:                        str = argv[i];
        !          1692:                        if (strlen(str) > 2 && isdigit(str[0]) && str[1] == '=')
        !          1693:                        {
        !          1694:                                drive = str[0] - '0';
        !          1695:                                if (drive < 0 || drive > 1)
        !          1696:                                        return Opt_ShowError(OPT_IDEBYTESWAP, str, "Invalid IDE drive <id>, must be 0/1");
        !          1697:                                str += 2;
        !          1698:                        }
        !          1699:                        else
        !          1700:                        {
        !          1701:                                drive = 0;
        !          1702:                        }
        !          1703:                        if (strcasecmp(str, "off") == 0)
        !          1704:                                ConfigureParams.Ide[drive].nByteSwap = BYTESWAP_OFF;
        !          1705:                        else if (strcasecmp(str, "on") == 0)
        !          1706:                                ConfigureParams.Ide[drive].nByteSwap = BYTESWAP_ON;
        !          1707:                        else if (strcasecmp(str, "auto") == 0)
        !          1708:                                ConfigureParams.Ide[drive].nByteSwap = BYTESWAP_AUTO;
        !          1709:                        else
        !          1710:                                return Opt_ShowError(OPT_IDEBYTESWAP, argv[i], "Invalid byte-swap setting");
        !          1711:                        break;
        !          1712: 
1.1.1.2   root     1713:                        /* Memory options */
                   1714:                case OPT_MEMSIZE:
1.1.1.4   root     1715:                        memsize = atoi(argv[++i]);
1.1.1.15  root     1716:                        memsize = STMemory_RAM_Validate_Size_KB ( memsize );
                   1717:                        if (memsize < 0)
1.1.1.2   root     1718:                        {
1.1.1.4   root     1719:                                return Opt_ShowError(OPT_MEMSIZE, argv[i], "Invalid memory size");
1.1       root     1720:                        }
1.1.1.15  root     1721:                        ConfigureParams.Memory.STRamSize_KB = memsize;
1.1.1.6   root     1722:                        bLoadAutoSave = false;
1.1       root     1723:                        break;
1.1.1.9   root     1724: 
1.1.1.13  root     1725: #if ENABLE_WINUAE_CPU
                   1726:                case OPT_TT_RAM:
                   1727:                        memsize = atoi(argv[++i]);
1.1.1.16! root     1728:                        ConfigureParams.Memory.TTRamSize_KB = Opt_ValueAlignMinMax(memsize+3, 4, 0, 512) * 1024;
1.1.1.13  root     1729:                        bLoadAutoSave = false;
                   1730:                        break;
                   1731: #endif
                   1732: 
1.1.1.2   root     1733:                case OPT_TOS:
                   1734:                        i += 1;
1.1.1.6   root     1735:                        ok = Opt_StrCpy(OPT_TOS, true, ConfigureParams.Rom.szTosImageFileName,
1.1.1.4   root     1736:                                        argv[i], sizeof(ConfigureParams.Rom.szTosImageFileName),
1.1.1.16! root     1737:                                        &bUseTos);
        !          1738:                        if (ok || !bUseTos)
1.1.1.4   root     1739:                        {
1.1.1.6   root     1740:                                bLoadAutoSave = false;
1.1.1.4   root     1741:                        }
1.1.1.2   root     1742:                        break;
1.1.1.9   root     1743: 
                   1744:                case OPT_PATCHTOS:
                   1745:                        ok = Opt_Bool(argv[++i], OPT_PATCHTOS, &ConfigureParams.Rom.bPatchTos);
                   1746:                        break;
                   1747: 
1.1       root     1748:                case OPT_CARTRIDGE:
                   1749:                        i += 1;
1.1.1.6   root     1750:                        ok = Opt_StrCpy(OPT_CARTRIDGE, true, ConfigureParams.Rom.szCartridgeImageFileName,
1.1.1.4   root     1751:                                        argv[i], sizeof(ConfigureParams.Rom.szCartridgeImageFileName),
                   1752:                                        NULL);
                   1753:                        if (ok)
                   1754:                        {
1.1.1.6   root     1755:                                bLoadAutoSave = false;
1.1.1.4   root     1756:                        }
1.1.1.2   root     1757:                        break;
                   1758: 
                   1759:                case OPT_MEMSTATE:
                   1760:                        i += 1;
1.1.1.6   root     1761:                        ok = Opt_StrCpy(OPT_MEMSTATE, true, ConfigureParams.Memory.szMemoryCaptureFileName,
1.1.1.4   root     1762:                                        argv[i], sizeof(ConfigureParams.Memory.szMemoryCaptureFileName),
                   1763:                                        NULL);
                   1764:                        if (ok)
                   1765:                        {
1.1.1.6   root     1766:                                bLoadMemorySave = true;
                   1767:                                bLoadAutoSave = false;
1.1.1.4   root     1768:                        }
1.1       root     1769:                        break;
1.1.1.9   root     1770: 
1.1.1.2   root     1771:                        /* CPU options */
1.1       root     1772:                case OPT_CPULEVEL:
                   1773:                        /* UAE core uses cpu_level variable */
1.1.1.2   root     1774:                        ncpu = atoi(argv[++i]);
1.1.1.13  root     1775: #if ENABLE_WINUAE_CPU
                   1776:                        if(ncpu < 0 || ncpu == 5 || ncpu > 6)
                   1777: #else
1.1.1.2   root     1778:                        if(ncpu < 0 || ncpu > 4)
1.1.1.13  root     1779: #endif
1.1.1.2   root     1780:                        {
1.1.1.4   root     1781:                                return Opt_ShowError(OPT_CPULEVEL, argv[i], "Invalid CPU level");
1.1.1.2   root     1782:                        }
1.1.1.13  root     1783:                        if ( ncpu == 6 )                        /* Special case for 68060, nCpuLevel should be 5 */
                   1784:                                ncpu = 5;
1.1.1.2   root     1785:                        ConfigureParams.System.nCpuLevel = ncpu;
1.1.1.6   root     1786:                        bLoadAutoSave = false;
1.1.1.2   root     1787:                        break;
1.1.1.9   root     1788: 
1.1.1.2   root     1789:                case OPT_CPUCLOCK:
                   1790:                        cpuclock = atoi(argv[++i]);
                   1791:                        if(cpuclock != 8 && cpuclock != 16 && cpuclock != 32)
                   1792:                        {
1.1.1.4   root     1793:                                return Opt_ShowError(OPT_CPUCLOCK, argv[i], "Invalid CPU clock");
1.1       root     1794:                        }
1.1.1.15  root     1795:                        Configuration_ChangeCpuFreq ( cpuclock );
1.1.1.6   root     1796:                        bLoadAutoSave = false;
1.1       root     1797:                        break;
1.1.1.9   root     1798: 
1.1       root     1799:                case OPT_COMPATIBLE:
1.1.1.4   root     1800:                        ok = Opt_Bool(argv[++i], OPT_COMPATIBLE, &ConfigureParams.System.bCompatibleCpu);
                   1801:                        if (ok)
                   1802:                        {
1.1.1.6   root     1803:                                bLoadAutoSave = false;
1.1.1.4   root     1804:                        }
1.1       root     1805:                        break;
1.1.1.9   root     1806: #if ENABLE_WINUAE_CPU
                   1807:                case OPT_CPU_ADDR24:
                   1808:                        ok = Opt_Bool(argv[++i], OPT_CPU_ADDR24, &ConfigureParams.System.bAddressSpace24);
                   1809:                        bLoadAutoSave = false;
                   1810:                        break;
                   1811: 
                   1812:                case OPT_CPU_CYCLE_EXACT:
                   1813:                        ok = Opt_Bool(argv[++i], OPT_CPU_CYCLE_EXACT, &ConfigureParams.System.bCycleExactCpu);
                   1814:                        bLoadAutoSave = false;
                   1815:                        break;
                   1816: 
                   1817:                case OPT_FPU_TYPE:
                   1818:                        i += 1;
                   1819:                        if (strcasecmp(argv[i], "none") == 0)
                   1820:                        {
                   1821:                                ConfigureParams.System.n_FPUType = FPU_NONE;
                   1822:                        }
                   1823:                        else if (strcasecmp(argv[i], "68881") == 0)
                   1824:                        {
                   1825:                                ConfigureParams.System.n_FPUType = FPU_68881;
                   1826:                        }
                   1827:                        else if (strcasecmp(argv[i], "68882") == 0)
                   1828:                        {
                   1829:                                ConfigureParams.System.n_FPUType = FPU_68882;
                   1830:                        }
                   1831:                        else if (strcasecmp(argv[i], "internal") == 0)
                   1832:                        {
                   1833:                                ConfigureParams.System.n_FPUType = FPU_CPU;
                   1834:                        }
                   1835:                        else
                   1836:                        {
                   1837:                                return Opt_ShowError(OPT_FPU_TYPE, argv[i], "Unknown FPU type");
                   1838:                        }
                   1839:                        bLoadAutoSave = false;
                   1840:                        break;
1.1.1.14  root     1841: /*
                   1842:                case OPT_FPU_JIT_COMPAT:
1.1.1.9   root     1843:                        ok = Opt_Bool(argv[++i], OPT_FPU_COMPATIBLE, &ConfigureParams.System.bCompatibleFPU);
                   1844:                        break;
1.1.1.14  root     1845: */
1.1.1.15  root     1846:                case OPT_FPU_SOFTFLOAT:
                   1847:                        ok = Opt_Bool(argv[++i], OPT_FPU_SOFTFLOAT, &ConfigureParams.System.bSoftFloatFPU);
                   1848:                        break;
                   1849: 
1.1.1.9   root     1850:                case OPT_MMU:
                   1851:                        ok = Opt_Bool(argv[++i], OPT_MMU, &ConfigureParams.System.bMMU);
                   1852:                        bLoadAutoSave = false;
                   1853:                        break;
                   1854: #endif
1.1.1.2   root     1855: 
                   1856:                        /* system options */
                   1857:                case OPT_MACHINE:
                   1858:                        i += 1;
                   1859:                        if (strcasecmp(argv[i], "st") == 0)
                   1860:                        {
                   1861:                                ConfigureParams.System.nMachineType = MACHINE_ST;
                   1862:                                ConfigureParams.System.nCpuLevel = 0;
1.1.1.15  root     1863:                                Configuration_ChangeCpuFreq ( 8 );
1.1.1.2   root     1864:                        }
1.1.1.14  root     1865:                        else if (strcasecmp(argv[i], "megast") == 0)
                   1866:                        {
                   1867:                                ConfigureParams.System.nMachineType = MACHINE_MEGA_ST;
                   1868:                                ConfigureParams.System.nCpuLevel = 0;
1.1.1.15  root     1869:                                Configuration_ChangeCpuFreq ( 8 );
1.1.1.14  root     1870:                        }
1.1.1.2   root     1871:                        else if (strcasecmp(argv[i], "ste") == 0)
                   1872:                        {
                   1873:                                ConfigureParams.System.nMachineType = MACHINE_STE;
                   1874:                                ConfigureParams.System.nCpuLevel = 0;
1.1.1.15  root     1875:                                Configuration_ChangeCpuFreq ( 8 );
1.1.1.2   root     1876:                        }
1.1.1.14  root     1877:                        else if (strcasecmp(argv[i], "megaste") == 0)
                   1878:                        {
                   1879:                                ConfigureParams.System.nMachineType = MACHINE_MEGA_STE;
                   1880:                                ConfigureParams.System.nCpuLevel = 0;
1.1.1.15  root     1881:                                Configuration_ChangeCpuFreq ( 16 );
1.1.1.14  root     1882:                        }
1.1.1.2   root     1883:                        else if (strcasecmp(argv[i], "tt") == 0)
                   1884:                        {
                   1885:                                ConfigureParams.System.nMachineType = MACHINE_TT;
                   1886:                                ConfigureParams.System.nCpuLevel = 3;
1.1.1.15  root     1887:                                Configuration_ChangeCpuFreq ( 32 );
1.1.1.2   root     1888:                        }
                   1889:                        else if (strcasecmp(argv[i], "falcon") == 0)
                   1890:                        {
1.1.1.8   root     1891: #if ENABLE_DSP_EMU
1.1.1.10  root     1892:                                ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
1.1.1.8   root     1893: #endif
1.1.1.2   root     1894:                                ConfigureParams.System.nMachineType = MACHINE_FALCON;
                   1895:                                ConfigureParams.System.nCpuLevel = 3;
1.1.1.15  root     1896:                                Configuration_ChangeCpuFreq ( 16 );
1.1.1.2   root     1897:                        }
                   1898:                        else
                   1899:                        {
1.1.1.4   root     1900:                                return Opt_ShowError(OPT_MACHINE, argv[i], "Unknown machine type");
1.1.1.2   root     1901:                        }
1.1.1.10  root     1902: #if ENABLE_WINUAE_CPU
1.1.1.14  root     1903:                        if (Config_IsMachineST() || Config_IsMachineSTE())
1.1.1.11  root     1904:                        {
                   1905:                                ConfigureParams.System.bMMU = false;
                   1906:                                ConfigureParams.System.bAddressSpace24 = true;
                   1907:                        }
1.1.1.14  root     1908:                        if (Config_IsMachineTT())
1.1.1.10  root     1909:                        {
                   1910:                                ConfigureParams.System.bCompatibleFPU = true;
                   1911:                                ConfigureParams.System.n_FPUType = FPU_68882;
1.1.1.14  root     1912:                        }
                   1913:                        else
                   1914:                        {
1.1.1.10  root     1915:                                ConfigureParams.System.n_FPUType = FPU_NONE;    /* TODO: or leave it as-is? */
                   1916:                        }
                   1917: #endif
1.1.1.6   root     1918:                        bLoadAutoSave = false;
1.1       root     1919:                        break;
1.1.1.9   root     1920: 
1.1.1.2   root     1921:                case OPT_BLITTER:
1.1.1.4   root     1922:                        ok = Opt_Bool(argv[++i], OPT_BLITTER, &ConfigureParams.System.bBlitter);
                   1923:                        if (ok)
                   1924:                        {
1.1.1.6   root     1925:                                bLoadAutoSave = false;
1.1.1.4   root     1926:                        }
1.1.1.9   root     1927:                        break;
                   1928: 
1.1.1.6   root     1929:                case OPT_TIMERD:
                   1930:                        ok = Opt_Bool(argv[++i], OPT_TIMERD, &ConfigureParams.System.bPatchTimerD);
1.1.1.9   root     1931:                        break;
                   1932:                case OPT_FASTBOOT:
                   1933:                        ok = Opt_Bool(argv[++i], OPT_FASTBOOT, &ConfigureParams.System.bFastBoot);
                   1934:                        break;
                   1935: 
1.1.1.2   root     1936:                case OPT_DSP:
                   1937:                        i += 1;
                   1938:                        if (strcasecmp(argv[i], "none") == 0)
                   1939:                        {
                   1940:                                ConfigureParams.System.nDSPType = DSP_TYPE_NONE;
                   1941:                        }
                   1942:                        else if (strcasecmp(argv[i], "dummy") == 0)
                   1943:                        {
                   1944:                                ConfigureParams.System.nDSPType = DSP_TYPE_DUMMY;
                   1945:                        }
                   1946:                        else if (strcasecmp(argv[i], "emu") == 0)
                   1947:                        {
                   1948: #if ENABLE_DSP_EMU
                   1949:                                ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
                   1950: #else
1.1.1.4   root     1951:                                return Opt_ShowError(OPT_DSP, argv[i], "DSP type 'emu' support not compiled in");
1.1.1.2   root     1952: #endif
                   1953:                        }
                   1954:                        else
                   1955:                        {
1.1.1.4   root     1956:                                return Opt_ShowError(OPT_DSP, argv[i], "Unknown DSP type");
1.1       root     1957:                        }
1.1.1.6   root     1958:                        bLoadAutoSave = false;
1.1       root     1959:                        break;
1.1.1.8   root     1960: 
1.1.1.9   root     1961:                        /* sound options */
1.1.1.8   root     1962:                case OPT_YM_MIXING:
                   1963:                        i += 1;
                   1964:                        if (strcasecmp(argv[i], "linear") == 0)
                   1965:                        {
                   1966:                                ConfigureParams.Sound.YmVolumeMixing = YM_LINEAR_MIXING;
                   1967:                        }
                   1968:                        else if (strcasecmp(argv[i], "table") == 0)
                   1969:                        {
                   1970:                                ConfigureParams.Sound.YmVolumeMixing = YM_TABLE_MIXING;
                   1971:                        }
1.1.1.9   root     1972:                        else if (strcasecmp(argv[i], "model") == 0)
                   1973:                        {
                   1974:                                ConfigureParams.Sound.YmVolumeMixing = YM_MODEL_MIXING;
                   1975:                        }
1.1.1.8   root     1976:                        else
                   1977:                        {
                   1978:                                return Opt_ShowError(OPT_YM_MIXING, argv[i], "Unknown YM mixing method");
                   1979:                        }
                   1980:                        break;
                   1981: 
1.1.1.2   root     1982:                case OPT_SOUND:
1.1       root     1983:                        i += 1;
1.1.1.2   root     1984:                        if (strcasecmp(argv[i], "off") == 0)
                   1985:                        {
1.1.1.6   root     1986:                                ConfigureParams.Sound.bEnableSound = false;
1.1.1.2   root     1987:                        }
                   1988:                        else
                   1989:                        {
1.1.1.6   root     1990:                                freq = atoi(argv[i]);
                   1991:                                if (freq < 6000 || freq > 50066)
                   1992:                                {
                   1993:                                        return Opt_ShowError(OPT_SOUND, argv[i], "Unsupported sound frequency");
                   1994:                                }
                   1995:                                ConfigureParams.Sound.nPlaybackFreq = freq;
                   1996:                                ConfigureParams.Sound.bEnableSound = true;
1.1       root     1997:                        }
1.1.1.16! root     1998:                        Log_Printf(LOG_DEBUG, "Sound %s, frequency = %d.\n",
        !          1999:                                ConfigureParams.Sound.bEnableSound ? "ON" : "OFF",
        !          2000:                                ConfigureParams.Sound.nPlaybackFreq);
1.1       root     2001:                        break;
1.1.1.2   root     2002: 
1.1.1.7   root     2003:                case OPT_SOUNDBUFFERSIZE:
                   2004:                        i += 1;
                   2005:                        temp = atoi(argv[i]);
                   2006:                        if ( temp == 0 )                        /* use default setting for SDL */
                   2007:                                ;
                   2008:                        else if (temp < 10 || temp > 100)
                   2009:                                {
                   2010:                                        return Opt_ShowError(OPT_SOUNDBUFFERSIZE, argv[i], "Unsupported sound buffer size");
                   2011:                                }
1.1.1.16! root     2012:                        Log_Printf(LOG_DEBUG, "SDL sound buffer size = %d ms.\n", temp);
1.1.1.7   root     2013:                        ConfigureParams.Sound.SdlAudioBufferSize = temp;
                   2014:                        break;
1.1.1.10  root     2015: 
                   2016:                case OPT_SOUNDSYNC:
                   2017:                        ok = Opt_Bool(argv[++i], OPT_SOUNDSYNC, &ConfigureParams.Sound.bEnableSoundSync);
                   2018:                        break;
1.1.1.8   root     2019:                        
                   2020:                case OPT_MICROPHONE:
                   2021:                        ok = Opt_Bool(argv[++i], OPT_MICROPHONE, &ConfigureParams.Sound.bEnableMicrophone);
1.1.1.9   root     2022:                        break;
1.1.1.7   root     2023: 
1.1       root     2024:                case OPT_KEYMAPFILE:
                   2025:                        i += 1;
1.1.1.6   root     2026:                        ok = Opt_StrCpy(OPT_KEYMAPFILE, true, ConfigureParams.Keyboard.szMappingFileName,
1.1.1.4   root     2027:                                        argv[i], sizeof(ConfigureParams.Keyboard.szMappingFileName),
                   2028:                                        NULL);
                   2029:                        if (ok)
                   2030:                        {
                   2031:                                ConfigureParams.Keyboard.nKeymapType = KEYMAP_LOADED;
                   2032:                        }
1.1       root     2033:                        break;
                   2034:                        
1.1.1.2   root     2035:                        /* debug options */
1.1.1.11  root     2036: #ifdef WIN32
                   2037:                case OPT_WINCON:
                   2038:                        ConfigureParams.Log.bConsoleWindow = true;
                   2039:                        break;
                   2040: #endif
1.1.1.2   root     2041:                case OPT_DEBUG:
1.1.1.12  root     2042:                        if (ExceptionDebugMask)
1.1.1.4   root     2043:                        {
1.1.1.12  root     2044:                                ExceptionDebugMask = EXCEPT_NONE;
1.1.1.16! root     2045:                                Log_Printf(LOG_INFO, "Exception debugging disabled.\n");
1.1.1.4   root     2046:                        }
                   2047:                        else
                   2048:                        {
1.1.1.15  root     2049:                                ExceptionDebugMask = ConfigureParams.Debugger.nExceptionDebugMask;
1.1.1.16! root     2050:                                Log_Printf(LOG_INFO, "Exception debugging enabled (0x%x).\n", ExceptionDebugMask);
1.1.1.4   root     2051:                        }
1.1.1.2   root     2052:                        break;
1.1.1.4   root     2053: 
1.1.1.12  root     2054:                case OPT_EXCEPTIONS:
                   2055:                        i += 1;
1.1.1.15  root     2056:                        /* sets ConfigureParams.Debugger.nExceptionDebugMask */
1.1.1.12  root     2057:                        errstr = Log_SetExceptionDebugMask(argv[i]);
                   2058:                        if (errstr)
1.1.1.8   root     2059:                        {
1.1.1.16! root     2060:                                if (!errstr[0])
        !          2061:                                {
1.1.1.12  root     2062:                                        /* silent parsing termination */
                   2063:                                        return false;
                   2064:                                }
                   2065:                                return Opt_ShowError(OPT_EXCEPTIONS, argv[i], errstr);
1.1.1.8   root     2066:                        }
1.1.1.12  root     2067:                        if (ExceptionDebugMask)
1.1.1.8   root     2068:                        {
1.1.1.12  root     2069:                                /* already enabled, change run-time config */
                   2070:                                int oldmask = ExceptionDebugMask;
1.1.1.15  root     2071:                                ExceptionDebugMask = ConfigureParams.Debugger.nExceptionDebugMask;
1.1.1.16! root     2072:                                Log_Printf(LOG_INFO, "Exception debugging changed (0x%x -> 0x%x).\n",
        !          2073:                                        oldmask, ExceptionDebugMask);
1.1.1.8   root     2074:                        }
1.1.1.7   root     2075:                        break;
                   2076: 
1.1.1.12  root     2077:                case OPT_BIOSINTERCEPT:
1.1.1.16! root     2078:                        ok = Opt_Bool(argv[++i], OPT_BIOSINTERCEPT, &bBiosIntercept);
        !          2079:                        Log_Printf(LOG_DEBUG, "XBIOS 11/20/255 Hatari versions %sabled: "
        !          2080:                                "Dbmsg(), Scrdmp(), HatariControl().\n",
        !          2081:                                bBiosIntercept ? "en" : "dis");
        !          2082:                        XBios_EnableCommands(bBiosIntercept);
1.1.1.12  root     2083:                        break;
                   2084: 
1.1.1.11  root     2085:                case OPT_CONOUT:
                   2086:                        i += 1;
                   2087:                        ConOutDevice = atoi(argv[i]);
                   2088:                        if (ConOutDevice < 0 || ConOutDevice > 7)
                   2089:                        {
                   2090:                                return Opt_ShowError(OPT_CONOUT, argv[i], "Invalid console device vector number");
                   2091:                        }
1.1.1.16! root     2092:                        Log_Printf(LOG_DEBUG, "Xcounout device %d vector redirection enabled.\n", ConOutDevice);
1.1.1.11  root     2093:                        break;
                   2094: 
                   2095:                case OPT_NATFEATS:
                   2096:                        ok = Opt_Bool(argv[++i], OPT_NATFEATS, &ConfigureParams.Log.bNatFeats);
1.1.1.16! root     2097:                        Log_Printf(LOG_DEBUG, "Native Features %s.\n", ConfigureParams.Log.bNatFeats ? "enabled" : "disabled");
1.1.1.11  root     2098:                        break;
                   2099: 
1.1.1.8   root     2100:                case OPT_PARACHUTE:
                   2101:                        bNoSDLParachute = true;
1.1       root     2102:                        break;
1.1.1.11  root     2103: 
                   2104:                case OPT_DISASM:
                   2105:                        i += 1;
                   2106:                        errstr = Disasm_ParseOption(argv[i]);
                   2107:                        if (errstr)
                   2108:                        {
1.1.1.16! root     2109:                                if (!errstr[0])
        !          2110:                                {
1.1.1.11  root     2111:                                        /* silent parsing termination */
                   2112:                                        return false;
                   2113:                                }
                   2114:                                return Opt_ShowError(OPT_DISASM, argv[i], errstr);
                   2115:                        }
                   2116:                        break;
1.1       root     2117:                        
1.1.1.2   root     2118:                case OPT_TRACE:
                   2119:                        i += 1;
1.1.1.6   root     2120:                        errstr = Log_SetTraceOptions(argv[i]);
                   2121:                        if (errstr)
1.1.1.4   root     2122:                        {
1.1.1.16! root     2123:                                if (!errstr[0])
        !          2124:                                {
1.1.1.7   root     2125:                                        /* silent parsing termination */
                   2126:                                        return false;
                   2127:                                }
1.1.1.6   root     2128:                                return Opt_ShowError(OPT_TRACE, argv[i], errstr);
1.1.1.4   root     2129:                        }
                   2130:                        break;
                   2131: 
                   2132:                case OPT_TRACEFILE:
                   2133:                        i += 1;
1.1.1.6   root     2134:                        ok = Opt_StrCpy(OPT_TRACEFILE, false, ConfigureParams.Log.sTraceFileName,
1.1.1.4   root     2135:                                        argv[i], sizeof(ConfigureParams.Log.sTraceFileName),
                   2136:                                        NULL);
                   2137:                        break;
                   2138: 
                   2139:                case OPT_CONTROLSOCKET:
                   2140:                        i += 1;
                   2141:                        errstr = Control_SetSocket(argv[i]);
                   2142:                        if (errstr)
1.1.1.2   root     2143:                        {
1.1.1.4   root     2144:                                return Opt_ShowError(OPT_CONTROLSOCKET, argv[i], errstr);
1.1.1.2   root     2145:                        }
                   2146:                        break;
                   2147: 
1.1.1.16! root     2148:                case OPT_CMDFIFO:
        !          2149:                        i += 1;
        !          2150:                        errstr = Control_SetFifo(argv[i]);
        !          2151:                        if (errstr)
        !          2152:                        {
        !          2153:                                return Opt_ShowError(OPT_CMDFIFO, argv[i], errstr);
        !          2154:                        }
        !          2155:                        break;
        !          2156: 
1.1.1.4   root     2157:                case OPT_LOGFILE:
                   2158:                        i += 1;
1.1.1.6   root     2159:                        ok = Opt_StrCpy(OPT_LOGFILE, false, ConfigureParams.Log.sLogFileName,
1.1.1.4   root     2160:                                        argv[i], sizeof(ConfigureParams.Log.sLogFileName),
                   2161:                                        NULL);
                   2162:                        break;
                   2163: 
1.1.1.7   root     2164:                case OPT_PARSE:
                   2165:                        i += 1;
                   2166:                        ok = DebugUI_SetParseFile(argv[i]);
                   2167:                        break;
                   2168: 
                   2169:                case OPT_SAVECONFIG:
                   2170:                        /* Hatari-UI needs Hatari config to start */
                   2171:                        Configuration_Save();
                   2172:                        exit(0);
                   2173:                        break;
                   2174: 
1.1.1.4   root     2175:                case OPT_LOGLEVEL:
                   2176:                        i += 1;
                   2177:                        ConfigureParams.Log.nTextLogLevel = Log_ParseOptions(argv[i]);
                   2178:                        if (ConfigureParams.Log.nTextLogLevel == LOG_NONE)
                   2179:                        {
                   2180:                                return Opt_ShowError(OPT_LOGLEVEL, argv[i], "Unknown log level!");
                   2181:                        }
1.1.1.16! root     2182:                        Log_SetLevels();
1.1.1.4   root     2183:                        break;
                   2184: 
                   2185:                case OPT_ALERTLEVEL:
                   2186:                        i += 1;
                   2187:                        ConfigureParams.Log.nAlertDlgLogLevel = Log_ParseOptions(argv[i]);
                   2188:                        if (ConfigureParams.Log.nAlertDlgLogLevel == LOG_NONE)
                   2189:                        {
                   2190:                                return Opt_ShowError(OPT_ALERTLEVEL, argv[i], "Unknown alert level!");
                   2191:                        }
1.1.1.16! root     2192:                        Log_SetLevels();
1.1.1.4   root     2193:                        break;
1.1.1.6   root     2194: 
                   2195:                case OPT_RUNVBLS:
1.1.1.16! root     2196:                        val = atoi(argv[++i]);
        !          2197:                        Log_Printf(LOG_DEBUG, "Exit after %d VBLs.\n", val);
        !          2198:                        Main_SetRunVBLs(val);
1.1.1.6   root     2199:                        break;
1.1.1.4   root     2200:                       
1.1.1.15  root     2201:                case OPT_BENCHMARK:
                   2202:                        BenchmarkMode = true;
                   2203:                        break;
                   2204: 
1.1.1.4   root     2205:                case OPT_ERROR:
                   2206:                        /* unknown option or missing option parameter */
1.1.1.6   root     2207:                        return false;
1.1.1.4   root     2208: 
1.1       root     2209:                default:
1.1.1.4   root     2210:                        return Opt_ShowError(OPT_ERROR, argv[i], "Internal Hatari error, unhandled option");
                   2211:                }
                   2212:                if (!ok)
                   2213:                {
                   2214:                        /* Opt_Bool() or Opt_StrCpy() failed */
1.1.1.6   root     2215:                        return false;
1.1       root     2216:                }
                   2217:        }
1.1.1.4   root     2218: 
1.1.1.15  root     2219:        return Opt_ValidateOptions();
1.1       root     2220: }
1.1.1.7   root     2221: 
                   2222: /**
                   2223:  * Readline match callback for option name completion.
                   2224:  * STATE = 0 -> different text from previous one.
                   2225:  * Return next match or NULL if no matches.
                   2226:  */
                   2227: char *Opt_MatchOption(const char *text, int state)
                   2228: {
                   2229:        static int i, len;
                   2230:        const char *name;
                   2231:        
1.1.1.16! root     2232:        if (!state)
        !          2233:        {
1.1.1.7   root     2234:                /* first match */
                   2235:                len = strlen(text);
                   2236:                i = 0;
                   2237:        }
                   2238:        /* next match */
1.1.1.16! root     2239:        while (i < ARRAY_SIZE(HatariOptions))
        !          2240:        {
1.1.1.7   root     2241:                name = HatariOptions[i++].str;
                   2242:                if (name && strncasecmp(name, text, len) == 0)
                   2243:                        return (strdup(name));
                   2244:        }
                   2245:        return NULL;
                   2246: }

unix.superglobalmegacorp.com

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