Save/restore registers to host during memory operations. Cache ROM data.
authorKeith Packard <keithp@keithp.com>
Wed, 31 Dec 2008 06:35:53 +0000 (22:35 -0800)
committerKeith Packard <keithp@keithp.com>
Wed, 31 Dec 2008 06:38:35 +0000 (22:38 -0800)
Because the debug port uses instructions for most operations, the debug code
will clobber registers used by the running program. Save and restore these
to avoid corrupting application data.

If the ROM file is known, use that to return data instead of fetching it
from the target to improve performance.

Signed-off-by: Keith Packard <keithp@keithp.com>
lib/Makefile.am
lib/ccdbg-debug.c
lib/ccdbg-debug.h
lib/ccdbg-flash.c
lib/ccdbg-memory.c
lib/ccdbg-rom.c [new file with mode: 0644]
lib/ccdbg-state.c [new file with mode: 0644]
lib/ccdbg.h
s51/s51-command.c
s51/s51-parse.c
s51/s51.h

index 16f5b921e6581ee4c0bd2ae8fdb1b8f2e364a008..ba6f9725c4b4973a12e72f20b80b6c8091af1a3f 100644 (file)
@@ -11,5 +11,7 @@ libcc_a_SOURCES = \
        ccdbg-io.c \
        ccdbg-manual.c \
        ccdbg-memory.c \
        ccdbg-io.c \
        ccdbg-manual.c \
        ccdbg-memory.c \
+       ccdbg-rom.c \
+       ccdbg-state.c \
        cp-usb.c \
        cp-usb-async.c
        cp-usb.c \
        cp-usb-async.c
index 8f6f9e11a800c20bec8d764d0b87678fc6c19d7d..847361c7bf142b9717c638260a11007863d7154f 100644 (file)
@@ -47,7 +47,8 @@ ccdbg_debug(int level, char *format, ...)
 }
 
 void
 }
 
 void
-ccdbg_flush(void)
+ccdbg_flush(int level)
 {
 {
-       fflush(stdout);
+       if (ccdbg_level & level)
+               fflush(stdout);
 }
 }
index a09148d32ddc8d08ad19535e9a0209d935efdb39..0b5b44c131a39cf5e5fbbe46c681148cb0975ba9 100644 (file)
@@ -39,6 +39,6 @@ void
 ccdbg_clear_debug(int level);
 
 void
 ccdbg_clear_debug(int level);
 
 void
-ccdbg_flush(void);
+ccdbg_flush(int level);
 
 #endif /* _CCDBG_DEBUG_H_ */
 
 #endif /* _CCDBG_DEBUG_H_ */
index 8b3390c7787719b203983b25943bf7ff57577938..8a586a21ccb4fc076da2886881d9830662736925 100644 (file)
@@ -288,13 +288,14 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)
 
                ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr);
                ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time);
 
                ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr);
                ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time);
-
+#if 0
                ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in ram\n", this_time);
                ccdbg_read_memory(dbg, ram_addr, verify, this_time);
                if (memcmp (image->data + start, verify, this_time) != 0) {
                        fprintf(stderr, "ram verify failed\n");
                        return 1;
                }
                ccdbg_debug(CC_DEBUG_FLASH, "Verify %d bytes in ram\n", this_time);
                ccdbg_read_memory(dbg, ram_addr, verify, this_time);
                if (memcmp (image->data + start, verify, this_time) != 0) {
                        fprintf(stderr, "ram verify failed\n");
                        return 1;
                }
+#endif
                
                flash_addr = image->address + start;
                flash_word_addr = flash_addr >> 1;
                
                flash_addr = image->address + start;
                flash_word_addr = flash_addr >> 1;
@@ -324,10 +325,13 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image)
                status = ccdbg_resume(dbg);
                for (times = 0; times < 10; times++) {
                        status = ccdbg_read_status(dbg);
                status = ccdbg_resume(dbg);
                for (times = 0; times < 10; times++) {
                        status = ccdbg_read_status(dbg);
-                       ccdbg_debug(CC_DEBUG_FLASH, "chip status is 0x%02x\n", status);
+                       ccdbg_debug(CC_DEBUG_FLASH, ".");
+                       ccdbg_flush(CC_DEBUG_FLASH);
                        if ((status & CC_STATUS_CPU_HALTED) != 0)
                                break;
                        if ((status & CC_STATUS_CPU_HALTED) != 0)
                                break;
+                       usleep(10000);
                }
                }
+               ccdbg_debug(CC_DEBUG_FLASH, "\n");
                if (times == 10) {
                        fprintf(stderr, "flash page timed out\n");
                        return 1;
                if (times == 10) {
                        fprintf(stderr, "flash page timed out\n");
                        return 1;
index d74726fb11e8bd875a03a0da423b24eb50aac565..20a247999ae1a59339eb1e822c7bfe93bea16d09 100644 (file)
  */
 
 static uint8_t memory_init[] = {
  */
 
 static uint8_t memory_init[] = {
-       2,      MOV_direct_A,           0x7f,
-       3,      MOV_direct1_direct2,    0x7e, SFR_DPL0,
-       3,      MOV_direct1_direct2,    0x7d, SFR_DPH0,
-       3,      MOV_direct1_direct2,    0x7c, SFR_DPL1,
-       3,      MOV_direct1_direct2,    0x7b, SFR_DPH1,
        3,      MOV_DPTR_data16,        0,      0,
        3,      MOV_DPTR_data16,        0,      0,
-#define HIGH_START     21
-#define LOW_START      22
+#define HIGH_START     2
+#define LOW_START      3
        0,
 };
 
        0,
 };
 
@@ -49,19 +44,13 @@ static uint8_t read8[] = {
        0,
 };
 
        0,
 };
 
-static uint8_t memory_fini[] = {
-       2,      MOV_A_direct,           0x7f,
-       3,      MOV_direct1_direct2,    SFR_DPL0, 0x7e,
-       3,      MOV_direct1_direct2,    SFR_DPH0, 0x7d,
-       3,      MOV_direct1_direct2,    SFR_DPL1, 0x7c,
-       3,      MOV_direct1_direct2,    SFR_DPH1, 0x7b,
-       0,
-};
-
 uint8_t
 ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
 {
        int i, nl = 0;
 uint8_t
 ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
 {
        int i, nl = 0;
+       struct ccstate state;
+
+       ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP);
        memory_init[HIGH_START] = addr >> 8;
        memory_init[LOW_START] = addr;
        (void) ccdbg_execute(dbg, memory_init);
        memory_init[HIGH_START] = addr >> 8;
        memory_init[LOW_START] = addr;
        (void) ccdbg_execute(dbg, memory_init);
@@ -70,7 +59,7 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
                ccdbg_execute(dbg, write8);
                if ((i & 0xf) == 0xf) {
                        ccdbg_debug(CC_DEBUG_MEMORY, ".");
                ccdbg_execute(dbg, write8);
                if ((i & 0xf) == 0xf) {
                        ccdbg_debug(CC_DEBUG_MEMORY, ".");
-                       ccdbg_flush();
+                       ccdbg_flush(CC_DEBUG_MEMORY);
                        nl = 1;
                }
                if ((i & 0xff) == 0xff) {
                        nl = 1;
                }
                if ((i & 0xff) == 0xff) {
@@ -78,7 +67,7 @@ ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
                        nl = 0;
                }
        }
                        nl = 0;
                }
        }
-       (void) ccdbg_execute(dbg, memory_fini);
+       ccdbg_state_restore(dbg, &state);
        if (nl)
                ccdbg_debug(CC_DEBUG_MEMORY, "\n");
        return 0;
        if (nl)
                ccdbg_debug(CC_DEBUG_MEMORY, "\n");
        return 0;
@@ -88,6 +77,13 @@ uint8_t
 ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
 {
        int i, nl = 0;
 ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
 {
        int i, nl = 0;
+       struct ccstate state;
+
+       if (ccdbg_rom_contains(dbg, addr, nbytes)) {
+               ccdbg_rom_replace_xmem(dbg, addr, bytes, nbytes);
+               return 0;
+       }
+       ccdbg_state_save(dbg, &state, CC_STATE_ACC | CC_STATE_PSW | CC_STATE_DP);
        memory_init[HIGH_START] = addr >> 8;
        memory_init[LOW_START] = addr;
        (void) ccdbg_execute(dbg, memory_init);
        memory_init[HIGH_START] = addr >> 8;
        memory_init[LOW_START] = addr;
        (void) ccdbg_execute(dbg, memory_init);
@@ -95,7 +91,7 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
                *bytes++ = ccdbg_execute(dbg, read8);
                if ((i & 0xf) == 0xf) {
                        ccdbg_debug(CC_DEBUG_MEMORY, ".");
                *bytes++ = ccdbg_execute(dbg, read8);
                if ((i & 0xf) == 0xf) {
                        ccdbg_debug(CC_DEBUG_MEMORY, ".");
-                       ccdbg_flush();
+                       ccdbg_flush(CC_DEBUG_MEMORY);
                        nl = 1;
                }
                if ((i & 0xff) == 0xff) {
                        nl = 1;
                }
                if ((i & 0xff) == 0xff) {
@@ -103,7 +99,8 @@ ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
                        nl = 0;
                }
        }
                        nl = 0;
                }
        }
-       (void) ccdbg_execute(dbg, memory_fini);
+       ccdbg_state_replace_xmem(dbg, &state, addr, bytes, nbytes);
+       ccdbg_state_restore(dbg, &state);
        if (nl)
                ccdbg_debug(CC_DEBUG_MEMORY, "\n");
        return 0;
        if (nl)
                ccdbg_debug(CC_DEBUG_MEMORY, "\n");
        return 0;
@@ -135,16 +132,6 @@ ccdbg_read_hex_image(struct ccdbg *dbg, uint16_t address, uint16_t length)
        return image;
 }
 
        return image;
 }
 
-static uint8_t sfr_init[] = {
-       2,      MOV_direct_A,           0x7f,
-       0,
-};
-
-static uint8_t sfr_fini[] = {
-       2,      MOV_A_direct,           0x7f,
-       0,
-};
-
 static uint8_t sfr_read[] = {
        2,      MOV_A_direct,           0,
 #define SFR_READ_ADDR  2
 static uint8_t sfr_read[] = {
        2,      MOV_A_direct,           0,
 #define SFR_READ_ADDR  2
@@ -162,12 +149,15 @@ uint8_t
 ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes)
 {
        int     i;
 ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes)
 {
        int     i;
-       (void) ccdbg_execute(dbg, sfr_init);
+       struct ccstate state;
+
+       ccdbg_state_save(dbg, &state, CC_STATE_ACC);
        for (i = 0; i < nbytes; i++) {
                sfr_read[SFR_READ_ADDR] = addr + i;
                *bytes++ = ccdbg_execute(dbg, sfr_read);
        }
        for (i = 0; i < nbytes; i++) {
                sfr_read[SFR_READ_ADDR] = addr + i;
                *bytes++ = ccdbg_execute(dbg, sfr_read);
        }
-       (void) ccdbg_execute(dbg, sfr_fini);
+       ccdbg_state_replace_sfr(dbg, &state, addr, bytes, nbytes);
+       ccdbg_state_restore(dbg, &state);
        return 0;
 }
 
        return 0;
 }
 
diff --git a/lib/ccdbg-rom.c b/lib/ccdbg-rom.c
new file mode 100644 (file)
index 0000000..4559b4e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+uint8_t
+ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom)
+{
+       if (dbg->rom)
+               ccdbg_hex_image_free(dbg->rom);
+       dbg->rom = rom;
+       return 0;
+}
+
+uint8_t
+ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes)
+{
+       struct hex_image *rom = dbg->rom;
+       if (!rom)
+               return 0;
+       if (addr < rom->address || rom->address + rom->length < addr + nbytes)
+               return 0;
+       return 1;
+}
+
+uint8_t
+ccdbg_rom_replace_xmem(struct ccdbg *dbg,
+                      uint16_t addr, uint8_t *bytes, int nbytes)
+{
+       struct hex_image *rom = dbg->rom;
+       if (!rom)
+               return 0;
+       
+       if (rom->address < addr + nbytes && addr < rom->address + rom->length) {
+               int     start, stop;
+
+               start = addr;
+               if (addr < rom->address)
+                       start = rom->address;
+               stop = addr + nbytes;
+               if (rom->address + rom->length < stop)
+                       stop = rom->address + rom->length;
+               memcpy(bytes + start - addr, rom->data + start - rom->address,
+                      stop - start);
+               return 1;
+       }
+       return 0;
+}
diff --git a/lib/ccdbg-state.c b/lib/ccdbg-state.c
new file mode 100644 (file)
index 0000000..9aca8d2
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2008 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ccdbg.h"
+
+static uint8_t save_acc[] = {
+       1,      NOP,
+       0
+};
+
+static uint8_t save_sfr[] = {
+       2,      MOV_A_direct,   0,
+#define SAVE_SFR_ADDR  2
+       0,
+};
+
+struct sfr_state {
+       uint8_t         address;
+       uint16_t        mask;
+       char            *name;
+};
+
+static struct sfr_state        sfrs[CC_STATE_NSFR] = {
+       { SFR_DPL0,     CC_STATE_DP,    "dpl0" },
+       { SFR_DPH0,     CC_STATE_DP,    "dph0" },
+       { SFR_DPL1,     CC_STATE_DP,    "dpl1" },
+       { SFR_DPH1,     CC_STATE_DP,    "dph1" },
+       { PSW(0),       CC_STATE_PSW,   "psw"  },
+};
+
+uint8_t
+ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask)
+{
+       int     i;
+
+       mask |= CC_STATE_ACC;
+       if (mask & CC_STATE_ACC)
+               state->acc = ccdbg_execute(dbg, save_acc);
+       for (i = 0; i < CC_STATE_NSFR; i++) {
+               if (sfrs[i].mask & mask) {
+                       save_sfr[SAVE_SFR_ADDR] = sfrs[i].address;
+                       state->sfr[i] = ccdbg_execute(dbg, save_sfr);
+               }
+       }
+       state->mask = mask;
+       return 0;
+}
+
+static uint8_t restore_sfr[] = {
+       3,      MOV_direct_data,        0,      0,
+#define RESTORE_SFR_ADDR       2
+#define RESTORE_SFR_DATA       3
+       0
+};
+
+static uint8_t restore_acc[] = {
+       2,      MOV_A_data,     0,
+#define RESTORE_ACC_DATA       2
+       0
+};
+
+uint8_t
+ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state)
+{
+       int i;
+       for (i = CC_STATE_NSFR - 1; i >= 0; i--) {
+               if (sfrs[i].mask & state->mask) {
+                       restore_sfr[RESTORE_SFR_ADDR] = sfrs[i].address;
+                       restore_sfr[RESTORE_SFR_DATA] = state->sfr[i];
+                       ccdbg_execute(dbg, restore_sfr);
+               }
+       }
+       if (state->mask & CC_STATE_ACC) {
+               restore_acc[RESTORE_ACC_DATA] = state->acc;
+               ccdbg_execute(dbg, restore_acc);
+       }
+       state->mask = 0;
+       return 0;
+}
+
+static void
+ccdbg_state_replace(uint16_t sfr_addr, uint8_t sfr, char *name,
+                   uint16_t addr, uint8_t *bytes, int nbytes)
+{
+       sfr_addr += 0xdf00;
+
+       if (addr <= sfr_addr && sfr_addr < addr + nbytes) {
+               fprintf(stderr, "replacing %s at 0x%04x - read 0x%02x saved 0x%02x\n",
+                       name, sfr_addr, bytes[sfr_addr - addr], sfr);
+               bytes[sfr_addr - addr] = sfr;
+       }
+}
+
+void
+ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state,
+                        uint16_t addr, uint8_t *bytes, int nbytes)
+{
+       int i;
+       if (state->mask & CC_STATE_ACC)
+               ccdbg_state_replace(ACC(0), state->acc, "acc",
+                                   addr, bytes, nbytes);
+       for (i = 0; i < CC_STATE_NSFR; i++)
+               if (state->mask & sfrs[i].mask)
+                       ccdbg_state_replace(sfrs[i].address, state->sfr[i],
+                                           sfrs[i].name, addr, bytes, nbytes);
+}
+
+void
+ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state,
+                       uint8_t addr, uint8_t *bytes, int nbytes)
+{
+       ccdbg_state_replace_xmem(dbg, state, (uint16_t) addr + 0xdf00, bytes, nbytes);
+}
index 203b5aebb8c723b043f0654c95838afcfa7dcfac..241c4eecf311b717ee4f216cd9b84edf7c492a20 100644 (file)
@@ -39,6 +39,7 @@
 
 /* 8051 instructions
  */
 
 /* 8051 instructions
  */
+#define NOP                    0x00
 #define MOV_direct_data                0x75
 #define LJMP                   0x02
 #define MOV_Rn_data(n)         (0x78 | (n))
 #define MOV_direct_data                0x75
 #define LJMP                   0x02
 #define MOV_Rn_data(n)         (0x78 | (n))
 /* Bit-addressable accumulator */
 #define ACC(bit)               (0xE0 | (bit))
 
 /* Bit-addressable accumulator */
 #define ACC(bit)               (0xE0 | (bit))
 
+/* Bit-addressable status word */
+#define PSW(bit)               (0xD0 | (bit))
+
 #define CP_USB_ASYNC
 
 struct ccdbg {
 #define CP_USB_ASYNC
 
 struct ccdbg {
@@ -107,6 +111,7 @@ struct ccdbg {
 #else
        struct cp_usb *cp;
 #endif
 #else
        struct cp_usb *cp;
 #endif
+       struct hex_image *rom;
 };
 
 /* Intel hex file format data
 };
 
 /* Intel hex file format data
@@ -130,6 +135,18 @@ struct hex_image {
        uint8_t         data[0];
 };
 
        uint8_t         data[0];
 };
 
+#define CC_STATE_ACC   0x1
+#define CC_STATE_PSW   0x2
+#define CC_STATE_DP    0x4
+
+#define CC_STATE_NSFR  5
+
+struct ccstate {
+       uint16_t        mask;
+       uint8_t         acc;
+       uint8_t         sfr[CC_STATE_NSFR];
+};
+
 #define HEX_RECORD_NORMAL              0x00
 #define HEX_RECORD_EOF                 0x01
 #define HEX_RECORD_EXTENDED_ADDRESS    0x02
 #define HEX_RECORD_NORMAL              0x00
 #define HEX_RECORD_EOF                 0x01
 #define HEX_RECORD_EXTENDED_ADDRESS    0x02
@@ -337,4 +354,30 @@ ccdbg_read_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
 uint8_t
 ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
 
 uint8_t
 ccdbg_write_sfr(struct ccdbg *dbg, uint8_t addr, uint8_t *bytes, int nbytes);
 
+/* ccdbg-rom.c */
+uint8_t
+ccdbg_set_rom(struct ccdbg *dbg, struct hex_image *rom);
+
+uint8_t
+ccdbg_rom_contains(struct ccdbg *dbg, uint16_t addr, int nbytes);
+
+uint8_t
+ccdbg_rom_replace_xmem(struct ccdbg *dbg,
+                      uint16_t addrp, uint8_t *bytesp, int nbytes);
+
+/* ccdbg-state.c */
+uint8_t
+ccdbg_state_save(struct ccdbg *dbg, struct ccstate *state, unsigned int mask);
+
+uint8_t
+ccdbg_state_restore(struct ccdbg *dbg, struct ccstate *state);
+
+void
+ccdbg_state_replace_xmem(struct ccdbg *dbg, struct ccstate *state,
+                        uint16_t addr, uint8_t *bytes, int nbytes);
+
+void
+ccdbg_state_replace_sfr(struct ccdbg *dbg, struct ccstate *state,
+                       uint8_t addr, uint8_t *bytes, int nbytes);
+
 #endif /* _CCDBG_H_ */
 #endif /* _CCDBG_H_ */
index 25328f1ece4e4b1f587edd4e677642ac092c724f..63d142f45c3fd51b8e80e7961ac9ffce543f3fcd 100644 (file)
@@ -69,12 +69,12 @@ command_quit (int argc, char **argv)
 }
 
 static void
 }
 
 static void
-dump_bytes(uint8_t *memory, int length, uint16_t start)
+dump_bytes(uint8_t *memory, int length, uint16_t start, char *format)
 {
        int group, i;
        
        for (group = 0; group < length; group += 8) {
 {
        int group, i;
        
        for (group = 0; group < length; group += 8) {
-               s51_printf("0x%04x ", start + group);
+               s51_printf(format, start + group);
                for (i = group; i < length && i < group + 8; i++)
                        s51_printf("%02x ", memory[i]);
                for (; i < group + 8; i++)
                for (i = group; i < length && i < group + 8; i++)
                        s51_printf("%02x ", memory[i]);
                for (; i < group + 8; i++)
@@ -105,7 +105,7 @@ command_di (int argc, char **argv)
                return command_error;
        length = (int) end - (int) start + 1;
        status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
                return command_error;
        length = (int) end - (int) start + 1;
        status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
-       dump_bytes(memory, length, start);
+       dump_bytes(memory, length, start, "0x%02x ");
        return command_success;
 }
 
        return command_success;
 }
 
@@ -125,7 +125,7 @@ command_ds (int argc, char **argv)
                return command_error;
        length = (int) end - (int) start + 1;
        status = ccdbg_read_sfr(s51_dbg, start, memory, length);
                return command_error;
        length = (int) end - (int) start + 1;
        status = ccdbg_read_sfr(s51_dbg, start, memory, length);
-       dump_bytes(memory, length, start);
+       dump_bytes(memory, length, start, "0x%02x ");
        return command_success;
 }
 
        return command_success;
 }
 
@@ -145,7 +145,7 @@ command_dx (int argc, char **argv)
                return command_error;
        length = (int) end - (int) start + 1;
        status = ccdbg_read_memory(s51_dbg, start, memory, length);
                return command_error;
        length = (int) end - (int) start + 1;
        status = ccdbg_read_memory(s51_dbg, start, memory, length);
-       dump_bytes(memory, length, start);
+       dump_bytes(memory, length, start, "0x%04x ");
        return command_success;
 }
 
        return command_success;
 }
 
@@ -174,6 +174,7 @@ enum command_result
 command_file (int argc, char **argv)
 {
        struct hex_file *hex;
 command_file (int argc, char **argv)
 {
        struct hex_file *hex;
+       struct hex_image *image;
        FILE *file;
        
        if (argc != 2)
        FILE *file;
        
        if (argc != 2)
@@ -189,7 +190,10 @@ command_file (int argc, char **argv)
                ccdbg_hex_file_free(hex);
                return command_error;
        }
                ccdbg_hex_file_free(hex);
                return command_error;
        }
-       start_address = hex->records[0]->address;
+       image = ccdbg_hex_image_create(hex);
+       ccdbg_hex_file_free(hex);
+       start_address = image->address;
+       ccdbg_set_rom(s51_dbg, image);
        return command_success;
 }
 
        return command_success;
 }
 
@@ -473,6 +477,12 @@ command_halt (int argc, char **argv)
        return command_success;
 }
 
        return command_success;
 }
 
+enum command_result
+command_stop (int argc, char **argv)
+{
+       return command_success;
+}
+
 enum command_result
 command_reset (int argc, char **argv)
 {
 enum command_result
 command_reset (int argc, char **argv)
 {
@@ -511,6 +521,58 @@ command_status(int argc, char **argv)
        return command_success;
 }
 
        return command_success;
 }
 
+static enum command_result
+info_breakpoints(int argc, char **argv)
+{
+       int b;
+       uint16_t address;
+       enum command_result result;
+
+       if (argc == 1) {
+               s51_printf("Num Type       Disp Hit   Cnt   Address  What\n");
+               for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+                       if (breakpoints[b].enabled) {
+                               s51_printf("%-3d fetch      %s 1     1     0x%04x   uc::disass() unimplemented\n",
+                                          b,
+                                          breakpoints[b].temporary ? "del " : "keep",
+                                          breakpoints[b].address);
+                       }
+               return command_success;
+       }
+       
+}
+
+static enum command_result
+info_help(int argc, char **argv);
+
+static struct command_function infos[] = {
+       { "breakpoints", "b", info_breakpoints, "[b]reakpoints",
+               "List current breakpoints\n" },
+       { "help",   "?",  info_help,    "help",
+               "Print this list\n" },
+       
+       { NULL, NULL, NULL, NULL, NULL },
+};
+
+static enum command_result
+info_help(int argc, char **argv)
+{
+       return command_function_help(infos, argc, argv);
+}
+
+enum command_result
+command_info(int argc, char **argv)
+{
+       struct command_function *func;
+       
+       if (argc < 2)
+               return command_error;
+       func = command_string_to_function(infos, argv[1]);
+       if (!func)
+               return command_syntax;
+       return (*func->func)(argc-1, argv+1);
+}
+
 enum command_result
 cc_wait(void)
 {
 enum command_result
 cc_wait(void)
 {
index d0bfb45b943b4a8b4f6908701d92de09a3a053e4..749d7bd8490e873c97ad04e185fb7e23ab0f1b42 100644 (file)
 
 #include "s51.h"
 
 
 #include "s51.h"
 
-struct command_function {
-       char                    *name;
-       char                    *alias;
-       enum command_result     (*func)(int argc, char **argv);
-       char                    *usage;
-       char                    *help;
-};
-
 static struct command_function functions[] = {
        { "help",   "?",  command_help, "help",         "Print this list\n" },
        { "quit",   "q",  command_quit, "[q]uit",       "Quit\n" },
 static struct command_function functions[] = {
        { "help",   "?",  command_help, "help",         "Print this list\n" },
        { "quit",   "q",  command_quit, "[q]uit",       "Quit\n" },
@@ -50,6 +42,8 @@ static struct command_function functions[] = {
                "Clear break point\n" },
        { "run",    "r",  command_run, "[r]un [start] [stop]",
                "Run with optional start and temp breakpoint addresses\n" },
                "Clear break point\n" },
        { "run",    "r",  command_run, "[r]un [start] [stop]",
                "Run with optional start and temp breakpoint addresses\n" },
+       { "go",     "g",  command_run, "[g]o [start] [stop]",
+               "Run with optional start and temp breakpoint addresses\n" },
        { "next",   "n",  command_next, "[n]ext",
                "Step over one instruction, past any call\n" },
        { "step",   "s",  command_step, "[s]tep",
        { "next",   "n",  command_next, "[n]ext",
                "Step over one instruction, past any call\n" },
        { "step",   "s",  command_step, "[s]tep",
@@ -62,10 +56,13 @@ static struct command_function functions[] = {
                "Reset the CPU\n" },
        { "status","status",command_status, "status",
                "Display CC1111 debug status\n" },
                "Reset the CPU\n" },
        { "status","status",command_status, "status",
                "Display CC1111 debug status\n" },
+       { "info",   "i",  command_info, "[i]info",
+               "Get information\n" },
+       { "stop",  "stop", command_stop, "stop",
+               "Ignored\n" },
+       { NULL, NULL, NULL, NULL, NULL },
 };
 
 };
 
-#define NUM_FUNCTIONS (sizeof functions / sizeof functions[0])
-
 #ifndef FALSE
 #define FALSE 0
 #define TRUE 1
 #ifndef FALSE
 #define FALSE 0
 #define TRUE 1
@@ -106,17 +103,41 @@ string_to_int(char *s, int *v)
     return TRUE;
 }
 
     return TRUE;
 }
 
-static struct command_function *
-command_string_to_function(char *name)
+struct command_function *
+command_string_to_function(struct command_function *functions, char *name)
 {
        int i;
 {
        int i;
-       for (i = 0; i < NUM_FUNCTIONS; i++)
+       for (i = 0; functions[i].name; i++)
                if (!strcmp(name, functions[i].name) ||
                    !strcmp(name, functions[i].alias))
                        return &functions[i];
        return NULL;
 }    
 
                if (!strcmp(name, functions[i].name) ||
                    !strcmp(name, functions[i].alias))
                        return &functions[i];
        return NULL;
 }    
 
+enum command_result
+command_function_help(struct command_function *functions, int argc, char **argv)
+{
+       int i;
+       struct command_function *func;
+
+       if (argc == 1) {
+               for (i = 0; functions[i].name; i++)
+                       s51_printf("%-10s%s\n", functions[i].name,
+                              functions[i].usage);
+       } else {
+               for (i = 1; i < argc; i++) {
+                       func = command_string_to_function(functions, argv[i]);
+                       if (!func) {
+                               s51_printf("%-10s unknown command\n", argv[i]);
+                               return command_syntax;
+                       }
+                       s51_printf("%-10s %s\n%s", func->name,
+                              func->usage, func->help);
+               }
+       }
+       return command_debug;
+}
+
 static int
 command_split_into_words(char *line, char **argv)
 {
 static int
 command_split_into_words(char *line, char **argv)
 {
@@ -153,28 +174,10 @@ command_split_into_words(char *line, char **argv)
 enum command_result
 command_help(int argc, char **argv)
 {
 enum command_result
 command_help(int argc, char **argv)
 {
-       int i;
-       struct command_function *func;
-
-       if (argc == 1) {
-               for (i = 0; i < NUM_FUNCTIONS; i++)
-                       s51_printf("%-10s%s\n", functions[i].name,
-                              functions[i].usage);
-       } else {
-               for (i = 1; i < argc; i++) {
-                       func = command_string_to_function(argv[i]);
-                       if (!func) {
-                               s51_printf("%-10s unknown command\n", argv[i]);
-                               return command_syntax;
-                       }
-                       s51_printf("%-10s %s\n%s", func->name,
-                              func->usage, func->help);
-               }
-       }
-       return command_debug;
+       return command_function_help(functions, argc, argv);
 }
     
 }
     
-static void
+void
 command_syntax_error(int argc, char **argv)
 {
        s51_printf("Syntax error in:");
 command_syntax_error(int argc, char **argv)
 {
        s51_printf("Syntax error in:");
@@ -206,7 +209,7 @@ command_read (void)
                s51_interrupted = 0;
                argc = command_split_into_words(line, argv);
                if (argc > 0) {
                s51_interrupted = 0;
                argc = command_split_into_words(line, argv);
                if (argc > 0) {
-                       func = command_string_to_function(argv[0]);
+                       func = command_string_to_function(functions, argv[0]);
                        if (!func)
                                command_syntax_error(argc, argv);
                        else
                        if (!func)
                                command_syntax_error(argc, argv);
                        else
index eab61452ad49e108e713d471b848199e1724294c..f4dcce66d259b6ea20159daaddea9fa1acb879eb 100644 (file)
--- a/s51/s51.h
+++ b/s51/s51.h
@@ -27,12 +27,32 @@ enum command_result {
        command_success, command_debug, command_syntax, command_interrupt, command_error,
 };
 
        command_success, command_debug, command_syntax, command_interrupt, command_error,
 };
 
+struct command_function {
+       char                    *name;
+       char                    *alias;
+       enum command_result     (*func)(int argc, char **argv);
+       char                    *usage;
+       char                    *help;
+};
+
+struct command_function *
+command_string_to_function(struct command_function *functions, char *name);
+
+enum command_result
+command_function_help(struct command_function *functions, int argc, char **argv);
+
+void
+command_syntax_error(int argc, char **argv);
+
 enum command_result
 command_quit (int argc, char **argv);
 
 enum command_result
 command_help (int argc, char **argv);
 
 enum command_result
 command_quit (int argc, char **argv);
 
 enum command_result
 command_help (int argc, char **argv);
 
+enum command_result
+command_stop (int argc, char **argv);
+
 enum command_result
 command_di (int argc, char **argv);
 
 enum command_result
 command_di (int argc, char **argv);
 
@@ -81,6 +101,9 @@ command_reset (int argc, char **argv);
 enum command_result
 command_status (int argc, char **argv);
 
 enum command_result
 command_status (int argc, char **argv);
 
+enum command_result
+command_info (int argc, char **argv);
+
 enum command_result
 cc_wait(void);
 
 enum command_result
 cc_wait(void);