]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/cmd_attach.c
New command(s): attach (and detach) - not fully working.
[z180-stamp.git] / avr / cmd_attach.c
diff --git a/avr/cmd_attach.c b/avr/cmd_attach.c
new file mode 100644 (file)
index 0000000..e1a3b2c
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * (C) Copyright 2016 Leo C. <erbl259-lmu@yahoo.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+/*
+ * attach chanels to devices
+ */
+
+#include "common.h"
+#include <string.h>
+#include <stdbool.h>
+
+#include "command.h"
+#include "z180-serv.h"
+#include "getopt-min.h"
+//#include "print-utils.h"
+//#include "con-utils.h"
+//#include "timer.h"
+//#include "z80-if.h"
+//#include "debug.h"
+
+
+static const FLASH char * const FLASH rc_messages[] = {
+                       FSTR("OK"),
+                       FSTR("Unknown error"),
+                       FSTR("Disk number out of range 0..7"),
+                       FSTR("Disk allready attached"),
+                       FSTR("Disk not attached"),
+                       FSTR("File not found"),
+                       FSTR("Not enough memory"),
+                       FSTR("Error opening file"),
+                       FSTR("File allready attached to other drive"),
+               };
+
+static
+void printerror(int rc, uint8_t unit, char *fn)
+{
+       if (rc < 0 || (unsigned) rc >= ARRAY_SIZE(rc_messages))
+               rc = 1;
+
+#if GCC_BUG_61443 * 0
+               printf_P(PSTR("rc=%u FR_"), rc);
+               my_puts_P(rc_names[rc]);
+               my_puts_P(PSTR("\n"));
+#else
+               printf_P(PSTR("Attachment of '%s' to dsk%d failed: %S!\n"),
+                               fn, unit, rc_messages[rc]);
+#endif
+}
+
+/*
+ * attach [[options] [unit [diskfile]]]
+ *
+ * detach unit
+ * attach -d unit
+ *
+ * attach -o reattach unit
+ * attach -o reattach unit diskfile
+ *
+ * attach unit diskfile
+ *
+ */
+
+command_ret_t do_attach(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       uint8_t unit;
+       char *filename = NULL;
+       bool detach = false;
+       drv_opt_t options = 0;
+       int res;
+
+       (void) cmdtp; (void) flag;
+
+
+       if (argv[0][0] == 'd')
+               /* we are called as 'detach' */
+               detach = true;
+
+       if (argc == 1) {
+               /* no arguments */
+               drv_list();
+               return CMD_RET_SUCCESS;
+       }
+
+       /* reset getopt() */
+       optind = 1;
+
+       int opt;
+       while ((opt = getopt(argc, argv, PSTR("drwo:"))) != -1) {
+               switch (opt) {
+               case 'd':
+                       detach = true;
+                       break;
+               case 'r':
+                       options |= DRV_OPT_RO;
+                       break;
+               case 'w':
+                       options &= ~DRV_OPT_RO;
+                       break;
+               case 'o':
+                       {
+                               static const FLASH char delim[] = {", "};
+                               char *p = strtok_P(optarg, delim);
+                               while (p != NULL) {
+                                       if (!strcmp_P(p, PSTR("ro")))
+                                               options |= DRV_OPT_RO;
+                                       else if (!strcmp_P(p, PSTR("rw")))
+                                               options &= ~DRV_OPT_RO;
+                                       else if (!strcmp_P(p, PSTR("debug")))
+                                               options |= DRV_OPT_DEBUG;
+                                       else if (!strcmp_P(p, PSTR("nodebug")))
+                                               options &= ~DRV_OPT_DEBUG;
+                                       else if (!strcmp_P(p, PSTR("reattach")))
+                                               options |= DRV_OPT_REATTATCH;
+                                       else
+                                               return CMD_RET_USAGE;
+
+                                       p = strtok_P(NULL, delim);
+                               }
+                       }
+                       break;
+               default: /* '?' */
+                       return CMD_RET_USAGE;
+               }
+       }
+
+       /* remaining arguments */
+       argc -= optind;
+       if ( !((detach && argc == 1) ||
+                       ((options & DRV_OPT_REATTATCH) && argc == 1) ||
+                       argc == 2) )
+               return CMD_RET_USAGE;
+
+       if ((strlen(argv[optind]) != 4) ||
+                       strncmp_P(argv[optind], PSTR("dsk"), 3) ||
+                       (unit = argv[optind][3] - '0') >= CONFIG_CPM_MAX_DRIVE) {
+
+               printf_P(PSTR("Unknown device: '%s'\n"), argv[optind]);
+               return CMD_RET_FAILURE;
+       }
+
+       if (detach) {
+               res = drv_detach(unit);
+               return CMD_RET_SUCCESS;
+       }
+
+       if (argc == 2)
+               filename = argv[++optind];
+
+       res = drv_attach(unit, filename, options);
+       if (res)
+               printerror(res, unit, filename);
+
+       return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}