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)
159 enum command_result ret = command_success;
162 return command_error;
163 if (parse_uint16(argv[2], &address) != command_success)
164 return command_error;
166 return command_success;
169 return command_error;
170 for (i = 0; i < len; i++)
171 if (parse_uint8(argv[i+3], &data[i]) != command_success)
172 return command_error;
174 if (strcmp(argv[1], "xram") == 0) {
175 ccdbg_write_memory(s51_dbg, address, data, len);
176 } else if (strcmp(argv[1], "iram") == 0) {
177 ccdbg_write_memory(s51_dbg, address + 0xff00, data, len);
178 } else if (strcmp(argv[1], "sfr") == 0) {
179 ccdbg_write_sfr(s51_dbg, (uint8_t) address, data, len);
187 command_dump (int argc, char **argv)
190 if (strcmp(argv[1], "rom") == 0 ||
191 strcmp(argv[1], "xram") == 0)
192 return command_dx(argc-1, argv+1);
193 if (strcmp(argv[1], "iram") == 0)
194 return command_di(argc-1, argv+1);
195 if (strcmp(argv[1], "sfr") == 0)
196 return command_ds(argc-1, argv+1);
198 return command_error;
202 command_file (int argc, char **argv)
204 struct hex_file *hex;
205 struct hex_image *image;
209 return command_error;
210 file = fopen (argv[1], "r");
212 return command_error;
213 hex = ccdbg_hex_file_read(file, argv[1]);
216 return command_error;
217 if (hex->nrecord == 0) {
218 ccdbg_hex_file_free(hex);
219 return command_error;
221 image = ccdbg_hex_image_create(hex);
222 ccdbg_hex_file_free(hex);
223 start_address = image->address;
224 ccdbg_set_rom(s51_dbg, image);
225 return command_success;
229 command_pc (int argc, char **argv)
233 enum command_result result;
234 result = parse_uint16(argv[1], &pc);
235 if (result != command_success)
237 ccdbg_set_pc(s51_dbg, pc);
239 pc = ccdbg_get_pc(s51_dbg);
240 s51_printf(" 0x%04x 00\n", pc);
242 return command_success;
251 #define CC_NUM_BREAKPOINTS 4
253 static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
256 disable_breakpoint(int b)
260 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
261 if (status != 0x00 && status != 0xff)
262 s51_printf("disable_breakpoint status 0x%02x\n", status);
266 enable_breakpoint(int b)
270 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
272 s51_printf("enable_breakpoint status 0x%02x\n", status);
276 enable_breakpoints(void)
279 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
280 if (breakpoints[b].enabled)
281 enable_breakpoint(b);
285 set_breakpoint(uint16_t address, int temporary)
289 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
290 if (breakpoints[b].enabled == 0)
292 if (breakpoints[b].address == address)
295 if (b == CC_NUM_BREAKPOINTS) {
296 s51_printf("Error: too many breakpoints requested\n");
297 return command_success;
299 if (breakpoints[b].enabled == 0) {
300 breakpoints[b].address = address;
301 enable_breakpoint(b);
303 ++breakpoints[b].enabled;
304 s51_printf("Breakpoint %d at 0x%04x\n", b, address);
305 breakpoints[b].temporary += temporary;
306 return command_success;
310 clear_breakpoint(uint16_t address, int temporary)
315 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
316 if (breakpoints[b].enabled != 0 &&
317 ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
318 breakpoints[b].address == address)
321 if (b == CC_NUM_BREAKPOINTS) {
322 s51_printf("Error: no matching breakpoint found\n");
323 return command_success;
325 --breakpoints[b].enabled;
326 breakpoints[b].temporary -= temporary;
327 if (breakpoints[b].enabled == 0) {
328 disable_breakpoint(b);
329 breakpoints[b].address = -1;
331 return command_success;
336 find_breakpoint(uint16_t address)
340 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
341 if (breakpoints[b].enabled && breakpoints[b].address == address)
343 if (b == CC_NUM_BREAKPOINTS)
349 command_break (int argc, char **argv)
353 enum command_result result;
356 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
357 if (breakpoints[b].enabled)
358 s51_printf("Breakpoint %d 0x%04x\n",
359 b, breakpoints[b].address);
360 return command_success;
363 return command_error;
364 result = parse_uint16(argv[1], &address);
365 if (result != command_success)
368 return set_breakpoint(address, 0);
372 command_clear (int argc, char **argv)
376 enum command_result result;
379 return command_error;
380 result = parse_uint16(argv[1], &address);
381 if (result != command_success)
383 return clear_breakpoint(address, 0);
387 cc_stopped(uint8_t status)
394 pc = ccdbg_get_pc(s51_dbg);
395 if (status & CC_STATUS_CPU_HALTED) {
396 if ((status & CC_STATUS_HALT_STATUS) != 0) {
399 reason = "Breakpoint";
400 b = find_breakpoint(pc);
401 if (b != -1 && breakpoints[b].temporary)
402 clear_breakpoint(pc, 1);
403 ccdbg_set_pc(s51_dbg, pc);
406 reason = "Interrupt";
408 s51_printf("Stop at 0x%04x: (%d) %s\n",
419 b = find_breakpoint(pc);
421 disable_breakpoint(b);
422 status = ccdbg_step_instr(s51_dbg);
424 enable_breakpoint(b);
429 command_run (int argc, char **argv)
432 enum command_result result;
438 result = parse_uint16(argv[1], &start);
439 if (result != command_success)
442 result = parse_uint16(argv[2], &end);
443 if (result != command_success)
446 if (start_address && start == 0) {
447 start = start_address;
448 s51_printf("Starting at 0x%04x\n", start);
450 ccdbg_set_pc(s51_dbg, start);
453 start = ccdbg_get_pc(s51_dbg);
454 s51_printf("Resume at 0x%04x\n", start);
456 b = find_breakpoint(pc);
459 pc = ccdbg_get_pc(s51_dbg);
460 if (find_breakpoint(pc) != -1) {
461 status = ccdbg_read_status(s51_dbg);
463 return command_success;
466 ccdbg_resume(s51_dbg);
472 command_next (int argc, char **argv)
474 return command_step(argc, argv);
478 command_step (int argc, char **argv)
484 a = cc_step(ccdbg_get_pc(s51_dbg));
485 s51_printf(" ACC= 0x%02x\n", a);
486 pc = ccdbg_get_pc(s51_dbg);
487 ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
488 s51_printf(" ? 0x%04x %02x\n", pc, opcode);
489 return command_success;
493 command_load (int argc, char **argv)
495 return command_error;
499 command_halt (int argc, char **argv)
503 pc = ccdbg_get_pc(s51_dbg);
504 s51_printf("Halted at 0x%04x\n", pc);
505 return command_success;
509 command_stop (int argc, char **argv)
511 return command_success;
515 command_reset (int argc, char **argv)
517 ccdbg_debug_mode(s51_dbg);
519 enable_breakpoints();
520 return command_success;
524 command_status(int argc, char **argv)
528 status = ccdbg_read_status(s51_dbg);
529 if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
530 s51_printf("\tChip erase in progress\n");
531 if (status & CC_STATUS_PCON_IDLE)
532 s51_printf("\tCPU is idle (clock gated)\n");
533 if (status & CC_STATUS_CPU_HALTED)
534 s51_printf("\tCPU halted\n");
536 s51_printf("\tCPU running\n");
537 if ((status & CC_STATUS_POWER_MODE_0) == 0)
538 s51_printf("\tPower Mode 1-3 selected\n");
539 if (status & CC_STATUS_HALT_STATUS)
540 s51_printf("\tHalted by software or hw breakpoint\n");
542 s51_printf("\tHalted by debug command\n");
543 if (status & CC_STATUS_DEBUG_LOCKED)
544 s51_printf("\tDebug interface is locked\n");
545 if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
546 s51_printf("\tOscillators are not stable\n");
547 if (status & CC_STATUS_STACK_OVERFLOW)
548 s51_printf("\tStack overflow\n");
549 return command_success;
552 static enum command_result
553 info_breakpoints(int argc, char **argv)
557 enum command_result result;
560 s51_printf("Num Type Disp Hit Cnt Address What\n");
561 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
562 if (breakpoints[b].enabled) {
563 s51_printf("%-3d fetch %s 1 1 0x%04x uc::disass() unimplemented\n",
565 breakpoints[b].temporary ? "del " : "keep",
566 breakpoints[b].address);
568 return command_success;
573 static enum command_result
574 info_help(int argc, char **argv);
576 static struct command_function infos[] = {
577 { "breakpoints", "b", info_breakpoints, "[b]reakpoints",
578 "List current breakpoints\n" },
579 { "help", "?", info_help, "help",
580 "Print this list\n" },
582 { NULL, NULL, NULL, NULL, NULL },
585 static enum command_result
586 info_help(int argc, char **argv)
588 return command_function_help(infos, argc, argv);
592 command_info(int argc, char **argv)
594 struct command_function *func;
597 return command_error;
598 func = command_string_to_function(infos, argv[1]);
600 return command_syntax;
601 return (*func->func)(argc-1, argv+1);
609 status = ccdbg_read_status(s51_dbg);
610 if (status & CC_STATUS_CPU_HALTED) {
612 return command_success;
614 if (s51_interrupted || s51_check_input()) {
617 status = ccdbg_read_status(s51_dbg);
619 return command_interrupt;