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