+/*
+ * (C) Copyright 2014-2016 Leo C. <erbl259-lmu@yahoo.de>
+ *
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
/*
* Misc boot support
*/
-#include "common.h"
-#include <stdlib.h>
-#include <limits.h>
+#include "cmd_boot.h"
#include <ctype.h>
-#include <string.h>
-#include <util/delay.h>
-#include <avr/pgmspace.h>
+#include <util/atomic.h>
-#include "command.h"
-#include "getopt-min.h"
+#include "cli_readline.h" /* console_buffer[] */
+#include "cli.h" /* run_command() */
#include "env.h"
+#include "eval_arg.h"
+#include "con-utils.h"
+#include "getopt-min.h"
#include "z80-if.h"
-#include "pin.h"
+#include "z180-serv.h" /* restart_z180_serv() */
#include "debug.h"
/* ugly hack to get Z180 loadfile into flash memory */
#define const const FLASH
#include "../z180/hdrom.h"
+#include "../z180/cfboot.h"
#undef const
-
-static void z80_load_mem(void)
+command_ret_t do_loadf(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
- unsigned sec = 0;
- uint32_t sec_base = hdrom_start;
+ if (z80_bus_state() & ZST_RUNNING)
+ cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
+ z80_bus_request_or_exit();
+ z80_load_mem(2, hdrom,
+ &hdrom_sections,
+ hdrom_address,
+ hdrom_length_of_sections);
- printf_P(PSTR("Loading Z180 memory... \n"));
+ z80_bus_cmd(Release);
- while (sec < hdrom_sections) {
- printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"),
- hdrom_address[sec],
- hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
- hdrom_length_of_sections[sec]);
+ return CMD_RET_SUCCESS;
+}
+
+
+void print_vars(char *title)
+{
+ uint8_t buf[5];
+ zstate_t state = z80_bus_state();
+ if((state & ZST_ACQUIRED) == 0)
z80_bus_cmd(Request);
- z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */
- hdrom_address[sec], /* dest */
- hdrom_length_of_sections[sec]); /* len */
+
+ z80_read_block(buf, 9, sizeof buf);
+
+ if((state & ZST_ACQUIRED) == 0)
z80_bus_cmd(Release);
- sec_base+=hdrom_length_of_sections[sec];
- sec++;
- }
+
+ printf_P(PSTR("%s: stage: %d, flag: 0x%.02x, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
+ title, buf[0], buf[1], buf[2], buf[3], buf[4]);
}
-command_ret_t do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+
+/*
+ * bootcf [options]
+ *
+ * -a address (100h)
+ * -s start sector (0)
+ * -c sector count (7)
+ * -i Partition id (52)
+ * -n load only
+ * -t timeout (10000)
+ * -v verbose
+ */
+
+command_ret_t do_bootcf(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
{
- (void) cmdtp; (void) flag; (void) argc; (void) argv;
+ struct {
+ uint8_t jr[2];
+ uint16_t loadaddr;
+ uint8_t sec_start;
+ uint8_t sec_cnt;
+ uint8_t part_id;
+ uint16_t timeout;
+ uint8_t stages;
+ } boot_param;
+
+ struct {
+ uint8_t stages;
+ uint8_t done;
+ uint8_t result;
+ uint8_t ide_stat;
+ uint8_t ide_error;
+ } boot_res;
+
+ int_fast8_t verbosity = 0;
+ uint8_t default_stages;
+ uint32_t val;
+ ERRNUM res = ESUCCESS;
+
+ /* get default values */
+ memcpy_P(&boot_param, cfboot, sizeof boot_param);
+ default_stages = boot_param.stages;
- if (z80_bus_state() & ZST_RUNNING) {
- printf_P(PSTR("## Can't load while CPU is running!\n"));
+ /* reset getopt() */
+ optind = 0;
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("vna:s:c:t:i:"))) != -1) {
+ switch (opt) {
+ case 'v':
+ verbosity++;
+ break;
+ case 'n':
+ if (boot_param.stages > 0)
+ boot_param.stages--;
+ break;
+ case 'a':
+ val = eval_arg(optarg, NULL);
+ if (val < 0x100 || val > 0xFE00) {
+ printf_P(PSTR("Address out of range: 0x%.4lX\n"), val);
+ return CMD_RET_FAILURE;
+ }
+ boot_param.loadaddr = val;
+ break;
+ case 's':
+ val = eval_arg(optarg, NULL);
+ if (val > 255) {
+ printf_P(PSTR("Start sector out of range: 0x%lX\n"), val);
+ return CMD_RET_FAILURE;
+ }
+ boot_param.sec_start = val;
+ break;
+ case 'c':
+ val = eval_arg(optarg, NULL);
+ if (val > 127) {
+ printf_P(PSTR("Sector count out of range: 0x%lX\n"), val);
+ return CMD_RET_FAILURE;
+ }
+ boot_param.sec_cnt = val;
+ break;
+ case 't':
+ val = eval_arg(optarg, NULL);
+ if (val < 0x1 || val > 0xFFFF) {
+ printf_P(PSTR("Timeout value out of range: 0x%lX\n"), val);
+ return CMD_RET_FAILURE;
+ }
+ boot_param.timeout = val;
+ break;
+ case 'i':
+ val = eval_arg(optarg, NULL);
+ if (val < 0x01 || val > 0xFF) {
+ printf_P(PSTR("Partition id out of range: 0x%lX\n"), val);
+ return CMD_RET_FAILURE;
+ }
+ boot_param.part_id = val;
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+
+ /* remaining arguments */
+ argc -= optind;
+ if (argc) {
+ my_puts_P(PSTR("Argument error!\n"));
+ return CMD_RET_USAGE;
+ }
+
+ if ((val = (uint32_t) boot_param.loadaddr + boot_param.sec_cnt * 512) >= 0xFF00) {
+ printf_P(PSTR("Top address out of range: 0x%.4lX\n"), val);
return CMD_RET_FAILURE;
}
- z80_load_mem();
+ if (z80_bus_state() & ZST_RUNNING)
+ cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
+ z80_bus_request_or_exit();
+ z80_load_mem(verbosity, cfboot,
+ &cfboot_sections,
+ cfboot_address,
+ cfboot_length_of_sections);
+
+ z80_write_block((const uint8_t *) &boot_param,
+ cfboot_address[0], sizeof boot_param);
+ z80_bus_cmd(Release);
+
+ if (boot_param.stages == 0) {
+ printf_P(PSTR("Bootloader loaded at: 0x%.4X\n"), (uint16_t) cfboot_address[0]);
+ } else {
+ printf_P(PSTR("Executing %d of %d Bootloader stages...\n"),
+ boot_param.stages, default_stages);
+
+ z80_bus_cmd(Run);
+ z80_bus_cmd(Release);
+
+ clear_ctrlc(); /* forget any previous Control C */
+ for (boot_res.done = 0; boot_res.done != 0xFF;) {
+ _delay_ms(8);
+ /* check for ctrl-c to abort... */
+ if (had_ctrlc() || ctrlc()) {
+ break;
+ }
+ z80_bus_cmd(Request);
+ z80_read_block((uint8_t *) &boot_res,
+ cfboot_address[0]+sizeof boot_param - 1, sizeof boot_res);
+ z80_bus_cmd(Release);
+ }
+
+ if (boot_res.done != 0xFF) {
+ z80_bus_cmd(Reset);
+ my_puts_P(PSTR("Abort\n"));
+ } else {
+ if (boot_param.stages == default_stages &&
+ boot_res.stages == 0 &&
+ boot_res.result == 0) {
+ my_puts_P(PSTR("Booting...\n"));
+ } else {
+ z80_bus_cmd(Reset);
+ boot_res.stages++;
+ printf_P(PSTR("Bootloader stopped at stage %d, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
+ boot_param.stages - boot_res.stages,
+ boot_res.result, boot_res.ide_stat, boot_res.ide_error);
+ }
+ }
+ }
return CMD_RET_SUCCESS;
}
-
-command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
{
uint16_t count=1;
- (void) cmdtp; (void) flag;
-
if (!(z80_bus_state() & ZST_RUNNING)) {
printf_P(PSTR("## CPU is not running!\n"));
return CMD_RET_FAILURE;
}
if (argc > 1)
- count = (uint16_t) strtoul(argv[2], NULL, 16);
+ count = (uint16_t) eval_arg(argv[1], NULL);
z80_bus_cmd(Request);
while (count--)
}
-command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_go(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
{
uint32_t addr;
+ bool hold = 0;
+
+ /* reset getopt() */
+ optind = 0;
- (void) cmdtp; (void) flag;
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("h"))) != -1) {
+ switch (opt) {
+ case 'h':
+ hold = 1;
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+ argc -= optind; /* remaining arguments */
- if (argc < 2)
+ if (argc != 1)
return CMD_RET_USAGE;
- addr = strtoul(argv[1], NULL, 16);
+ addr = eval_arg(argv[optind], NULL);
if (addr >= (1UL<<16)) {
- printf_P(PSTR("## Startaddress 0x%05lx too high.\n"
+ printf_P(PSTR("Invalid startaddress: 0x%05lx\n"
" (Out of logical address space (0x00000-0x0ffff))\n"),
addr);
return CMD_RET_FAILURE;
}
if (z80_bus_state() & ZST_RUNNING) {
- printf_P(PSTR("## CPU allready running!\n"));
+ printf_P(PSTR("CPU already running!\n"));
return CMD_RET_FAILURE;
}
- printf_P(PSTR("## Starting application at 0x%04lx ...\n"), addr);
+ printf_P(PSTR("Starting application at 0x%04lx ...\n"), addr);
if (addr != 0) {
uint8_t tmp[3];
- uint_fast8_t i;
z80_bus_cmd(Request);
- for (i = 0; i < 3; i++)
- tmp[i] = z80_read(i);
+ z80_read_block (tmp, 0, 3);
z80_write(0, 0xc3);
z80_write(1, addr);
z80_write(2, (addr >> 8));
z80_bus_cmd(Run);
+ _delay_us(10);
z80_bus_cmd(M_Cycle);
+ _delay_us(10);
z80_bus_cmd(M_Cycle);
- for (i = 0; i < 3; i++)
- z80_write(i, tmp[i]);
- } else
+ _delay_us(10);
+ z80_write_block(tmp, 0, 3);
+ } else {
+ if (!hold)
+ z80_bus_cmd(Request);
z80_bus_cmd(Run);
-
- z80_bus_cmd(Release);
+ }
+ if (!hold)
+ z80_bus_cmd(Release);
return CMD_RET_SUCCESS;
}
-command_ret_t do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static
+void reset_cpu(bus_cmd_t mode)
{
- (void) cmdtp; (void) flag; (void) argc; (void) argv;
-
- printf_P(PSTR("## CPU now in reset state.\n"));
-
- z80_bus_cmd(Reset);
- return CMD_RET_SUCCESS;
+ restart_z180_serv();
+ z80_bus_cmd(mode);
}
-command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- (void) cmdtp; (void) flag; (void) argc; (void) argv;
-
- z80_bus_cmd(Restart);
-
- return CMD_RET_SUCCESS;
-}
-#if 0
-command_ret_t do_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+command_ret_t do_reset(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
- long freq;
- char *endp;
-
- (void) cmdtp; (void) flag;
-
- if (argc == 2) {
- if (toupper(argv[1][0]) == 'L')
- freq = 0;
- else if (toupper(argv[1][0]) == 'H')
- freq = LONG_MAX;
- else {
- freq = strtol(argv[1], &endp, 10);
- switch (*endp) {
- case 'M':
- freq *= 1000;
- case 'K':
- freq *= 1000;
- endp++;
- case '\0':
- if (*endp == '\0')
- break;
- default:
- printf_P(PSTR("invalid value\n"));
- return CMD_RET_USAGE;
- }
-
- if (freq == 0) {
- printf_P(PSTR("CPU clock cannot be 0\n"));
- return CMD_RET_USAGE;
- }
-
-
-/* if (freq > (long) F_CPU / 2) {
- printf_P(PSTR("Max CPU clock freq. is: %luHz\n"), F_CPU/2);
- return CMD_RET_USAGE;
- }
-*/
- }
- if (z80_clock_set(freq) < 0) {
- printf_P(PSTR("Setting CPU clock freq. to %luHz failed.\n"),
- freq);
- }
- }
-
- printf_P(PSTR("CPU clock: %luHz\n"), z80_clock_get());
-
+ printf_P(PSTR("CPU now in reset state.\n"));
+ reset_cpu(Reset);
return CMD_RET_SUCCESS;
}
-command_ret_t do_clock2(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+command_ret_t do_restart(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
- long value;
- char *endp;
- uint8_t div_flag = 0;
-
- (void) cmdtp; (void) flag;
-
- if (argc >= 2) {
- if (argv[1][0] == '-' && argv[1][1] == 'd') {
- div_flag = 1;
- argc--;
- argv++;
- }
- }
-
- if (argc == 2) {
- if (toupper(argv[1][0]) == 'L')
- value = 0;
- else if (toupper(argv[1][0]) == 'H')
- value = LONG_MAX;
- else {
- value = strtol(argv[1], &endp, 10);
- switch (*endp) {
- case 'M':
- value *= 1000;
- case 'K':
- value *= 1000;
- endp++;
- case '\0':
- if (*endp == '\0')
- break;
- default:
- printf_P(PSTR("invalid value\n"));
- return CMD_RET_USAGE;
- }
-
- if (value == 0) {
- printf_P(PSTR("clk2 cannot be 0\n"));
- return CMD_RET_USAGE;
- }
-
- if (div_flag) {
- if (value > 256*1024L) {
- printf_P(PSTR("Max clk2 divider is: %lu\n"), 256*1024L);
- return CMD_RET_USAGE;
- }
- } else {
- if (value > (long) F_CPU / 2) {
- printf_P(PSTR("Max clk2 freq. is: %luHz\n"), F_CPU/2);
- return CMD_RET_USAGE;
- }
- }
- }
- if (div_flag ? z80_clock2_divset(value) : z80_clock2_set(value) < 0) {
- printf_P(PSTR("Setting clk2 freq. to %luHz failed.\n"),
- value);
- }
- }
-
- printf_P(PSTR("clk2: %luHz\n"), z80_clock2_get());
-
+ reset_cpu(Restart);
return CMD_RET_SUCCESS;
}
-#endif
-
-
-static const int namestr = PIN_MAX;
-static char *pin_names[PIN_MAX+1];
-static uint_least8_t pin_names_width;
-
-void pinnames_get(void)
-{
- static const FLASH char delim1[] = {":= "};
- static const FLASH char delim2[] = {", "};
- char *lp;
- char *ptr;
- uint_fast8_t i;
-
- if (pin_names[namestr] != NULL)
- free(pin_names[namestr]);
- memset(pin_names, 0, sizeof(pin_names));
- pin_names_width = 0;
-
- if ((lp = getenv(PSTR(ENV_PINALIAS))) != NULL) {
- pin_names[namestr] = strdup(lp);
- ptr = strtok_P(pin_names[namestr], delim1);
- while (ptr != NULL) {
- if (((i = strtoul(ptr, &lp, 10)) < PIN_MAX) &&
- lp != ptr &&
- (ptr = strtok_P(NULL, delim2)) != NULL ) {
- pin_names[i] = ptr;
- ptr = strtok_P(NULL, delim1);
- }
- }
-
- for (i = 0; i < PIN_MAX; i++)
- if (strlen(pin_names[i]) > pin_names_width)
- pin_names_width = strlen(pin_names[i]);
- }
-}
-
-
-static void print_blanks(uint_fast8_t count)
-{
- while(count--)
- putchar(' ');
-}
-static int xstrlen(char *s)
-{
- if (s == NULL)
- return 0;
- else
- return strlen(s);
+static
+void print_con_usage(char esc)
+{ printf_P(PSTR("\n"
+ "------------------------------------------------\n"
+ " ?,H - This Help\n"
+ " Q,X - Return to command line\n"
+ " R - Reset (Restart) CPU\n"
+ " : - Execute monitor command\n"
+ " \\ - code input:\n"
+ " \\nnn 3 decimal digits character code\n"
+ " \\Xhh 2 hexadecimal digits character code\n"
+ " ^%c - (Escape char) Type again to send itself\n"
+ "key>"
+ ), esc + 0x40);
}
-static const FLASH char * const FLASH pinconf_str[] = {
- FSTR("?"),
- FSTR("Input"),
- FSTR("Pullup"),
- FSTR("Output"),
- FSTR("Clock"),
- };
-
-static const FLASH char * const FLASH pinlevel_str[] = {
- FSTR("Low"),
- FSTR("High"),
- FSTR(""),
- };
-
-int print_pin(int pin, int multi)
+command_ret_t do_console(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
- int pinconf;
- const FLASH char *levelp;
- long div;
-
- pinconf = pin_config_get(pin);
- if (pinconf == OUTPUT_TIMER) {
- div = pin_clockdiv_get(pin);
- levelp = pinlevel_str[2];
- } else
- levelp = pinlevel_str[pin_read(pin)];
-
- if (multi) {
- printf_P(PSTR("%3d "), pin);
- if (pin_names_width) {
- printf_P(PSTR("%s "), pin_names[pin]);
- print_blanks(pin_names_width - xstrlen(pin_names[pin]));
- }
- my_puts_P(pinconf_str[pinconf]);
- print_blanks(7 - strlen_P(pinconf_str[pinconf]));
- my_puts_P(levelp);
- print_blanks(5 - strlen_P(levelp));
- if (pinconf == OUTPUT_TIMER)
- printf_P(PSTR("%8ld %8ld"),
- div, F_CPU/div);
- } else {
- printf_P(PSTR("%d: \"%s\", "), pin, pin_names[pin] ? pin_names[pin] : 0);
- my_puts_P(pinconf_str[pinconf]);
- printf_P(PSTR(", "));
- my_puts_P(levelp);
-
- if (pinconf == OUTPUT_TIMER)
- printf_P(PSTR("divide by %ld (%ldHz)"),
- div, F_CPU/div);
- }
- printf_P(PSTR("\n"));
+ int ch;
+ uint8_t pending;
+ uint8_t code = 0;
+ uint8_t state = 0;
+ char esc_char = (char) getenv_ulong(PSTR(ENV_ESC_CHAR), 16, CONFIG_ESC_CHAR);
- return 0;
-}
-
-int pinarg_insert(int pin, int count, int pinarg[])
-{
- int pos;
-
- if (pin < 0 || pin >= PIN_MAX)
- return -1;
-
- for (pos = 0; pos < count; pos++) {
- if (pin == pinarg[pos])
- return 0;
- if (pin < pinarg[pos])
- break;
- }
- for (int i = count-1; i == pos ; i--)
- pinarg[i+1] = pinarg[i];
- pinarg[pos] = pin;
-
- return 1;
-}
-
-int pinarg_get(char * arg, int pinarg[])
-{
- int count = 0;
- char *endp;
- int pin1, pin2, rc;
+ printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
+ esc_char + 0x40);
while (1) {
- pin1 = (int) strtoul(arg, &endp, 10);
- if (endp != arg && *endp == '-') {
- arg = endp+1;
- pin2 = (int) strtoul(arg, &endp, 10);
- if (pin1 < pin2)
- for (; pin1 < pin2; pin1++)
- if ((rc = pinarg_insert(pin1, count, pinarg)) >= 0)
- count += rc;
- else
- return 0;
- else
- return 0;
- }
- if (endp != arg && pin1 >= 0) {
- if ((*endp == ',' || *endp == '\0') &&
- (rc = pinarg_insert(pin1, count, pinarg)) >= 0) {
- count += rc;
- if (*endp == '\0')
- return count;
- } else
- return 0;
- } else
- return 0;
-
- arg = endp+1;
- }
-}
-
-command_ret_t do_pin(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
-{
- char printheader = 1;
- int pinarg[PIN_MAX];
- int pinargc;
-
- (void) cmdtp; (void) flag;
-
- /* reset getopt() */
- optind = 1;
-
- int opt;
- while ((opt = getopt(argc, argv, PSTR("s"))) != -1) {
- switch (opt) {
- case 's':
- printheader = 0;
- break;
- default: /* '?' */
- return CMD_RET_USAGE;
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ pending = (Stat & S_CON_PENDING) != 0;
+ Stat &= ~S_CON_PENDING;
}
- }
-
- /* remaining arguments */
- argc -= optind;
-
- pinnames_get();
-
- if (argc == 0) {
- /* print cofig of all pins */
- for (pinargc = 0; pinargc < PIN_MAX; pinargc++)
- pinarg[pinargc] = pinargc;
- } else {
- /* get first arg */
- pinargc = pinarg_get(argv[optind++], pinarg);
- if (pinargc == 0)
- return CMD_RET_USAGE;
- else
- argc--;
- }
-
- if (argc == 0) {
- /* no more args, print config */
- if (pinargc == 1)
- print_pin(pinarg[0], 0);
- else {
- if (printheader) {
- if (pin_names_width > 0) {
- if ( strlen("Name") > pin_names_width)
- pin_names_width = strlen("Name");
- char s[pin_names_width+1];
- memset(s, ' ', pin_names_width);
- s[pin_names_width] = '\0';
- strncpy_P(s, PSTR("Name"), 4);
- printf_P(PSTR("Pin %s Config Level Divider Frequency/Hz\n"),s);
- memset(s, '-', pin_names_width);
- printf_P(PSTR("----%s-----------------------------------\n"), s);
- } else
- printf_P(PSTR("Pin Config Level Divider Frequency/Hz\n"
- "--------------------------------------\n"));
- }
- for (int i = 0; i < pinargc; i++)
- print_pin(pinarg[i], 1);
+ if (pending) {
+ uint8_t count = 100;
+ while ((ch = z80_memfifo_getc(fifo_conout)) >= 0 && --count)
+ putchar(ch);
}
- return CMD_RET_SUCCESS;
- }
- /* arguments must be in pairs: pins conf */
- if (argc % 2 != 1)
- return CMD_RET_USAGE;
+ if ((ch = my_getchar(0)) >= 0) {
+ switch (state) {
+ case 0:
+ if (ch == esc_char) {
+ state = 1;
+ /* TODO: Timer starten */
+ } else {
+ z80_memfifo_putc(fifo_conin, ch);
+ }
+ break;
+ case 2:
+ my_puts_P(PSTR("\n"
+ "------------------------------------------------\n"));
+ case 1:
+ state = 0;
+ switch (toupper(ch)) {
+
+ case '?':
+ case 'H':
+ print_con_usage(esc_char);
+ state = 2;
+ break;
- while (argc > 0) {
- char *endp;
- pinmode_t mode = NONE;
- int level = 0;
- unsigned long value = 0;
- uint8_t hz_flag = 0;
-
- switch (toupper(argv[optind][0])) {
- case 'H':
- level = 1;
- case 'L':
- mode = OUTPUT;
- break;
- case 'P':
- mode = INPUT_PULLUP;
- break;
- case 'I':
- case 'T':
- mode = INPUT;
- break;
+ case 'R':
+ reset_cpu(Restart);
+ break;
- default:
- value = strtoul(argv[optind], &endp, 10);
- switch (*endp) {
- case 'M':
- value *= 1000;
- case 'K':
- value *= 1000;
- endp++;
- }
+ case 'X':
+ case 'Q':
+ putchar('\n');
+ goto quit;
+ break;
- if (*endp && strcmp_P(endp, PSTR("Hz")) == 0) {
- hz_flag = 1;
- endp += 2;
- }
+ case ':':
+ putchar('\n');
+ int cmdlen = cli_readline(PSTR(": "), 1);
+ if (cmdlen > 0)
+ run_command(console_buffer, 0);
+ break;
- if (*endp != '\0') {
- printf_P(PSTR("invalid parameter: '%s'\n"), argv[optind]);
- return CMD_RET_USAGE;
- }
-
- if (value == 0) {
- printf_P(PSTR("invalid value: %lu \n"));
- return CMD_RET_USAGE;
- }
+ case '\\':
+ code = 0;
+ state = 3;
+ break;
- if (hz_flag) {
- if (value > F_CPU / 2) {
- printf_P(PSTR("Max frequency is: %luHz\n"), F_CPU/2);
- return CMD_RET_USAGE;
+ default:
+ if (ch == esc_char)
+ z80_memfifo_putc(fifo_conin, ch);
+ break;
}
- value = F_CPU/value;
- }
- mode = OUTPUT_TIMER;
-
- }
-
- if (mode == NONE)
- return CMD_RET_USAGE;
-
- for (int i = 0; i < pinargc; i++) {
- switch (mode) {
- case OUTPUT:
- pin_write(pinarg[i], level);
- /* fall thru */
- case INPUT:
- case INPUT_PULLUP:
- pin_config(pinarg[i], mode);
break;
- case OUTPUT_TIMER:
- if (pin_clockdiv_set(pinarg[i], value) < 0) {
- printf_P(PSTR("Setting pin %d to %lu failed.\n"),
- pinarg[i], value);
+ case 3:
+ if (toupper(ch) == 'X') {
+ state = 6;
+ break;
+ }
+ /* fall thru */
+ case 4:
+ case 5:
+ if (isdigit(ch)) {
+ code = code * 10 + ch - '0';
+ state++;
+ } else {
+ if (state > 3)
+ z80_memfifo_putc(fifo_conin, code);
+ z80_memfifo_putc(fifo_conin, ch);
+ state = 0;
+ }
+ if (state > 5) {
+ z80_memfifo_putc(fifo_conin, code);
+ state = 0;
}
break;
- default:
+ case 6:
+ case 7:
+ if (isxdigit(ch)) {
+ ch = toupper(ch);
+ if (ch >= 'A')
+ ch -= 'A' - 10;
+ code = code * 16 + ch - '0';
+ state++;
+ }else {
+ if (state > 6)
+ z80_memfifo_putc(fifo_conin, code);
+ z80_memfifo_putc(fifo_conin, ch);
+ state = 0;
+ }
+ if (state > 7) {
+ z80_memfifo_putc(fifo_conin, code);
+ state = 0;
+ }
break;
}
}
-
- optind++;
- pinargc = pinarg_get(argv[optind++], pinarg);
- argc -= 2;
}
-
+quit:
return CMD_RET_SUCCESS;
}
-