X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/31033ab3f82c4d00e12fb72a65c2ba614da8ad2f..aea51b6c4c93c56715f50e64d424e1181c6d0242:/avr/cmd_loadihex.c diff --git a/avr/cmd_loadihex.c b/avr/cmd_loadihex.c index 01fb6b0..a7c9238 100644 --- a/avr/cmd_loadihex.c +++ b/avr/cmd_loadihex.c @@ -1,54 +1,15 @@ /* * (C) Copyright 2015 Leo C. * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0 */ -#include "common.h" -#include +#include "cmd_loadihex.h" #include -#include -#include "command.h" #include "con-utils.h" #include "z80-if.h" -//#include "debug.h" - - -uint32_t detect_ramsize(void) -{ - uint32_t addr; - uint8_t save_addr, save_0; - const uint8_t PATTERN_1 = 0x55; - const uint8_t PATTERN_2 = ~PATTERN_1; - - if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) { - my_puts_P(PSTR("Bus timeout\n")); - return 0; - } - - save_0 = z80_read(0); - z80_write(0, PATTERN_1); - - for (addr=1; addr < CONFIG_SYS_RAMSIZE_MAX; addr <<= 1) { - save_addr = z80_read(addr); - z80_write(addr, PATTERN_2); - if (z80_read(0) != PATTERN_1 || z80_read(addr) != PATTERN_2) - break; - z80_write(addr, save_addr); - } - z80_write(0, save_0); - z80_bus_cmd(Release); - - return addr; -} - -static uint32_t min(uint32_t a, uint32_t b) -{ - if (a < b) - return a; - return b; -} +#include "debug.h" typedef enum { @@ -66,9 +27,8 @@ typedef struct { } ihex_t; -static -int get_hexdigit(void) { - +static int get_hexdigit(void) +{ int c; c = toupper(my_getchar(1)); if (isxdigit(c)) { @@ -80,9 +40,8 @@ int get_hexdigit(void) { return -1; } -static -int get_hexbyte(void) { - +static int get_hexbyte(void) +{ uint8_t i,j; if ((i = (uint8_t) get_hexdigit()) < 0x10) @@ -93,87 +52,24 @@ int get_hexbyte(void) { return -1; } -#if 0 - -static -ihex_t ihex_get_record() { - - int i; - uint8_t sum, c; - ihex_t rec = { IHX_BROKEN, 0, 0, 0, 0 }; - - - while ((c = my_getchar(0)) != ':') - if (c == 0x03) - return rec; - - if ((i = get_hexbyte()) < 0) /* Start code */ - return rec; - sum = i; - rec.len = i; - if ((i = get_hexbyte()) < 0) /* Byte Count */ - return rec; - sum += i; - rec.address = i * 256; - if ((i = get_hexbyte()) < 0) /* Address */ - return rec; - sum += i; - rec.address += i; - if ((i = get_hexbyte()) < 0) /* Record type */ - return rec; - sum += i; - rec.type = i; - - if (rec.len) { /* Record Data */ - uint8_t *p; int k; - if ((rec.data = malloc(rec.len)) == 0) - return rec; - - for (p=rec.data, k=rec.len; k; k--) { - if ((i = get_hexbyte()) < 0) - break; - sum += i; - *p++ = i; - } - - if (k) { - free(rec.data); rec.data = 0; - return rec; - } - } - - i = get_hexbyte(); /* Check sum */ - - if (i >= 0) { - sum += i; - if (sum == 0) - rec.status = IHX_OK; - else - rec.status = IHX_CHKSUMERR; - } - - if (rec.status != IHX_OK) { - free(rec.data); - rec.data = 0; - } - - return rec; -} - -#else - -static -int ihex_get_record(ihex_t *rec) { +static int ihex_get_record(ihex_t *rec) +{ int c; uint8_t sum; rec->status = IHX_BROKEN; + rec->len = 0; + rec->type = 0xff; - - while ((c = my_getchar(0)) != ':') + while ((c = my_getchar(0)) != ':') { if (c == 0x03) - return -1; + return -1; /* Control-C */ + if (c == 0x04) { + rec->status = IHX_OK; + return 0; /*Control-D, EOF */ + } + } if ((c = get_hexbyte()) < 0) /* Start code */ return -1; @@ -220,26 +116,28 @@ int ihex_get_record(ihex_t *rec) { return rec->len; } -#endif -command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +command_ret_t do_loadihex(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) { long offset = 0; uint32_t base_address = 0; - uint32_t address_max = detect_ramsize(); uint32_t address_high = 0; - uint32_t address_low = address_max; - command_ret_t rcode = CMD_RET_FAILURE; + uint32_t address_max; + uint32_t address_low; + bool firstrec = true; ihex_t rec; - (void) cmdtp; (void) flag; - + if (argc > 1) + offset = strtol(argv[1], NULL, 16); - printf_P(PSTR("RAM Size: 0x%.5lX\n"), address_max); + int32_t ram = z80_memsize_detect(); + if (ram < 0) + cmd_error(CMD_RET_FAILURE, (ERRNUM) -ram, NULL); + address_max = ram; + address_low = address_max; - if (argc > 1) - offset = strtol(argv[1], NULL, 16); + my_puts_P(PSTR("Waiting for Intel Hex Records...\n")); while (ihex_get_record(&rec) > 0 && rec.status == IHX_OK && @@ -247,6 +145,10 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg switch (rec.type) { case 0: /* Data record */ + if (firstrec) { + my_puts_P(PSTR("Loading: 0x.....")); + firstrec = false; + } if (rec.len) { uint32_t addr = base_address + rec.address + offset; if (addr < address_low) @@ -254,19 +156,15 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg if (addr+rec.len > address_high) address_high = addr + rec.len; - -printf_P(PSTR("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d\n"), - address_low, address_high, address_max, addr, rec.len); - +// debug("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d\n", +// address_low, address_high, address_max, addr, rec.len); + printf_P(PSTR("\b\b\b\b\b%.5lX"), addr); if (addr < address_max) { uint32_t tmplen = address_max - addr; if (rec.len > tmplen) rec.len = tmplen; - 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_block(rec.data, /* src */ addr, /* dest */ rec.len); /* len */ @@ -280,7 +178,7 @@ printf_P(PSTR("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d break; #endif case 2: /* Extended Segment Address Record */ - base_address = ((rec.data[0] << 8) + rec.data[1]) << 4; + base_address = (uint32_t)((rec.data[0] << 8) + rec.data[1]) << 4; break; case 4: /* Extended Linear Address Record */ @@ -294,27 +192,26 @@ printf_P(PSTR("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d } } - switch (rec.status) { - case IHX_OK: - rcode = CMD_RET_SUCCESS; - break; + if (rec.status != IHX_OK) + my_puts_P(PSTR("Broken Hex Record or loading interrupted!\n")); - case IHX_BROKEN: - case IHX_CHKSUMERR: - printf_P(PSTR("Broken Hex Record or loading interrupted!\n")); - break; + for (uint_fast8_t i=0; i<100; ++i) { + /* flush input buffer */ + while (my_getchar(0) > 0) + ; + udelay(1000); } - printf_P(PSTR("Data loaded: ")); - if (address_low >= min(address_high, address_max)) - printf_P(PSTR("None.\n")); + my_puts_P(PSTR("\nData loaded: ")); + if (address_low >= MIN(address_high, address_max)) + my_puts_P(PSTR("None.\n")); else printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low, - min(address_high, address_max) - 1); + MIN(address_high, address_max) - 1); if (address_high > address_max) printf_P(PSTR("Data above highest RAM address " - "(Range 0x%.5lX...0x%.5lX) ignored!\n"), address_max, address_high - 1); + "(in range 0x%.5lX - 0x%.5lX) ignored!\n"), address_max, address_high - 1); - return rcode; + return rec.status == IHX_OK ? CMD_RET_SUCCESS : CMD_RET_FAILURE; }