X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/41d36f28612cb6c49cf0260236f3b834549883be..fecee2418b6aea15008ed6d3a856d202d59a5cdb:/avr/cmd_boot.c diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c index 285dd65..301f4f5 100644 --- a/avr/cmd_boot.c +++ b/avr/cmd_boot.c @@ -1,18 +1,24 @@ +/* + * (C) Copyright 2014 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 -#include -#include +#include #include "command.h" -#include "getopt-min.h" +#include "con-utils.h" #include "z80-if.h" -#include "pin.h" +#include "z180-serv.h" #include "debug.h" /* ugly hack to get Z180 loadfile into flash memory */ @@ -36,7 +42,7 @@ static void z80_load_mem(void) hdrom_length_of_sections[sec]); z80_bus_cmd(Request); - z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */ + z80_write_block_P((const FLASH unsigned char *) &hdrom[sec_base], /* src */ hdrom_address[sec], /* dest */ hdrom_length_of_sections[sec]); /* len */ z80_bus_cmd(Release); @@ -129,13 +135,21 @@ command_ret_t do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_SUCCESS; } +static +void reset_cpu(bus_cmd_t mode) +{ + restart_z180_serv(); + z80_bus_cmd(mode); +} + + command_ret_t do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { (void) cmdtp; (void) flag; (void) argc; (void) argv; printf_P(PSTR("## CPU now in reset state.\n")); - z80_bus_cmd(Reset); + reset_cpu(Reset); return CMD_RET_SUCCESS; } @@ -143,305 +157,126 @@ 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); + reset_cpu(Restart); return CMD_RET_SUCCESS; } -#if 0 -command_ret_t do_clock(cmd_tbl_t *cmdtp, int 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()); - - - return CMD_RET_SUCCESS; +static +void print_con_usage(char esc) +{ printf_P(PSTR("\n" + "------------------------------------------------\n" + " ?,H - This Help\n" + " R - Reset (Restart) CPU\n" + " Q,X - Return to command line\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); } -command_ret_t do_clock2(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +command_ret_t do_console(cmd_tbl_t *cmdtp, int 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()); - - - return CMD_RET_SUCCESS; -} -#endif - -// {INPUT, INPUT_PULLUP, OUTPUT, OUTPUT_TIMER} pinmode_t; - + int ch; + uint8_t pending; +// uint8_t help_prompt = 0; + uint8_t code = 0; + uint8_t state = 0; -static void print_blanks(uint_fast8_t count) -{ - while(count--) - putchar(' '); -} - -static const FLASH char * const FLASH pinconf_str[] = { - 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); - my_puts_P(pinconf_str[pinconf]); - print_blanks(8 - strlen_P(pinconf_str[pinconf])); - my_puts_P(levelp); - print_blanks(6 - strlen_P(levelp)); - if (pinconf == OUTPUT_TIMER) - printf_P(PSTR("%7ld %8ld"), - div, F_CPU/div); - } else { - printf_P(PSTR("Pin %d: "), pin); - 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; -} - - -/* - * TODO: - pin groups - * - error if pin "config clock" on pins without clock - * - stat for single pin (group) - */ - -command_ret_t do_pin(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) -{ - int opt, pin; - unsigned long value; - char *endp; - char printheader = 1; + (void) cmdtp; (void) flag; (void) argc; (void) argv; - (void) cmdtp; (void) flag; - /* reset getopt() */ - optind = 1; + while (1) { - 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; } - } - -// if ((argc - optind) % 2 != 0) -// return CMD_RET_USAGE; - - debug("argc: %d, optind: %d\n", argc, optind); - - switch (argc - optind) { - case 0: - if (printheader) - printf_P(PSTR("Pin Config Level Divider Frequency/Hz\n" - "-----------------------------------------\n")); - for (pin = 0; pin < PIN_MAX; pin++) - print_pin(pin, 1); - - return CMD_RET_SUCCESS; - break; - case 1: - pin = strtol(argv[optind], &endp, 10); - print_pin(pin, 0); - return CMD_RET_SUCCESS; - break; - } + if (pending) + while ((ch = z80_memfifo_getc(fifo_conout)) >= 0) + putchar(ch); + + if ((ch = my_getchar(0)) >= 0) { + switch (state) { + case 0: + if (ch == CONFIG_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(CONFIG_ESC_CHAR); + state = 2; + break; - while (optind < argc ) { - uint8_t hz_flag = 0; - - pin = strtol(argv[optind++], &endp, 10); - - switch (toupper(argv[optind][0])) { - case 'L': - case 'H': - pin_write(pin, toupper(argv[optind][0]) == 'H'); - pin_config(pin, OUTPUT); - break; - case 'P': - pin_config(pin, INPUT_PULLUP); - break; - case 'I': - case 'T': - pin_config(pin, INPUT); - break; - - default: - value = strtoul(argv[optind], &endp, 10); - switch (*endp) { - case 'M': - value *= 1000; - case 'K': - value *= 1000; - endp++; - } + case 'R': + reset_cpu(Restart); + break; - if (*endp && strcmp_P(endp, PSTR("Hz")) == 0) { - hz_flag = 1; - endp += 2; - } + case 'X': + case 'Q': + printf_P(PSTR("\n")); + goto quit; + 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; + case CONFIG_ESC_CHAR: + z80_memfifo_putc(fifo_conin, ch); + break; + default: + break; } - value = F_CPU/value; - } - - - debug("** setting pin '%d' to '%lu'\n", pin, value); - if (pin_clockdiv_set(pin, value) < 0) { - printf_P(PSTR("Setting pin %d to %lu failed.\n"), - pin, value); + break; + case 3: + if (toupper(ch) == 'X') { + state = 6; + break; + } + /* fall thru */ + case 4: + case 5: + if (isdigit(ch)) { + code = code * 10 + ch - '0'; + state++; + } + if (state > 5) { + z80_memfifo_putc(fifo_conin, code); + state = 0; + } + break; + case 6: + case 7: + if (isxdigit(ch)) { + ch = toupper(ch); + if (ch >= 'A') + ch -= 'A' - 10; + code = code * 16 + ch - '0'; + state++; + } + if (state > 7) { + z80_memfifo_putc(fifo_conin, code); + state = 0; + } + break; } } - - optind++; } - - +quit: return CMD_RET_SUCCESS; } -