KERNEL_OBJS=cccp.o
LIBUSB_OBJS=cp-usb.o
-OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o ccdbg-io.o $(LIBUSB_OBJS)
+OBJS=ccdbg.o ccdbg-command.o ccdbg-debug.o \
+ ccdbg-io.o ccdbg-memory.o \
+ $(LIBUSB_OBJS)
INCS=ccdbg.h cccp.h
PROG=ccdbg
{
return ccdbg_cmd_write_read16(dbg, CC_GET_CHIP_ID, NULL, 0);
}
+
+/*
+ * Execute a sequence of instructions
+ */
+uint8_t
+ccdbg_execute(struct ccdbg *dbg, uint8_t *inst)
+{
+ uint8_t status = 0;
+ while(inst[0] != 0) {
+ uint8_t len = inst[0];
+ int i;
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, "\t%02x", inst[1]);
+ for (i = 0; i < len - 1; i++)
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " %02x", inst[i+2]);
+ status = ccdbg_debug_instr(dbg, inst+1, len);
+ for (; i < 3; i++)
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " ");
+ ccdbg_debug(CC_DEBUG_INSTRUCTIONS, " -> %02x\n", status);
+ inst += len + 1;
+ }
+ return status;
+}
+
*/
#include "ccdbg.h"
-
-void
-ccdbg_quarter_clock(struct ccdbg *dbg)
-{
- usleep(CC_CLOCK_US / 4);
-}
+#include <time.h>
void
ccdbg_half_clock(struct ccdbg *dbg)
{
- usleep(CC_CLOCK_US / 2);
+ struct timespec req, rem;
+ req.tv_sec = (CC_CLOCK_US / 2) / 1000000;
+ req.tv_nsec = ((CC_CLOCK_US / 2) % 1000000) * 1000;
+// nanosleep(&req, &rem);
}
struct ccdbg *
--- /dev/null
+/*
+ * 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"
+
+/*
+ * Read and write arbitrary memory through the debug port
+ */
+
+#define MOV_dptr_data16 0x90
+
+static uint8_t memory_init[] = {
+ 3, MOV_dptr_data16, 0, 0,
+#define HIGH_START 2
+#define LOW_START 3
+ 0,
+};
+
+#define MOV_a_data 0x74
+#define MOVX_atdptr_a 0xf0
+#define MOVX_a_atdptr 0xe0
+#define INC_dptr 0xa3
+
+static uint8_t write8[] = {
+ 2, MOV_a_data, 0,
+#define DATA_BYTE 2
+ 1, MOVX_atdptr_a,
+ 1, INC_dptr,
+ 0
+};
+
+static uint8_t read8[] = {
+ 1, MOVX_a_atdptr,
+ 1, INC_dptr,
+ 0,
+};
+
+uint8_t
+ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ memory_init[HIGH_START] = addr >> 8;
+ memory_init[LOW_START] = addr;
+ (void) ccdbg_execute(dbg, memory_init);
+ while (nbytes-- > 0) {
+ write8[DATA_BYTE] = *bytes++;
+ ccdbg_execute(dbg, write8);
+ }
+ return 0;
+}
+
+uint8_t
+ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes)
+{
+ memory_init[HIGH_START] = addr >> 8;
+ memory_init[LOW_START] = addr;
+ (void) ccdbg_execute(dbg, memory_init);
+ while (nbytes-- > 0)
+ *bytes++ = ccdbg_execute(dbg, read8);
+ return 0;
+}
#include "ccdbg.h"
-#define MOV 0x75
+#define MOV_direct_data 0x75
+#define LJMP 0x02
+#define MOV_Rn_data(n) (0x78 | (n))
+#define DJNZ_Rn_rel(n) (0xd8 | (n))
+#if 0
static uint8_t instructions[] = {
- 3, MOV, 0xfe, 0x02,
- 3, MOV, 0x90, 0xff,
+ 3, MOV_direct_data, 0xfe, 0x02,
+ 3, MOV_direct_data, 0x90, 0xff,
0
};
+#endif
-static void
-ccdbg_instructions(struct ccdbg *dbg, uint8_t *inst)
-{
- while(inst[0] != 0) {
- uint8_t len = inst[0];
- uint8_t status;
- status = ccdbg_debug_instr(dbg, inst+1, len);
- printf ("inst status 0x%02x\n", status);
- inst += len + 1;
- }
-}
+static uint8_t mem_instr[] = {
+ MOV_direct_data, 0xfe, 0x02,
+ MOV_direct_data, 0x90, 0xff,
+ MOV_Rn_data(2), 0x10,
+ MOV_Rn_data(0), 0xff,
+ MOV_Rn_data(1), 0xff,
+ DJNZ_Rn_rel(1), 0xfe,
+ DJNZ_Rn_rel(0), 0xfa,
+ DJNZ_Rn_rel(2), 0xf6,
+ MOV_direct_data, 0x90, 0xfd,
+ MOV_Rn_data(2), 0x10,
+ MOV_Rn_data(0), 0xff,
+ MOV_Rn_data(1), 0xff,
+ DJNZ_Rn_rel(1), 0xfe,
+ DJNZ_Rn_rel(0), 0xfa,
+ DJNZ_Rn_rel(2), 0xf6,
+ LJMP, 0xf0, 0x03
+};
+
+static uint8_t jump_mem[] = {
+ 3, LJMP, 0xf0, 0x00,
+ 0
+};
int
main (int argc, char **argv)
struct ccdbg *dbg;
uint8_t status;
uint16_t chip_id;
+ uint16_t pc;
+ uint8_t memory[0x10];
+ int i;
dbg = ccdbg_open("/dev/ttyUSB0");
if (!dbg)
ccdbg_manual(dbg, stdin);
#endif
#if 1
+ ccdbg_reset(dbg);
ccdbg_debug_mode(dbg);
status = ccdbg_read_status(dbg);
printf("Status: 0x%02x\n", status);
printf("Chip id: 0x%04x\n", chip_id);
status = ccdbg_halt(dbg);
printf ("halt status: 0x%02x\n", status);
- ccdbg_instructions(dbg, instructions);
+/* ccdbg_execute(dbg, instructions); */
+ ccdbg_write_memory(dbg, 0xf000, mem_instr, sizeof (mem_instr));
+ ccdbg_read_memory(dbg, 0xf000, memory, sizeof (memory));
+ for (i = 0; i < sizeof (memory); i++)
+ printf (" %02x", memory[i]);
+ printf ("\n");
+ ccdbg_execute(dbg, jump_mem);
+ pc = ccdbg_get_pc(dbg);
+ printf ("pc starts at 0x%04x\n", pc);
+ status = ccdbg_resume(dbg);
+ printf ("resume status: 0x%02x\n", status);
#endif
ccdbg_close(dbg);
exit (0);
#define CC_DEBUG_BITBANG 0x00000001
#define CC_DEBUG_COMMAND 0x00000002
+#define CC_DEBUG_INSTRUCTIONS 0x00000004
/* ccdbg-command.c */
void
uint16_t
ccdbg_get_chip_id(struct ccdbg *dbg);
-
+uint8_t
+ccdbg_execute(struct ccdbg *dbg, uint8_t *inst);
/* ccdbg-debug.c */
void
ccdbg_clear_debug(int level);
/* ccdbg-io.c */
-void
-ccdbg_quarter_clock(struct ccdbg *dbg);
-
void
ccdbg_half_clock(struct ccdbg *dbg);
void
ccdbg_manual(struct ccdbg *dbg, FILE *input);
+/* ccdbg-memory.c */
+uint8_t
+ccdbg_write_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
+
+uint8_t
+ccdbg_read_memory(struct ccdbg *dbg, uint16_t addr, uint8_t *bytes, int nbytes);
+
/* cp-usb.c */
void
cp_usb_init(struct ccdbg *dbg);