]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/cmd_loadihex.c
rewrite of cmd_cpu/do_cpu_freq
[z180-stamp.git] / avr / cmd_loadihex.c
index debccd7253ae5066d7941cfe558093833708a664..a7c9238d675f69913631e1466de7ad24fc79f992 100644 (file)
@@ -1,48 +1,17 @@
 /*
  * (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,
@@ -58,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)) {
@@ -72,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)
@@ -86,18 +53,23 @@ int get_hexbyte(void) {
 }
 
 
-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;
@@ -145,28 +117,38 @@ int ihex_get_record(ihex_t *rec) {
 }
 
 
-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)
@@ -176,16 +158,13 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
 
 //                             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 */
@@ -213,20 +192,19 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
                }
        }
 
-       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);
@@ -235,5 +213,5 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
                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;
 }