/*
* (C) Copyright 2015 Leo C. <erbl259-lmu@yahoo.de>
*
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0
*/
-#include "common.h"
-#include <stdlib.h>
+#include "cmd_loadihex.h"
#include <ctype.h>
-#include <stdbool.h>
-#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;
-}
-
typedef enum {
IHX_OK,
IHX_BROKEN,
} ihex_t;
-static
-int get_hexdigit(void) {
-
+static int get_hexdigit(void)
+{
int c;
c = toupper(my_getchar(1));
if (isxdigit(c)) {
return -1;
}
-static
-int get_hexbyte(void) {
-
+static int get_hexbyte(void)
+{
uint8_t i,j;
if ((i = (uint8_t) get_hexdigit()) < 0x10)
}
-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;
}
-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);
+ int32_t ram = z80_memsize_detect();
+ if (ram < 0)
+ cmd_error(CMD_RET_FAILURE, (ERRNUM) -ram, NULL);
+
+ address_max = ram;
+ address_low = address_max;
+
+ my_puts_P(PSTR("Waiting for Intel Hex Records...\n"));
+
while (ihex_get_record(&rec) > 0 &&
rec.status == IHX_OK &&
rec.type != 1 ) {
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)
// 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 */
}
}
- 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: "));
+ my_puts_P(PSTR("\nData loaded: "));
if (address_low >= MIN(address_high, address_max))
- printf_P(PSTR("None.\n"));
+ 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);
printf_P(PSTR("Data above highest RAM address "
"(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;
}