mii_emu/src/mii_argv.c

204 lines
5.8 KiB
C

/*
* mii_argv.c
*
* Copyright (C) 2023 Michel Pollet <buserror@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "mii.h"
extern mii_slot_drv_t * mii_slot_drv_list;
static void
_mii_usage(
const char *progname)
{
printf("Usage: %s [options]\n", progname);
printf("Options:\n");
printf(" -h, --help\tThis help\n");
printf(" -v, --verbose\tVerbose output\n");
printf(" -m, --mute\tMute the speaker\n");
printf(" -vol, --volume <volume>\tSet speaker volume (0.0 to 10.0)\n");
printf(" --audio-off, --no-audio, --silent\tDisable audio output\n");
printf(" -speed, --speed <speed>\tSet the CPU speed in MHz\n");
printf(" -s, --slot <slot>:<driver>\tSpecify a slot and driver\n");
printf("\t\tSlot id is 1..7\n");
printf(" -d, --drive <slot>:<drive>:<filename>\tLoad a drive\n");
printf("\t\tSlot id is 1..7, drive is 1..2\n");
printf("\t\tAlternate syntax: <slot>:<drive> <filename>\n");
printf(" -L, --list-drivers\tList available drivers, exit\n");
printf(" -def, --default\tUse a set of default cards:\n");
printf("\t\tSlot 4: mouse\n");
printf("\t\tSlot 6: disk2\n");
printf("\t\tSlot 7: smartport\n");
printf(" -nsc[=0|1]\tEnable/Disable No Slot Clock:\n");
printf("\t\t0: disable\n");
printf("\t\t1: enable [Enabled by default]\n");
printf(" -titan[=0|1]\tEnable/Disable Titan Accelerator IIe:\n");
printf("\t\t0: disable [default]\n");
printf("\t\t1: enable [Start at 3.58MHz]\n");
}
int
mii_argv_parse(
mii_t *mii,
int argc,
const char *argv[],
int *index,
uint32_t *ioFlags)
{
if (*index == 0)
*index += 1;
for (int i = *index; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) {
_mii_usage(argv[0]);
exit(0);
} else if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
// mii->verbose++;
// continue;
} else if ((!strcmp(arg, "-s") || !strcmp(arg, "--slot")) && i < argc-1) {
// for mat for slot is 1..8:<name> where name is the driver name
const char *p = argv[++i];
int slot = 0;
char *drv = NULL;
if (sscanf(p, "%d:%ms", &slot, &drv) != 2) {
printf("mii: invalid slot specification %s\n", p);
return 1;
}
if (slot < 1 || slot > 8) {
printf("mii: invalid slot number %d\n", slot);
return 1;
}
if (drv == NULL) {
printf("mii: missing driver name for slot %d\n", slot);
return 1;
}
if (mii_slot_drv_register(mii, slot, drv) < 0) {
printf("mii: failed to register driver %s for slot %d\n", drv, slot);
return 1;
}
} else if ((!strcmp(arg, "-d") || !strcmp(arg, "--drive")) && i < argc-1) {
// drive takes 2 following arguments, the <slot>:<drive> and a filename
const char *p = argv[++i];
int slot = 0;
int drive = 0;
const char *filename = NULL;
int got = sscanf(p, "%d:%d:%ms", &slot, &drive, &filename);
if (got == 2) {
if (i < argc-1) {
filename = argv[++i];
got = 3;
} else {
printf("mii: missing filename for drive %d:%d\n", slot, drive);
return 1;
}
} else if (got != 3) {
printf("mii: invalid drive specification %s\n", p);
return 1;
}
if (slot < 1 || slot > 8) {
printf("mii: invalid slot number %d\n", slot);
return 1;
}
if (drive < 1 || drive > 2) {
printf("mii: invalid drive number %d\n", drive);
return 1;
}
if (filename == NULL) {
printf("mii: missing filename for drive %d:%d\n", slot, drive);
return 1;
}
mii_slot_command(mii, slot,
MII_SLOT_DRIVE_LOAD + drive - 1,
(void*)filename);
} else if (!strcmp(arg, "-def") || !strcmp(arg, "--default")) {
mii_slot_drv_register(mii, 4, "mouse");
mii_slot_drv_register(mii, 6, "disk2");
mii_slot_drv_register(mii, 7, "smartport");
} else if (!strcmp(arg, "-L") || !strcmp(arg, "--list-drivers")) {
mii_slot_drv_t * drv = mii_slot_drv_list;
printf("mii: available drivers:\n");
while (drv) {
printf("%10.10s - %s\n", drv->name, drv->desc);
drv = drv->next;
}
exit(0);
} else if (!strcmp(arg, "-m") || !strcmp(arg, "--mute")) {
mii->speaker.muted = true;
} else if (!strcmp(arg, "--audio-off") ||
!strcmp(arg, "--no-audio") ||
!strcmp(arg, "--silent")) {
mii->speaker.off = true;
} else if (!strcmp(arg, "-vol") || !strcmp(arg, "--volume")) {
if (i < argc-1) {
float vol = atof(argv[++i]);
if (vol < 0) vol = 0;
else if (vol > 10) vol = 10;
mii_speaker_volume(&mii->speaker, vol);
} else {
printf("mii: missing volume value\n");
return 1;
}
} else if (!strcmp(arg, "-speed") || !strcmp(arg, "--speed")) {
if (i < argc-1) {
mii->speed = atof(argv[++i]);
if (mii->speed <= 0.0)
mii->speed = 1.0;
} else {
printf("mii: missing speed value\n");
return 1;
}
} else {
if (argv[i][0] == '-') {
char dup[128];
snprintf(dup, sizeof(dup), "%s", argv[i] + 1);
char *equal = dup;
char *name = strsep(&equal, "=");
int enable = 1;
if (equal && *equal) {
if (!strcmp(equal, "0"))
enable = 0;
else if (!strcmp(equal, "1"))
enable = 1;
else {
printf("mii: invalid flag %s\n", argv[i]);
return 1;
}
}
// printf("%s lookup driver %s to %s\n", __func__,
// name, enable ? "enable" : "disable");
mii_slot_drv_t * drv = mii_slot_drv_list;
int done = 0;
while (drv) {
printf("%10.10s - %s\n", drv->name, drv->desc);
if (drv->enable_flag) {
if (!strcmp(name, drv->name)) {
*ioFlags = (*ioFlags & ~drv->enable_flag) |
(enable ? drv->enable_flag : 0);
printf("mii: %s %s\n", name, enable ? "enabled" : "disabled");
break;
}
}
drv = drv->next;
}
if (!done && equal) {
printf("mii: no driver found %s\n", argv[i]);
return 1;
}
continue;
}
printf("mii: unknown argument %s\n", argv[i]);
return 1;
}
}
*index = argc;
return 1;
}