/*
- * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
+ * (C) Copyright 2014,2018 Leo C. <erbl259-lmu@yahoo.de>
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0
*/
/*
* Copied from FADS ROM, Dan Malek (dmalek@jlc.net)
*/
-#include "common.h"
-#include <stdlib.h>
-#include <ctype.h>
+#include "cmd_mem.h"
#include <avr/interrupt.h>
-#include "command.h"
#include "cli_readline.h"
#include "print-utils.h"
#include "con-utils.h"
+#include "getopt-min.h"
+#include "eval_arg.h"
#include "timer.h"
#include "z80-if.h"
+#include "disas_z180.h"
#include "debug.h"
/* Display values from last command.
* Memory modify remembered values are different from display memory.
*/
+static uint32_t disas_last_addr;
static uint32_t dp_last_addr;
static uint32_t dp_last_length = 0x100;
static uint32_t mm_last_addr;
/*--------------------------------------------------------------------------*/
-
-void z180_read_buf(uint8_t *buf, uint32_t addr, uint8_t count)
+static ERRNUM z180_read_buf(uint8_t *buf, uint32_t addr, uint8_t count)
{
- if (z80_bus_cmd(Request) & ZST_ACQUIRED) {
- z80_read_block (buf, addr, count);
- z80_bus_cmd(Release);
- }
+ if (!(z80_bus_cmd(Request) & ZST_ACQUIRED))
+ return EBUSTO;
+
+ z80_read_block (buf, addr, count);
+ z80_bus_cmd(Release);
+ return ESUCCESS;
}
/*--------------------------------------------------------------------------*/
+command_ret_t do_mem_size(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
+{
+ int32_t ramsize = z80_memsize_detect();
+
+ if (ramsize < 0)
+ cmd_error(CMD_RET_FAILURE, (ERRNUM) -ramsize, PSTR("Couldn't access RAM"));
+
+ printf_P(PSTR("Detected RAM: Start %.5lx, End: %.5lx, Size: %.5lx (%ld dec)\n"),
+ 0l, ramsize ? ramsize-1 : 0l, ramsize, ramsize);
+
+ return CMD_RET_SUCCESS;
+}
+
+/*
+* Disassemble code from memory
+*
+* Usage:
+* disassemble address [# of lines]
+*
+ */
+command_ret_t do_disas(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
+{
+ (void) cmdtp;
+
+ /* We use the last specified parameters, unless new ones are
+ * entered.
+ */
+ uint32_t addr = disas_last_addr;
+ int length = 16;
+ int ret = CMD_RET_SUCCESS;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ if ((flag & CMD_FLAG_REPEAT) == 0) {
+ /* Address is specified since argc > 1 */
+ addr = eval_arg(argv[1], NULL);
+ addr += base_address;
+
+ /* If another parameter, it is the length (Number of lines) to display. */
+ if (argc > 2)
+ length = (int) eval_arg(argv[2], NULL);
+ }
+
+ z80_bus_request_or_exit();
+ clear_ctrlc(); /* forget any previous Control-C */
+ for (; length > 0; --length) {
+ addr = dis_decode(addr);
+ if (had_ctrlc() || ctrlc()) {
+ ret = CMD_RET_FAILURE;
+ break;
+ }
+ }
+ z80_bus_cmd(Release);
+ disas_last_addr = addr;
+
+ return ret;
+}
+
/* Memory Display
*
* Syntax:
* md {addr} {len}
*/
-command_ret_t do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_md(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
uint32_t addr, length;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/* Address is specified since argc > 1 */
- addr = strtoul(argv[1], NULL, 16);
+ addr = eval_arg(argv[1], NULL);
addr += base_address;
/* If another parameter, it is the length to display. */
if (argc > 2)
- length = strtoul(argv[2], NULL, 16);
+ length = eval_arg(argv[2], NULL);
}
/* Print the lines. */
- dump_mem(addr, addr, length, z180_read_buf, NULL);
+ ERRNUM ret = dump_mem(addr, addr, length, z180_read_buf, NULL);
+ if (ret == EBUSTO)
+ cmd_error(CMD_RET_FAILURE, ret, NULL);
- dp_last_addr = addr + length;
- dp_last_length = length;
+ if (ret == ESUCCESS) {
+ dp_last_addr = addr + length;
+ dp_last_length = length;
+ }
return CMD_RET_SUCCESS;
}
* nm {addr}
*/
static command_ret_t
-mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
+mod_mem(cmd_tbl_t *cmdtp, int incrflag, uint_fast8_t flag, int argc, char * const argv[])
{
uint32_t addr;
uint8_t data;
/* Address is specified since argc > 1
*/
- addr = strtoul(argv[1], NULL, 16);
+ addr = eval_arg(argv[1], NULL);
addr += base_address;
}
* the next value. A non-converted value exits.
*/
do {
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
data = z80_read(addr);
z80_bus_cmd(Release);
printf_P(PSTR("%05lx: %02x"), addr, data);
- nbytes = cli_readline(PSTR(" ? "));
+ nbytes = cli_readline(PSTR(" ? "), 0);
if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
/* <CR> pressed as only input, don't modify current
* location and move to next. "-" pressed will go back.
if (incrflag)
addr += nbytes ? -1 : 1;
nbytes = 1;
- }
- else {
+
+ } else {
char *endp;
- data = strtoul(console_buffer, &endp, 16);
+ data = eval_arg(console_buffer, &endp);
nbytes = endp - console_buffer;
if (nbytes) {
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
z80_write(addr, data);
z80_bus_cmd(Release);
if (incrflag)
addr++;
}
}
- } while (nbytes);
+ } while (nbytes > 0);
mm_last_addr = addr;
return CMD_RET_SUCCESS;
}
-command_ret_t do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_mm(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
return mod_mem (cmdtp, 1, flag, argc, argv);
}
-command_ret_t do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_nm(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
return mod_mem (cmdtp, 0, flag, argc, argv);
}
-command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
- uint8_t writeval;
- uint32_t addr, count;
+ uint32_t writeval;
+ uint32_t addr;
+ uint32_t count = 1;
+ uint_fast8_t width = 1;
- (void) cmdtp;
- (void) flag;
+ (void) cmdtp; (void) flag;
- if ((argc < 3) || (argc > 4))
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("bwl"))) != -1) {
+ switch (opt) {
+ case 'b':
+ width = 1;
+ break;
+ case 'w':
+ width = 2;
+ break;
+ case 'l':
+ width = 4;
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+
+ /* remaining arguments */
+ argc -= optind;
+ if ((argc < 2) || (argc > 3))
return CMD_RET_USAGE;
- /* Address is specified since argc > 1
- */
- addr = strtoul(argv[1], NULL, 16);
+ /* Address and value are specified since (adjusted) argc >= 2 */
+ addr = eval_arg(argv[optind++], NULL);
addr += base_address;
-
- /* Get the value to write.
- */
- writeval = (uint8_t) strtoul(argv[2], NULL, 16);
+ writeval = eval_arg(argv[optind++], NULL);
/* Count ? */
- if (argc == 4) {
- count = strtoul(argv[3], NULL, 16);
- } else {
- count = 1;
- }
-
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
+ if (argc == 3)
+ count = eval_arg(argv[optind], NULL);
+
+ z80_bus_request_or_exit();
+ if (width == 1)
+ z80_memset(addr, writeval, count);
+ else {
+ while (count--) {
+ z80_write_block((const uint8_t *) &writeval, addr, width);
+ addr += width;
+ }
}
- z80_memset(addr, writeval, count);
z80_bus_cmd(Release);
return CMD_RET_SUCCESS;
}
#ifdef CONFIG_MX_CYCLIC
-command_ret_t do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_mdc ( cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
uint32_t count;
uint32_t ts;
(void) cmdtp;
(void) flag;
- if (argc < 4)
+ if (argv[0][1] != 'd') {
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("bwl"))) != -1)
+ if (opt == '?')
+ return CMD_RET_USAGE;
+ --optind;
+ }
+
+ if (argc-optind != 4)
return CMD_RET_USAGE;
- count = strtoul(argv[3], NULL, 10);
+ count = eval_arg(argv[optind + 3], NULL);
clear_ctrlc(); /* forget any previous Control C */
for (;;) {
if (argv[0][1] == 'd')
- do_mem_md (NULL, 0, 3, argv);
+ do_mem_md (NULL, 0, argc-1, argv); /* memory display */
else
- do_mem_mw (NULL, 0, 3, argv);
+ do_mem_mw (NULL, 0, argc-1, argv); /* memory write */
/* delay for <count> ms... */
}
#endif /* CONFIG_MX_CYCLIC */
-command_ret_t do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_cmp(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
uint32_t addr1, addr2, count, ngood;
command_ret_t rcode = CMD_RET_SUCCESS;
return CMD_RET_USAGE;
- addr1 = strtoul(argv[1], NULL, 16);
+ addr1 = eval_arg(argv[1], NULL);
addr1 += base_address;
- addr2 = strtoul(argv[2], NULL, 16);
+ addr2 = eval_arg(argv[2], NULL);
addr2 += base_address;
- count = strtoul(argv[3], NULL, 16);
+ count = eval_arg(argv[3], NULL);
for (ngood = 0; ngood < count; ++ngood) {
if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
return rcode;
}
-command_ret_t do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_cp(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
uint32_t src, dest, count;
int_fast8_t step;
if (argc != 4)
return CMD_RET_USAGE;
- src = strtoul(argv[1], NULL, 16);
+ src = eval_arg(argv[1], NULL);
src += base_address;
- dest = strtoul(argv[2], NULL, 16);
+ dest = eval_arg(argv[2], NULL);
dest += base_address;
- count = strtoul(argv[3], NULL, 16);
+ count = eval_arg(argv[3], NULL);
if (count == 0) {
my_puts_P(PSTR("Zero length?\n"));
while (count-- > 0) {
uint8_t data;
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
data = z80_read(src);
z80_write(dest, data);
z80_bus_cmd(Release);
return CMD_RET_SUCCESS;
}
-command_ret_t do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc,
+command_ret_t do_mem_base(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc,
char * const argv[])
{
(void) cmdtp;
if (argc > 1) {
/* Set new base address. */
- base_address = strtoul(argv[1], NULL, 16);
+ base_address = eval_arg(argv[1], NULL);
}
/* Print the current base address. */
printf_P(PSTR("Base Address: 0x%05lx\n"), base_address);
return CMD_RET_SUCCESS;
}
-command_ret_t do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
+command_ret_t do_mem_loop(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc,
char * const argv[])
{
uint32_t addr, length;
return CMD_RET_USAGE;
/* Address is always specified. */
- addr = strtoul(argv[1], NULL, 16);
+ addr = eval_arg(argv[1], NULL);
/* Length is the number of bytes. */
- length = strtoul(argv[2], NULL, 16);
+ length = eval_arg(argv[2], NULL);
/* We want to optimize the loops to run as fast as possible.
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
cli();
for (;;)
z80_read(addr);
}
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
cli();
for (;;) {
uint32_t i = length;
return CMD_RET_SUCCESS;
}
-command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
{
uint32_t addr, length;
uint8_t data;
return CMD_RET_USAGE;
/* Address is always specified. */
- addr = strtoul(argv[1], NULL, 16);
+ addr = eval_arg(argv[1], NULL);
/* Length is the number of bytes. */
- length = strtoul(argv[2], NULL, 16);
+ length = eval_arg(argv[2], NULL);
- data = strtoul(argv[3], NULL, 16);
+ data = eval_arg(argv[3], NULL);
/*
* We want to optimize the loops to run as fast as possible.
* If we have only one object, just run infinite loops.
*/
if (length == 1) {
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
cli();
for (;;)
z80_write(addr, data);
}
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
cli();
for (;;) {
uint32_t i = length;
* configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until
* interrupted by ctrl-c or by a failure of one of the sub-tests.
*/
-command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
+command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc,
char * const argv[])
{
uint32_t start = 0;
(void) flag;
if (argc > 1)
- start = strtoul(argv[1], NULL, 16);
+ start = eval_arg(argv[1], NULL);
if (argc > 2)
- end = strtoul(argv[2], NULL, 16);
+ end = eval_arg(argv[2], NULL);
else
end = CONFIG_SYS_RAMSIZE_MAX - 1;
if (argc > 3)
- iteration_limit = (unsigned int) strtoul(argv[3], NULL, 16);
+ iteration_limit = (unsigned int) eval_arg(argv[3], NULL);
printf_P(PSTR("Testing %05lx ... %05lx:\n"), start, end);
// debug("## %s:%d: start %#05lx end %#05lx\n", __func__, __LINE__, start, end);
printf_P(PSTR("Iteration: %6d\r"), iteration + 1);
// debug("\n");
- if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
- my_puts_P(PSTR("Bus timeout\n"));
- return CMD_RET_FAILURE;
- }
+ z80_bus_request_or_exit();
errs += mem_test_alt(start, end);
z80_bus_cmd(Release);