X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/70c994914510f9db3ff71373cb96f50ee1669446..refs/heads/fatcommands:/avr/cmd_boot.c?ds=sidebyside diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c index 1213365..b4aa5c0 100644 --- a/avr/cmd_boot.c +++ b/avr/cmd_boot.c @@ -1,68 +1,279 @@ +/* + * (C) Copyright 2014-2016 Leo C. + * + * (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 -#include +#include "cmd_boot.h" #include -#include -#include -#include +#include -#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) +static void z80_load_mem(int_fast8_t verbosity, + const FLASH unsigned char data[], + const FLASH unsigned long *sections, + const FLASH unsigned long address[], + const FLASH unsigned long length_of_sections[]) { - unsigned sec = 0; - uint32_t sec_base = hdrom_start; + uint32_t sec_base = 0; - printf_P(PSTR("Loading Z180 memory... \n")); + if (verbosity > 1) + printf_P(PSTR("Loading Z180 memory... \n")); - 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]); + for (unsigned sec = 0; sec < *sections; sec++) { + if (verbosity > 0) { + printf_P(PSTR(" From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n"), + address[sec], + address[sec]+length_of_sections[sec] - 1, + length_of_sections[sec]); + } - 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_bus_cmd(Release); - sec_base+=hdrom_length_of_sections[sec]; - sec++; + z80_write_block_P((const FLASH unsigned char *) &data[sec_base], /* src */ + address[sec], /* dest */ + length_of_sections[sec]); /* len */ + sec_base += length_of_sections[sec]; } } -command_ret_t do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +command_ret_t do_loadf(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[]) { (void) cmdtp; (void) flag; (void) argc; (void) argv; if (z80_bus_state() & ZST_RUNNING) { - printf_P(PSTR("## Can't load while CPU is running!\n")); + my_puts_P(PSTR("Can't load while CPU is running!\n")); return CMD_RET_FAILURE; } + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return CMD_RET_FAILURE; + } + z80_load_mem(2, hdrom, + &hdrom_sections, + hdrom_address, + hdrom_length_of_sections); - z80_load_mem(); + z80_bus_cmd(Release); return CMD_RET_SUCCESS; } -command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +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_read_block(buf, 9, sizeof buf); + + if((state & ZST_ACQUIRED) == 0) + z80_bus_cmd(Release); + + 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]); +} + + +/* + * 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, uint_fast8_t flag, int argc, char * const 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; + + (void) cmdtp; (void) flag; + + /* get default values */ + memcpy_P(&boot_param, cfboot, sizeof boot_param); + default_stages = boot_param.stages; + + /* 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; + } + + + + if (z80_bus_state() & ZST_RUNNING) { + my_puts_P(PSTR("CPU is allready running!\n")); + return CMD_RET_FAILURE; + } + if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { + my_puts_P(PSTR("Bus timeout\n")); + return CMD_RET_FAILURE; + } + 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, uint_fast8_t flag, int argc, char * const argv[]) { uint16_t count=1; @@ -74,7 +285,7 @@ command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const } 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--) @@ -84,7 +295,7 @@ command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const } -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, uint_fast8_t flag, int argc, char * const argv[]) { uint32_t addr; @@ -92,7 +303,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 2) return CMD_RET_USAGE; - addr = strtoul(argv[1], NULL, 16); + addr = eval_arg(argv[1], NULL); if (addr >= (1UL<<16)) { printf_P(PSTR("## Startaddress 0x%05lx too high.\n" " (Out of logical address space (0x00000-0x0ffff))\n"), @@ -109,11 +320,9 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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)); @@ -121,8 +330,7 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) z80_bus_cmd(Run); z80_bus_cmd(M_Cycle); z80_bus_cmd(M_Cycle); - for (i = 0; i < 3; i++) - z80_write(i, tmp[i]); + z80_write_block(tmp, 0, 3); } else z80_bus_cmd(Run); @@ -131,462 +339,170 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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, uint_fast8_t flag, int argc, char * const argv[]) { - 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()); + (void) cmdtp; (void) flag; (void) argc; (void) argv; + 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, uint_fast8_t flag, int argc, char * const argv[]) { - 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()); + (void) cmdtp; (void) flag; (void) argc; (void) argv; + 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 +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 int xstrlen(char *s) +command_ret_t do_console(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[]) { - if (s == NULL) - return 0; - else - return strlen(s); -} + int ch; + uint8_t pending; +// uint8_t help_prompt = 0; + uint8_t code = 0; + uint8_t state = 0; + char esc_char = (char) getenv_ulong(PSTR(ENV_ESC_CHAR), 16, CONFIG_ESC_CHAR); -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) -{ - 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")); - - 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; + (void) cmdtp; (void) flag; (void) argc; (void) argv; - 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: + printf_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': + printf_P(PSTR("\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; } -