diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | ccdbg-command.c | 23 | ||||
| -rw-r--r-- | ccdbg-io.c | 12 | ||||
| -rw-r--r-- | ccdbg-memory.c | 75 | ||||
| -rw-r--r-- | ccdbg.c | 61 | ||||
| -rw-r--r-- | ccdbg.h | 14 | 
6 files changed, 162 insertions, 27 deletions
| @@ -9,7 +9,9 @@ LIBS=-lusb  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 diff --git a/ccdbg-command.c b/ccdbg-command.c index 415010f8..50dd1fd4 100644 --- a/ccdbg-command.c +++ b/ccdbg-command.c @@ -123,3 +123,26 @@ ccdbg_get_chip_id(struct ccdbg *dbg)  {  	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; +} + @@ -17,17 +17,15 @@   */  #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 * diff --git a/ccdbg-memory.c b/ccdbg-memory.c new file mode 100644 index 00000000..ffc09679 --- /dev/null +++ b/ccdbg-memory.c @@ -0,0 +1,75 @@ +/* + * 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; +} @@ -18,25 +18,42 @@  #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) @@ -44,6 +61,9 @@ 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) @@ -52,6 +72,7 @@ main (int argc, char **argv)  	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); @@ -59,7 +80,17 @@ main (int argc, char **argv)  	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); @@ -93,6 +93,7 @@ struct ccdbg {  #define CC_DEBUG_BITBANG	0x00000001  #define CC_DEBUG_COMMAND	0x00000002 +#define CC_DEBUG_INSTRUCTIONS	0x00000004  /* ccdbg-command.c */  void @@ -137,7 +138,8 @@ ccdbg_step_replace(struct ccdbg *dbg, uint8_t *instr, int nbytes);  uint16_t  ccdbg_get_chip_id(struct ccdbg *dbg); - +uint8_t +ccdbg_execute(struct ccdbg *dbg, uint8_t *inst);  /* ccdbg-debug.c */  void @@ -151,9 +153,6 @@ ccdbg_clear_debug(int level);  /* ccdbg-io.c */  void -ccdbg_quarter_clock(struct ccdbg *dbg); - -void  ccdbg_half_clock(struct ccdbg *dbg);  int @@ -224,6 +223,13 @@ ccdbg_print(char *format, uint8_t mask, uint8_t set);  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); | 
