/*
* Misc boot support
*/
-#include "common.h"
-#include <stdlib.h>
+#include "cmd_boot.h"
#include <ctype.h>
#include <util/atomic.h>
-#include "command.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"
#undef const
-
-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[])
-{
- uint32_t sec_base = 0;
-
- if (verbosity > 1)
- printf_P(PSTR("Loading Z180 memory... \n"));
-
- 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_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 UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
- (void) cmdtp; (void) flag; (void) argc; (void) argv;
-
- if (z80_bus_state() & ZST_RUNNING) {
- 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;
- }
+ 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,
* -v verbose
*/
-command_ret_t do_bootcf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_bootcf(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
{
struct {
uint8_t jr[2];
uint8_t sec_cnt;
uint8_t part_id;
uint16_t timeout;
- uint8_t stop_stage;
+ uint8_t stages;
} boot_param;
struct {
- uint8_t stop_stage;
+ uint8_t stages;
uint8_t done;
uint8_t result;
uint8_t ide_stat;
} boot_res;
int_fast8_t verbosity = 0;
- uint8_t stages;
+ uint8_t default_stages;
uint32_t val;
- (void) cmdtp; (void) flag;
-
/* get default values */
memcpy_P(&boot_param, cfboot, sizeof boot_param);
- stages = boot_param.stop_stage;
-
- /* reset getopt() */
- optind = 0;
+ default_stages = boot_param.stages;
int opt;
while ((opt = getopt(argc, argv, PSTR("vna:s:c:t:i:"))) != -1) {
verbosity++;
break;
case 'n':
- if (boot_param.stop_stage > 0)
- boot_param.stop_stage--;
+ if (boot_param.stages > 0)
+ boot_param.stages--;
break;
case 'a':
- val = strtoul(optarg, NULL, 16);
+ 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 = strtoul(optarg, NULL, 16);
+ 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 = strtoul(optarg, NULL, 16);
+ 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 = strtoul(optarg, NULL, 10);
+ 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.loadaddr = val;
+ boot_param.timeout = val;
break;
case 'i':
- val = strtoul(optarg, NULL, 16);
+ 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;
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;
- }
+ 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_address[0], sizeof boot_param);
z80_bus_cmd(Release);
- if (boot_param.stop_stage == 0) {
+ 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.stop_stage, stages);
+ boot_param.stages, default_stages);
z80_bus_cmd(Run);
z80_bus_cmd(Release);
z80_bus_cmd(Reset);
my_puts_P(PSTR("Abort\n"));
} else {
- if (boot_param.stop_stage == stages) {
+ 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.stop_stage - boot_res.stop_stage,
+ 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[1], 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;
- (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];
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);
+ _delay_us(10);
z80_write_block(tmp, 0, 3);
- } else
+ } 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[])
+command_ret_t do_reset(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
- (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_restart(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)
{
- (void) cmdtp; (void) flag; (void) argc; (void) argv;
-
reset_cpu(Restart);
return CMD_RET_SUCCESS;
), esc + 0x40);
}
-command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_console(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
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);
- (void) cmdtp; (void) flag; (void) argc; (void) argv;
-
printf_P(PSTR("Connecting to CPU. Escape character is '^%c'.\n"),
esc_char + 0x40);
}
break;
case 2:
- printf_P(PSTR("\n"
+ my_puts_P(PSTR("\n"
"------------------------------------------------\n"));
case 1:
state = 0;
case 'X':
case 'Q':
- printf_P(PSTR("\n"));
+ putchar('\n');
goto quit;
break;