2 * Copyright © 2008 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 static uint16_t start_address;
23 static enum command_result
24 parse_int(char *value, int *result)
28 *result = strtol(value, &endptr, 0);
30 return command_syntax;
31 return command_success;
34 static enum command_result
35 parse_uint16(char *value, uint16_t *uint16)
38 enum command_result result;
40 result = parse_int(value, &v);
41 if (result != command_success)
43 if (v < 0 || v > 0xffff)
46 return command_success;
49 static enum command_result
50 parse_uint8(char *value, uint8_t *uint8)
53 enum command_result result;
55 result = parse_int(value, &v);
56 if (result != command_success)
58 if (v < 0 || v > 0xff)
61 return command_success;
65 command_quit (int argc, char **argv)
72 dump_bytes(uint8_t *memory, int length, uint16_t start, char *format)
76 for (group = 0; group < length; group += 8) {
77 s51_printf(format, start + group);
78 for (i = group; i < length && i < group + 8; i++)
79 s51_printf("%02x ", memory[i]);
80 for (; i < group + 8; i++)
82 for (i = group; i < length && i < group + 8; i++) {
83 if (isascii(memory[i]) && isprint(memory[i]))
84 s51_printf("%c", memory[i]);
93 command_di (int argc, char **argv)
96 uint8_t memory[65536];
101 return command_error;
102 if (parse_uint16(argv[1], &start) != command_success)
103 return command_error;
104 if (parse_uint16(argv[2], &end) != command_success)
105 return command_error;
106 length = (int) end - (int) start + 1;
107 status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
108 dump_bytes(memory, length, start, "0x%02x ");
109 return command_success;
113 command_ds (int argc, char **argv)
116 uint8_t memory[0x100];
121 return command_error;
122 if (parse_uint8(argv[1], &start) != command_success)
123 return command_error;
124 if (parse_uint8(argv[2], &end) != command_success)
125 return command_error;
126 length = (int) end - (int) start + 1;
127 status = ccdbg_read_sfr(s51_dbg, start, memory, length);
128 dump_bytes(memory, length, start, "0x%02x ");
129 return command_success;
133 command_dx (int argc, char **argv)
136 uint8_t memory[65536];
141 return command_error;
142 if (parse_uint16(argv[1], &start) != command_success)
143 return command_error;
144 if (parse_uint16(argv[2], &end) != command_success)
145 return command_error;
146 length = (int) end - (int) start + 1;
147 status = ccdbg_read_memory(s51_dbg, start, memory, length);
148 dump_bytes(memory, length, start, "0x%04x ");
149 return command_success;
153 command_set (int argc, char **argv)
155 return command_error;
159 command_dump (int argc, char **argv)
162 if (strcmp(argv[1], "rom") == 0 ||
163 strcmp(argv[1], "xram") == 0)
164 return command_dx(argc-1, argv+1);
165 if (strcmp(argv[1], "iram") == 0)
166 return command_di(argc-1, argv+1);
167 if (strcmp(argv[1], "sfr") == 0)
168 return command_ds(argc-1, argv+1);
170 return command_error;
174 command_file (int argc, char **argv)
176 struct hex_file *hex;
177 struct hex_image *image;
181 return command_error;
182 file = fopen (argv[1], "r");
184 return command_error;
185 hex = ccdbg_hex_file_read(file, argv[1]);
188 return command_error;
189 if (hex->nrecord == 0) {
190 ccdbg_hex_file_free(hex);
191 return command_error;
193 image = ccdbg_hex_image_create(hex);
194 ccdbg_hex_file_free(hex);
195 start_address = image->address;
196 ccdbg_set_rom(s51_dbg, image);
197 return command_success;
201 command_pc (int argc, char **argv)
205 enum command_result result;
206 result = parse_uint16(argv[1], &pc);
207 if (result != command_success)
209 ccdbg_set_pc(s51_dbg, pc);
211 pc = ccdbg_get_pc(s51_dbg);
212 s51_printf(" 0x%04x 00\n", pc);
214 return command_success;
223 #define CC_NUM_BREAKPOINTS 4
225 static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
228 disable_breakpoint(int b)
232 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
233 if (status != 0x00 && status != 0xff)
234 s51_printf("disable_breakpoint status 0x%02x\n", status);
238 enable_breakpoint(int b)
242 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
244 s51_printf("enable_breakpoint status 0x%02x\n", status);
248 enable_breakpoints(void)
251 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
252 if (breakpoints[b].enabled)
253 enable_breakpoint(b);
257 set_breakpoint(uint16_t address, int temporary)
261 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
262 if (breakpoints[b].enabled == 0)
264 if (breakpoints[b].address == address)
267 if (b == CC_NUM_BREAKPOINTS) {
268 s51_printf("Error: too many breakpoints requested\n");
269 return command_success;
271 if (breakpoints[b].enabled == 0) {
272 breakpoints[b].address = address;
273 enable_breakpoint(b);
275 ++breakpoints[b].enabled;
276 s51_printf("Breakpoint %d at 0x%04x\n", b, address);
277 breakpoints[b].temporary += temporary;
278 return command_success;
282 clear_breakpoint(uint16_t address, int temporary)
287 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
288 if (breakpoints[b].enabled != 0 &&
289 ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
290 breakpoints[b].address == address)
293 if (b == CC_NUM_BREAKPOINTS) {
294 s51_printf("Error: no matching breakpoint found\n");
295 return command_success;
297 --breakpoints[b].enabled;
298 breakpoints[b].temporary -= temporary;
299 if (breakpoints[b].enabled == 0) {
300 disable_breakpoint(b);
301 breakpoints[b].address = -1;
303 return command_success;
308 find_breakpoint(uint16_t address)
312 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
313 if (breakpoints[b].enabled && breakpoints[b].address == address)
315 if (b == CC_NUM_BREAKPOINTS)
321 command_break (int argc, char **argv)
325 enum command_result result;
328 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
329 if (breakpoints[b].enabled)
330 s51_printf("Breakpoint %d 0x%04x\n",
331 b, breakpoints[b].address);
332 return command_success;
335 return command_error;
336 result = parse_uint16(argv[1], &address);
337 if (result != command_success)
340 return set_breakpoint(address, 0);
344 command_clear (int argc, char **argv)
348 enum command_result result;
351 return command_error;
352 result = parse_uint16(argv[1], &address);
353 if (result != command_success)
355 return clear_breakpoint(address, 0);
359 cc_stopped(uint8_t status)
366 pc = ccdbg_get_pc(s51_dbg);
367 if (status & CC_STATUS_CPU_HALTED) {
368 if ((status & CC_STATUS_HALT_STATUS) != 0) {
371 reason = "Breakpoint";
372 b = find_breakpoint(pc);
373 if (b != -1 && breakpoints[b].temporary)
374 clear_breakpoint(pc, 1);
375 ccdbg_set_pc(s51_dbg, pc);
378 reason = "Interrupt";
380 s51_printf("Stop at 0x%04x: (%d) %s\n",
391 b = find_breakpoint(pc);
393 disable_breakpoint(b);
394 status = ccdbg_step_instr(s51_dbg);
396 enable_breakpoint(b);
401 command_run (int argc, char **argv)
404 enum command_result result;
410 result = parse_uint16(argv[1], &start);
411 if (result != command_success)
414 result = parse_uint16(argv[2], &end);
415 if (result != command_success)
418 if (start_address && start == 0) {
419 start = start_address;
420 s51_printf("Starting at 0x%04x\n", start);
422 ccdbg_set_pc(s51_dbg, start);
425 start = ccdbg_get_pc(s51_dbg);
426 s51_printf("Resume at 0x%04x\n", start);
428 b = find_breakpoint(pc);
431 pc = ccdbg_get_pc(s51_dbg);
432 if (find_breakpoint(pc) != -1) {
433 status = ccdbg_read_status(s51_dbg);
435 return command_success;
438 ccdbg_resume(s51_dbg);
444 command_next (int argc, char **argv)
446 return command_step(argc, argv);
450 command_step (int argc, char **argv)
456 a = cc_step(ccdbg_get_pc(s51_dbg));
457 s51_printf(" ACC= 0x%02x\n", a);
458 pc = ccdbg_get_pc(s51_dbg);
459 ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
460 s51_printf(" ? 0x%04x %02x\n", pc, opcode);
461 return command_success;
465 command_load (int argc, char **argv)
467 return command_error;
471 command_halt (int argc, char **argv)
475 pc = ccdbg_get_pc(s51_dbg);
476 s51_printf("Halted at 0x%04x\n", pc);
477 return command_success;
481 command_stop (int argc, char **argv)
483 return command_success;
487 command_reset (int argc, char **argv)
489 ccdbg_debug_mode(s51_dbg);
491 enable_breakpoints();
492 return command_success;
496 command_status(int argc, char **argv)
500 status = ccdbg_read_status(s51_dbg);
501 if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
502 s51_printf("\tChip erase in progress\n");
503 if (status & CC_STATUS_PCON_IDLE)
504 s51_printf("\tCPU is idle (clock gated)\n");
505 if (status & CC_STATUS_CPU_HALTED)
506 s51_printf("\tCPU halted\n");
508 s51_printf("\tCPU running\n");
509 if ((status & CC_STATUS_POWER_MODE_0) == 0)
510 s51_printf("\tPower Mode 1-3 selected\n");
511 if (status & CC_STATUS_HALT_STATUS)
512 s51_printf("\tHalted by software or hw breakpoint\n");
514 s51_printf("\tHalted by debug command\n");
515 if (status & CC_STATUS_DEBUG_LOCKED)
516 s51_printf("\tDebug interface is locked\n");
517 if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
518 s51_printf("\tOscillators are not stable\n");
519 if (status & CC_STATUS_STACK_OVERFLOW)
520 s51_printf("\tStack overflow\n");
521 return command_success;
524 static enum command_result
525 info_breakpoints(int argc, char **argv)
529 enum command_result result;
532 s51_printf("Num Type Disp Hit Cnt Address What\n");
533 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
534 if (breakpoints[b].enabled) {
535 s51_printf("%-3d fetch %s 1 1 0x%04x uc::disass() unimplemented\n",
537 breakpoints[b].temporary ? "del " : "keep",
538 breakpoints[b].address);
540 return command_success;
545 static enum command_result
546 info_help(int argc, char **argv);
548 static struct command_function infos[] = {
549 { "breakpoints", "b", info_breakpoints, "[b]reakpoints",
550 "List current breakpoints\n" },
551 { "help", "?", info_help, "help",
552 "Print this list\n" },
554 { NULL, NULL, NULL, NULL, NULL },
557 static enum command_result
558 info_help(int argc, char **argv)
560 return command_function_help(infos, argc, argv);
564 command_info(int argc, char **argv)
566 struct command_function *func;
569 return command_error;
570 func = command_string_to_function(infos, argv[1]);
572 return command_syntax;
573 return (*func->func)(argc-1, argv+1);
581 status = ccdbg_read_status(s51_dbg);
582 if (status & CC_STATUS_CPU_HALTED) {
584 return command_success;
586 if (s51_interrupted || s51_check_input()) {
589 status = ccdbg_read_status(s51_dbg);
591 return command_interrupt;