]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
New memory test commands, loadi updates. Needs testing
authorLeo C <erbl259-lmu@yahoo.de>
Wed, 22 Apr 2015 19:59:58 +0000 (21:59 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Wed, 22 Apr 2015 19:59:58 +0000 (21:59 +0200)
- rename loop to mloop
- + mloopw
- + mtest
- + mdc
- + mwc

avr/cmd_mem.c
avr/command.c
avr/command_tbl.c
avr/ihex.c
include/cmd_mem.h
include/config.h

index 20a4412a0b2e770e8b8cc232c628057771b73bff..53b18426fbcc1400718ab88f1b2581ab43cf3ed0 100644 (file)
 #include "common.h"
 #include <stdlib.h>
 #include <ctype.h>
+#include <avr/interrupt.h>
 
 #include "command.h"
 #include "cli_readline.h"
 #include "print-utils.h"
 #include "con-utils.h"
+#include "timer.h"
 #include "z80-if.h"
-//#include "debug.h"
+#include "debug.h"
 
 
 #ifndef CONFIG_SYS_MEMTEST_SCRATCH
@@ -222,55 +224,35 @@ command_ret_t do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
 #ifdef CONFIG_MX_CYCLIC
 command_ret_t do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       int i;
        uint32_t count;
+       uint32_t ts;
+
+       (void) cmdtp;
+       (void) flag;
 
        if (argc < 4)
                return CMD_RET_USAGE;
 
        count = strtoul(argv[3], NULL, 10);
 
+       clear_ctrlc();          /* forget any previous Control C */
        for (;;) {
-               do_mem_md (NULL, 0, 3, argv);
-
-               /* delay for <count> ms... */
-/* TODO: use timer */
-               for (i=0; i<count; i++)
-                       udelay (1000);
-
-               /* check for ctrl-c to abort... */
-               if (ctrlc()) {
-                       my_puts_P(PSTR("Abort\n"));
-                       return CMD_RET_SUCCESS;
-               }
-       }
-
-       return CMD_RET_SUCCESS;
-}
-
-command_ret_t do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       int i;
-       uint32_t count;
-
-       if (argc < 4)
-               return CMD_RET_USAGE;
 
-       count = strtoul(argv[3], NULL, 10);
+               if (argv[0][1] == 'd')
+                       do_mem_md (NULL, 0, 3, argv);
+               else
+                       do_mem_mw (NULL, 0, 3, argv);
 
-       for (;;) {
-               do_mem_mw (NULL, 0, 3, argv);
 
                /* delay for <count> ms... */
-/* TODO: use timer */
-               for (i=0; i<count; i++)
-                       udelay (1000);
-
-               /* check for ctrl-c to abort... */
-               if (ctrlc()) {
-                       my_puts_P(PSTR("Abort\n"));
-                       return CMD_RET_SUCCESS;
-               }
+               ts = get_timer(0);
+               do {
+                       /* check for ctrl-c to abort... */
+                       if (had_ctrlc() || ctrlc()) {
+                               my_puts_P(PSTR("Abort\n"));
+                               return CMD_RET_SUCCESS;
+                       }
+               } while (get_timer(ts) < count);
        }
 
        return CMD_RET_SUCCESS;
@@ -417,27 +399,26 @@ command_ret_t do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc,
                        my_puts_P(PSTR("Bus timeout\n"));
                        return  CMD_RET_FAILURE;
                }
+               cli();
                for (;;)
                        z80_read(addr);
-               z80_bus_cmd(Release);
        }
 
        if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
                my_puts_P(PSTR("Bus timeout\n"));
                return  CMD_RET_FAILURE;
        }
+       cli();
        for (;;) {
                uint32_t i = length;
                uint32_t p = addr;
                while (i-- > 0)
                        z80_read(p++);
        }
-       z80_bus_cmd(Release);
 
        return CMD_RET_SUCCESS;
 }
 
-#ifdef CONFIG_LOOPW
 command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        uint32_t addr, length;
@@ -457,7 +438,8 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
 
        data = strtoul(argv[3], NULL, 16);
 
-       /* We want to optimize the loops to run as fast as possible.
+       /*
+        * 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) {
@@ -465,6 +447,7 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
                        my_puts_P(PSTR("Bus timeout\n"));
                        return  CMD_RET_FAILURE;
                }
+               cli();
                for (;;)
                        z80_write(addr, data);
        }
@@ -473,6 +456,7 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
                my_puts_P(PSTR("Bus timeout\n"));
                return  CMD_RET_FAILURE;
        }
+       cli();
        for (;;) {
                uint32_t i = length;
                uint32_t p = addr;
@@ -480,35 +464,33 @@ command_ret_t do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char * const a
                        z80_write(p++, data);
        }
 }
-#endif /* CONFIG_LOOPW */
+
+//#define CONFIG_SYS_ALT_MEMTEST
 
 #ifdef CONFIG_CMD_MEMTEST
-static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_addr,
-                         vu_long *dummy)
+static uint32_t mem_test_alt(uint32_t start_addr, uint32_t end_addr)
 {
-       vu_long *addr;
+       uint32_t addr;
+       uint32_t dummy;
        uint32_t errs = 0;
-       uint32_t val, readback;
-       int j;
-       vu_long offset;
-       vu_long test_offset;
-       vu_long pattern;
-       vu_long temp;
-       vu_long anti_pattern;
-       vu_long num_words;
-       static const FLASH uint32_t bitpattern[] = {
-               0x00000001,     /* single bit */
-               0x00000003,     /* two adjacent bits */
-               0x00000007,     /* three adjacent bits */
-               0x0000000F,     /* four adjacent bits */
-               0x00000005,     /* two non-adjacent bits */
-               0x00000015,     /* three non-adjacent bits */
-               0x00000055,     /* four non-adjacent bits */
-               0xaaaaaaaa,     /* alternating 1/0 */
+       uint32_t offset;
+       uint32_t test_offset;
+       uint8_t pattern;
+       uint8_t anti_pattern;
+       uint8_t temp;
+       uint32_t num_bytes;
+
+       static const FLASH uint8_t bitpattern[] = {
+               0x01,   /* single bit */
+               0x03,   /* two adjacent bits */
+               0x07,   /* three adjacent bits */
+               0x0F,   /* four adjacent bits */
+               0x05,   /* two non-adjacent bits */
+               0x15,   /* three non-adjacent bits */
+               0x55,   /* four non-adjacent bits */
+               0xaa,   /* alternating 1/0 */
        };
 
-       num_words = (end_addr - start_addr) / sizeof(vu_long);
-
        /*
         * Data line test: write a pattern to the first
         * location, write the 1's complement to a 'parking'
@@ -526,35 +508,39 @@ static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_add
         * '0's and '0' bits through a field of '1's (i.e.
         * pattern and ~pattern).
         */
-       addr = buf;
-       for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) {
-               val = bitpattern[j];
-               for (; val != 0; val <<= 1) {
-                       *addr = val;
-                       *dummy  = ~val; /* clear the test data off the bus */
-                       readback = *addr;
-                       if (readback != val) {
+       addr = start_addr;
+       dummy = start_addr+1;
+       for (unsigned int j = 0; j < ARRAY_SIZE(bitpattern); j++) {
+               pattern = bitpattern[j];
+               for (; pattern != 0; pattern <<= 1) {
+                       anti_pattern = ~pattern;
+                       z80_write(addr, pattern);
+                       z80_write(dummy, anti_pattern); /* clear the test data off the bus */
+                       temp = z80_read(addr);
+                       if (temp != pattern) {
                                printf_P(PSTR("FAILURE (data line): "
-                                       "expected %05lx, actual %05lx\n"),
-                                               val, readback);
+                                       "expected %02x, actual %02x\n"),
+                                               pattern, temp);
                                errs++;
-                               if (ctrlc())
-                                       return -1;
                        }
-                       *addr  = ~val;
-                       *dummy  = val;
-                       readback = *addr;
-                       if (readback != ~val) {
+                       z80_write(addr, anti_pattern);
+                       z80_write(dummy, pattern); /* clear the test data off the bus */
+                       temp = z80_read(addr);
+                       if (temp != anti_pattern) {
                                printf_P(PSTR("FAILURE (data line): "
-                                       "Is %05lx, should be %05lx\n"),
-                                               readback, ~val);
+                                       "Is %02x, should be %02x\n"),
+                                               temp, anti_pattern);
                                errs++;
-                               if (ctrlc())
-                                       return -1;
                        }
                }
+
+               if (ctrlc())
+                       return -1;
        }
 
+       if (errs)
+               return errs;
+
        /*
         * Based on code whose Original Author and Copyright
         * information follows: Copyright (c) 1998 by Michael
@@ -589,59 +575,61 @@ static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_add
         *
         * Returns:     0 if the test succeeds, 1 if the test fails.
         */
-       pattern = (vu_long) 0xaaaaaaaa;
-       anti_pattern = (vu_long) 0x55555555;
 
-       debug("%s:%d: length = 0x%.5lx\n", __func__, __LINE__, num_words);
+       num_bytes = (end_addr - start_addr) / sizeof(uint8_t);
+
+       pattern = 0xaa;
+       anti_pattern = 0x55;
+
+//     debug("## %s:%d: length = 0x%.5lx\n", __func__, __LINE__, num_bytes);
        /*
         * Write the default pattern at each of the
         * power-of-two offsets.
         */
-       for (offset = 1; offset < num_words; offset <<= 1)
-               addr[offset] = pattern;
+       for (offset = 1; offset < num_bytes; offset <<= 1)
+               z80_write(addr+offset, pattern);
 
        /*
         * Check for address bits stuck high.
         */
-       test_offset = 0;
-       addr[test_offset] = anti_pattern;
+       z80_write(start_addr, anti_pattern);
 
-       for (offset = 1; offset < num_words; offset <<= 1) {
-               temp = addr[offset];
+       for (offset = 1; offset < num_bytes; offset <<= 1) {
+               temp = z80_read(start_addr + offset);
                if (temp != pattern) {
-                       printf_P(PSTR("\nFAILURE: Address bit stuck high @ 0x%.5lx:"
-                               " expected 0x%.5lx, actual 0x%.5lx\n"),
-                               start_addr + offset*sizeof(vu_long),
-                               pattern, temp);
+                       printf_P(PSTR("FAILURE: Address bit stuck high @ 0x%.5lx:"
+                               " expected 0x%.2x, actual 0x%.2x\n"),
+                               start_addr + offset, pattern, temp);
                        errs++;
                        if (ctrlc())
                                return -1;
                }
        }
-       addr[test_offset] = pattern;
+       z80_write(start_addr, pattern);
 
        /*
         * Check for addr bits stuck low or shorted.
         */
-       for (test_offset = 1; test_offset < num_words; test_offset <<= 1) {
-               addr[test_offset] = anti_pattern;
+       for (test_offset = 1; test_offset < num_bytes; test_offset <<= 1) {
+               z80_write(start_addr + test_offset, anti_pattern);
 
-               for (offset = 1; offset < num_words; offset <<= 1) {
-                       temp = addr[offset];
+               for (offset = 1; offset < num_bytes; offset <<= 1) {
+                       temp = z80_read(start_addr + offset);
                        if ((temp != pattern) && (offset != test_offset)) {
-                               printf_P(PSTR("\nFAILURE: Address bit stuck low or"
-                                       " shorted @ 0x%.5lx: expected 0x%.5lx,"
-                                       " actual 0x%.5lx\n"),
-                                       start_addr + offset*sizeof(vu_long),
-                                       pattern, temp);
+                               printf_P(PSTR("FAILURE: Address bit stuck low or shorted"
+                                       " @ 0x%.5lx: expected 0x%.2x, actual 0x%.2x\n"),
+                                       start_addr + offset, pattern, temp);
                                errs++;
                                if (ctrlc())
                                        return -1;
                        }
                }
-               addr[test_offset] = pattern;
+               z80_write(start_addr + test_offset, pattern);
        }
 
+       if (errs)
+               return errs;
+
        /*
         * Description: Test the integrity of a physical
         *              memory device by performing an
@@ -654,111 +642,50 @@ static uint32_t mem_test_alt(vu_long *buf, uint32_t start_addr, uint32_t end_add
         *
         * Returns:     0 if the test succeeds, 1 if the test fails.
         */
-       num_words++;
+       num_bytes++;
 
        /*
         * Fill memory with a known pattern.
         */
-       for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
-               addr[offset] = pattern;
-       }
+       for (pattern = 1, addr = start_addr; addr <= end_addr; pattern++, addr++)
+               z80_write(addr, pattern);
 
        /*
         * Check each location and invert it for the second pass.
         */
-       for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
-               temp = addr[offset];
+       for (pattern = 1, addr = start_addr; addr <= end_addr; pattern++, addr++) {
+               temp = z80_read(addr);
                if (temp != pattern) {
-                       printf_P(PSTR("\nFAILURE (read/write) @ 0x%.5lx:"
-                               " expected 0x%.5lx, actual 0x%.5lx)\n"),
-                               start_addr + offset*sizeof(vu_long),
-                               pattern, temp);
+                       printf_P(PSTR("FAILURE (read/write) @ 0x%.5lx:"
+                               " expected 0x%.2x, actual 0x%.2x)\n"),
+                               addr, pattern, temp);
                        errs++;
                        if (ctrlc())
                                return -1;
                }
 
                anti_pattern = ~pattern;
-               addr[offset] = anti_pattern;
+               z80_write(addr, anti_pattern);
        }
 
        /*
         * Check each location for the inverted pattern and zero it.
         */
-       for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
-               WATCHDOG_RESET();
+       for (pattern = 1, addr = start_addr; addr <= end_addr; pattern++, addr++) {
                anti_pattern = ~pattern;
-               temp = addr[offset];
+               temp = z80_read(addr);
                if (temp != anti_pattern) {
-                       printf_P(PSTR("\nFAILURE (read/write): @ 0x%.5lx:"
-                               " expected 0x%.5lx, actual 0x%.5lx)\n"),
-                               start_addr + offset*sizeof(vu_long),
-                               anti_pattern, temp);
+                       printf_P(PSTR("FAILURE (read/write) @ 0x%.5lx:"
+                               " expected 0x%.2x, actual 0x%.2x)\n"),
+                               start_addr,     anti_pattern, temp);
                        errs++;
                        if (ctrlc())
                                return -1;
                }
-               addr[offset] = 0;
+               z80_write(addr, 0);
        }
 
-       return 0;
-}
-
-static uint32_t mem_test_quick(vu_long *buf, uint32_t start_addr, uint32_t end_addr,
-                           vu_long pattern, int iteration)
-{
-       vu_long *end;
-       vu_long *addr;
-       uint32_t errs = 0;
-       uint32_t incr, length;
-       uint32_t val, readback;
-
-       /* Alternate the pattern */
-       incr = 1;
-       if (iteration & 1) {
-               incr = -incr;
-               /*
-                * Flip the pattern each time to make lots of zeros and
-                * then, the next time, lots of ones.  We decrement
-                * the "negative" patterns and increment the "positive"
-                * patterns to preserve this feature.
-                */
-               if (pattern & 0x80000000)
-                       pattern = -pattern;     /* complement & increment */
-               else
-                       pattern = ~pattern;
-       }
-       length = (end_addr - start_addr) / sizeof(uint32_t);
-       end = buf + length;
-       printf_P(PSTR("\rPattern %08lX  Writing..."
-               "%12s"
-               "\b\b\b\b\b\b\b\b\b\b"),
-               pattern, "");
-
-       for (addr = buf, val = pattern; addr < end; addr++) {
-               *addr = val;
-               val += incr;
-       }
-
-       my_puts_P(PSTR("Reading..."));
-
-       for (addr = buf, val = pattern; addr < end; addr++) {
-               readback = *addr;
-               if (readback != val) {
-                       uint32_t offset = addr - buf;
-
-                       printf_P(PSTR("\nMem error @ 0x%08X: "
-                               "found %08lX, expected %08lX\n"),
-                               (unsigned int)(uintptr_t)(start_addr + offset*sizeof(vu_long)),
-                               readback, val);
-                       errs++;
-                       if (ctrlc())
-                               return -1;
-               }
-               val += incr;
-       }
-
-       return 0;
+       return errs;
 }
 
 /*
@@ -769,77 +696,61 @@ static uint32_t mem_test_quick(vu_long *buf, uint32_t start_addr, uint32_t end_a
 command_ret_t do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc,
                        char * const argv[])
 {
-       uint32_t start, end;
-       vu_long *buf, *dummy;
-       int iteration_limit;
-/* TODO: command_ret_t */
+       uint32_t start = 0;
+       uint32_t end;
+       unsigned int iteration_limit = 0;
+       unsigned int iteration;
+       uint32_t errs = 0;      /* number of errors */
        int ret;
-       uint32_t errs = 0;      /* number of errors, or -1 if interrupted */
-       uint32_t pattern;
-       int iteration;
-#if defined(CONFIG_SYS_ALT_MEMTEST)
-       const int alt_test = 1;
-#else
-       const int alt_test = 0;
-#endif
+
+       (void) cmdtp;
+       (void) flag;
 
        if (argc > 1)
                start = strtoul(argv[1], NULL, 16);
-       else
-               start = CONFIG_SYS_MEMTEST_START;
 
        if (argc > 2)
                end = strtoul(argv[2], NULL, 16);
        else
-               end = CONFIG_SYS_MEMTEST_END;
+               end = CONFIG_SYS_RAMSIZE_MAX - 1;
 
        if (argc > 3)
-               pattern = (uint32_t)strtoul(argv[3], NULL, 16);
-       else
-               pattern = 0;
+               iteration_limit = (unsigned int) strtoul(argv[3], NULL, 16);
 
-       if (argc > 4)
-               iteration_limit = (uint32_t)strtoul(argv[4], NULL, 16);
-       else
-               iteration_limit = 0;
+       printf_P(PSTR("Testing %05lx ... %05lx:\n"), start, end);
+//     debug("## %s:%d: start %#05lx end %#05lx\n", __func__, __LINE__, start, end);
 
-       printf_P(PSTR("Testing %08x ... %08x:\n"), (unsigned int)start, (unsigned int)end);
-       debug("%s:%d: start %#05lx end %#05lx\n", __func__, __LINE__,
-             start, end);
+       clear_ctrlc();          /* forget any previous Control C */
 
-/* TODO: */
-//     buf = map_sysmem(start, end - start);
-//     dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
        for (iteration = 0;
                        !iteration_limit || iteration < iteration_limit;
                        iteration++) {
-               if (ctrlc()) {
-                       errs = -1UL;
-                       break;
-               }
 
                printf_P(PSTR("Iteration: %6d\r"), iteration + 1);
-               debug("\n");
-               if (alt_test) {
-                       errs = mem_test_alt(buf, start, end, dummy);
-               } else {
-                       errs = mem_test_quick(buf, start, end, pattern,
-                                             iteration);
+//             debug("\n");
+
+               if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+                       my_puts_P(PSTR("Bus timeout\n"));
+                       return  CMD_RET_FAILURE;
                }
-               if (errs == -1UL)
+               errs += mem_test_alt(start, end);
+               z80_bus_cmd(Release);
+
+               if (had_ctrlc() || ctrlc()) {
                        break;
+               }
        }
 
-       if (errs == -1UL) {
+       if (had_ctrlc()) {
                /* Memory test was aborted - write a newline to finish off */
-               putc('\n');
-               ret = 1;
+               putchar('\n');
+               ret = CMD_RET_FAILURE;
        } else {
                printf_P(PSTR("Tested %d iteration(s) with %lu errors.\n"),
                        iteration, errs);
-               ret = errs != 0;
+               ret = errs ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
        }
 
-       return ret;     /* not reached */
+       return ret;
 }
 #endif /* CONFIG_CMD_MEMTEST */
index b6fa41864f6fba3b87e410e4381ff98fc4d1c81b..46e3a8af09d9a9ee54cac24162d025c76e12ac70 100644 (file)
@@ -149,8 +149,8 @@ cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len)
        for (cmdtp = table;
             cmdtp != table + table_len;
             cmdtp++) {
-               if (strncmp_P (cmd, cmdtp->name, len) == 0) {
-                       if (len == strlen (cmdtp->name))
+               if (strncmp_P(cmd, cmdtp->name, len) == 0) {
+                       if (len == strlen_P(cmdtp->name))
                                return cmdtp;   /* full match */
 
                        cmdtp_temp = cmdtp;     /* abbreviated command ? */
index 2163526212bb405e6770d2898c1a7dbb1340ceb0..6c1c10de579073ac7ea72c0351265b6a2373cf21 100644 (file)
@@ -212,23 +212,21 @@ CMD_TBL_ITEM(
        "    - set address offset for memory commands to 'offset'"
 ),
 CMD_TBL_ITEM(
-       loop,   3,      1,      do_mem_loop,
+       mloop,  3,      1,      do_mem_loop,
        "infinite loop on address range",
        "address number_of_bytes"
 ),
-#ifdef CONFIG_LOOPW
 CMD_TBL_ITEM(
-       loopw,  4,      1,      do_mem_loopw,
+       mloopw, 4,      1,      do_mem_loopw,
        "infinite write loop on address range",
        "address number_of_bytes data_to_write"
 ),
-#endif /* CONFIG_LOOPW */
 
 #ifdef CONFIG_CMD_MEMTEST
 CMD_TBL_ITEM(
-       mtest,  5,      1,      do_mem_mtest,
+       mtest,  4,      1,      do_mem_mtest,
        "simple RAM read/write test",
-       "[start [end [pattern [iterations]]]]"
+       "[start [end [iterations]]]"
 ),
 #endif /* CONFIG_CMD_MEMTEST */
 
@@ -239,7 +237,7 @@ CMD_TBL_ITEM(
        "address count delay(ms)"
 ),
 CMD_TBL_ITEM(
-       mwc,    4,      1,      do_mem_mwc,
+       mwc,    4,      1,      do_mem_mdc,
        "memory write cyclic",
        "address value delay(ms)"
 ),
index 4e7b1a8ec7e90e65f746fff8de1046154e19f000..01fb6b0bea8c32a99b9bbbfb5f92e164611f826d 100644 (file)
 //#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;
+}
+
+
 typedef enum {
        IHX_OK,
        IHX_BROKEN,
@@ -26,7 +62,7 @@ typedef struct {
        int8_t type;
        uint8_t len;
        uint16_t address;
-       uint8_t *data;
+       uint8_t data[256];
 } ihex_t;
 
 
@@ -57,6 +93,8 @@ int get_hexbyte(void) {
        return -1;
 }
 
+#if 0
+
 static
 ihex_t ihex_get_record() {
 
@@ -122,73 +160,138 @@ ihex_t ihex_get_record() {
        return rec;
 }
 
+#else
+
+static
+int ihex_get_record(ihex_t *rec) {
+
+       int c;
+       uint8_t sum;
+
+       rec->status = IHX_BROKEN;
+
+
+       while ((c = my_getchar(0)) != ':')
+               if (c == 0x03)
+                       return -1;
+
+       if ((c = get_hexbyte()) < 0)            /* Start code */
+                       return -1;
+       sum = c;
+       rec->len = c;
+       if ((c = get_hexbyte()) < 0)            /* Byte Count */
+                       return -1;
+       sum += c;
+       rec->address = c * 256;
+       if ((c = get_hexbyte()) < 0)            /* Address */
+                       return -1;
+       sum += c;
+       rec->address += c;
+       if ((c = get_hexbyte()) < 0)            /* Record type */
+               return -1;
+       sum += c;
+       rec->type = c;
+
+       if (rec->len) {                                         /* Record Data */
+               uint8_t n;
+
+               for (n = 0; n < rec->len; n++) {
+                       if ((c = get_hexbyte()) < 0)
+                               break;
+                       sum += c;
+                       rec->data[n] = c;
+               }
+
+               if (n < rec->len) {
+                       return -1;
+               }
+       }
+
+       c = get_hexbyte();                              /* Check sum */
+
+       if (c >= 0) {
+               sum += c;
+               if (sum == 0)
+                       rec->status = IHX_OK;
+               else
+                       rec->status = IHX_CHKSUMERR;
+       }
+
+       return rec->len;
+}
+
+#endif
 
 command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        long offset = 0;
        uint32_t base_address = 0;
-       uint32_t address_low = 0xffffffff;
+       uint32_t address_max = detect_ramsize();
        uint32_t address_high = 0;
-       bool done = false;
+       uint32_t address_low = address_max;
        command_ret_t rcode = CMD_RET_FAILURE;
        ihex_t rec;
 
-       (void) cmdtp;
-       (void) flag;
+       (void) cmdtp; (void) flag;
+
+
+       printf_P(PSTR("RAM Size: 0x%.5lX\n"), address_max);
+
 
        if (argc > 1)
                offset = strtol(argv[1], NULL, 16);
 
-       while (!done) {
-               rec = ihex_get_record();
+       while (ihex_get_record(&rec) > 0 &&
+                               rec.status == IHX_OK &&
+                               rec.type != 1 ) {
+
+               switch (rec.type) {
+               case 0: /* Data record */
+                       if (rec.len) {
+                               uint32_t addr = base_address + rec.address + offset;
+                               if (addr < address_low)
+                                       address_low = addr;
+                               if (addr+rec.len > address_high)
+                                       address_high = addr + rec.len;
 
-               if (rec.status == IHX_OK) {
-                       switch (rec.type) {
-                       case 0: /* Data record */
-                               if (rec.len) {
-                                       uint32_t addr = base_address + rec.address + offset;
-                                       if (addr < address_low)
-                                               address_low = addr;
-                                       if (addr+rec.len > address_high)
-                                               address_high = addr + rec.len;
 
-                                       z80_bus_cmd(Request);
+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);
+
+                               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_write_block(rec.data,               /* src */
                                                        addr,                                   /* dest */
                                                        rec.len);                               /* len */
                                        z80_bus_cmd(Release);
                                }
-                               continue;
-                               break;
-
-                       case 1: /* EOF record */
-
-                               done = true;
-                               break;
-
-                       case 2: /* Extended Segment Address Record */
-                               base_address = ((rec.data[0] << 8) + rec.data[1]) << 4;
-                               continue;
-                               break;
-
-                       case 4: /* Extended Linear Address Record */
-                               base_address = (uint32_t)((rec.data[0] << 8) + rec.data[1]) << 16;
-                               continue;
-                               break;
-
-                       case 3: /* Start Segment Address Record (ignored)*/
-                       case 5: /* Start Linear Address Record (ignored)*/
-                               continue;
-                               break;
-
                        }
+                       break;
 
-               } else
-                       done = true;
+#if 0
+               case 1: /* EOF record */
+                       break;
+#endif
+               case 2: /* Extended Segment Address Record */
+                       base_address = ((rec.data[0] << 8) + rec.data[1]) << 4;
+                       break;
 
-               free(rec.data);
-               rec.data = 0;
+               case 4: /* Extended Linear Address Record */
+                       base_address = (uint32_t)((rec.data[0] << 8) + rec.data[1]) << 16;
+                       break;
 
+               case 3: /* Start Segment Address Record (ignored)*/
+               case 5: /* Start Linear Address Record (ignored)*/
+                       break;
+
+               }
        }
 
        switch (rec.status) {
@@ -202,11 +305,16 @@ command_ret_t do_loadihex(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
                break;
        }
 
-       printf_P(PSTR("Data loaded - "));
-       if (address_low >= address_high)
+       printf_P(PSTR("Data loaded: "));
+       if (address_low >= min(address_high, address_max))
                printf_P(PSTR("None.\n"));
        else
-               printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low, address_high);
+               printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low,
+                               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);
 
        return rcode;
 }
index 05227cc4554b7782f5396ce1ba6a36e87cdf4eb8..782c10a94e679fa379ec35e06e7019418b930f0d 100644 (file)
@@ -19,15 +19,12 @@ extern command_ret_t do_mem_cp(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_mem_cmp(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_mem_base(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_mem_loop(cmd_tbl_t *, int, int, char * const []);
-#ifdef CONFIG_LOOPW
 extern command_ret_t do_mem_loopw(cmd_tbl_t *, int, int, char * const []);
-#endif
 #ifdef CONFIG_CMD_MEMTEST
 extern command_ret_t do_mem_mtest(cmd_tbl_t *, int, int, char * const []);
 #endif
 #ifdef CONFIG_MX_CYCLIC
 extern command_ret_t do_mem_mdc(cmd_tbl_t *, int, int, char * const []);
-extern command_ret_t do_mem_mwc(cmd_tbl_t *, int, int, char * const []);
 #endif /* CONFIG_MX_CYCLIC */
 
 #endif /* CMD_MEM_H */
index f51ebe926d2db8e7fcb082f163656cd39817111a..646835da8402d4ba51cd78f4669bd71d4a1000d7 100644 (file)
@@ -23,9 +23,9 @@
 #define CONFIG_BOOTDELAY       4
 //#define CONFIG_ZERO_BOOTDELAY_CHECK  1
 
-//#define CONFIG_LOOPW
-//#define CONFIG_CMD_MEMTEST
-//#define CONFIG_MX_CYCLIC
+#define CONFIG_CMD_MEMTEST
+#define CONFIG_MX_CYCLIC
+#define CONFIG_SYS_RAMSIZE_MAX (1l<<19)        /* max. addressable memory */
 
 #define CONFIG_CMD_DATE 1