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)
76 for (group = 0; group < length; group += 8) {
77 s51_printf("0x%04x ", 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);
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);
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);
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;
180 return command_error;
181 file = fopen (argv[1], "r");
183 return command_error;
184 hex = ccdbg_hex_file_read(file, argv[1]);
187 return command_error;
188 if (hex->nrecord == 0) {
189 ccdbg_hex_file_free(hex);
190 return command_error;
192 start_address = hex->records[0]->address;
193 return command_success;
197 command_pc (int argc, char **argv)
201 enum command_result result;
202 result = parse_uint16(argv[1], &pc);
203 if (result != command_success)
205 ccdbg_set_pc(s51_dbg, pc);
207 pc = ccdbg_get_pc(s51_dbg);
208 s51_printf(" 0x%04x 00\n", pc);
210 return command_success;
219 #define CC_NUM_BREAKPOINTS 4
221 static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
224 disable_breakpoint(int b)
228 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
229 if (status != 0x00 && status != 0xff)
230 s51_printf("disable_breakpoint status 0x%02x\n", status);
234 enable_breakpoint(int b)
238 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
240 s51_printf("enable_breakpoint status 0x%02x\n", status);
244 enable_breakpoints(void)
247 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
248 if (breakpoints[b].enabled)
249 enable_breakpoint(b);
253 set_breakpoint(uint16_t address, int temporary)
257 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
258 if (breakpoints[b].enabled == 0)
260 if (breakpoints[b].address == address)
263 if (b == CC_NUM_BREAKPOINTS) {
264 s51_printf("Error: too many breakpoints requested\n");
265 return command_success;
267 if (breakpoints[b].enabled == 0) {
268 breakpoints[b].address = address;
269 enable_breakpoint(b);
271 ++breakpoints[b].enabled;
272 s51_printf("Breakpoint %d at 0x%04x\n", b, address);
273 breakpoints[b].temporary += temporary;
274 return command_success;
278 clear_breakpoint(uint16_t address, int temporary)
283 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
284 if (breakpoints[b].enabled != 0 &&
285 ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
286 breakpoints[b].address == address)
289 if (b == CC_NUM_BREAKPOINTS) {
290 s51_printf("Error: no matching breakpoint found\n");
291 return command_success;
293 --breakpoints[b].enabled;
294 breakpoints[b].temporary -= temporary;
295 if (breakpoints[b].enabled == 0) {
296 disable_breakpoint(b);
297 breakpoints[b].address = -1;
299 return command_success;
304 find_breakpoint(uint16_t address)
308 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
309 if (breakpoints[b].enabled && breakpoints[b].address == address)
311 if (b == CC_NUM_BREAKPOINTS)
317 command_break (int argc, char **argv)
321 enum command_result result;
324 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
325 if (breakpoints[b].enabled)
326 s51_printf("Breakpoint %d 0x%04x\n",
327 b, breakpoints[b].address);
328 return command_success;
331 return command_error;
332 result = parse_uint16(argv[1], &address);
333 if (result != command_success)
336 return set_breakpoint(address, 0);
340 command_clear (int argc, char **argv)
344 enum command_result result;
347 return command_error;
348 result = parse_uint16(argv[1], &address);
349 if (result != command_success)
351 return clear_breakpoint(address, 0);
355 cc_stopped(uint8_t status)
362 pc = ccdbg_get_pc(s51_dbg);
363 if (status & CC_STATUS_CPU_HALTED) {
364 if ((status & CC_STATUS_HALT_STATUS) != 0) {
367 reason = "Breakpoint";
368 b = find_breakpoint(pc);
369 if (b != -1 && breakpoints[b].temporary)
370 clear_breakpoint(pc, 1);
371 ccdbg_set_pc(s51_dbg, pc);
374 reason = "Interrupt";
376 s51_printf("Stop at 0x%04x: (%d) %s\n",
387 b = find_breakpoint(pc);
389 disable_breakpoint(b);
390 status = ccdbg_step_instr(s51_dbg);
392 enable_breakpoint(b);
397 command_run (int argc, char **argv)
400 enum command_result result;
406 result = parse_uint16(argv[1], &start);
407 if (result != command_success)
410 result = parse_uint16(argv[2], &end);
411 if (result != command_success)
414 if (start_address && start == 0) {
415 start = start_address;
416 s51_printf("Starting at 0x%04x\n", start);
418 ccdbg_set_pc(s51_dbg, start);
421 start = ccdbg_get_pc(s51_dbg);
422 s51_printf("Resume at 0x%04x\n", start);
424 b = find_breakpoint(pc);
427 pc = ccdbg_get_pc(s51_dbg);
428 if (find_breakpoint(pc) != -1) {
429 status = ccdbg_read_status(s51_dbg);
431 return command_success;
434 ccdbg_resume(s51_dbg);
440 command_next (int argc, char **argv)
442 return command_step(argc, argv);
446 command_step (int argc, char **argv)
452 a = cc_step(ccdbg_get_pc(s51_dbg));
453 s51_printf(" ACC= 0x%02x\n", a);
454 pc = ccdbg_get_pc(s51_dbg);
455 ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
456 s51_printf(" ? 0x%04x %02x\n", pc, opcode);
457 return command_success;
461 command_load (int argc, char **argv)
463 return command_error;
467 command_halt (int argc, char **argv)
471 pc = ccdbg_get_pc(s51_dbg);
472 s51_printf("Halted at 0x%04x\n", pc);
473 return command_success;
477 command_reset (int argc, char **argv)
479 ccdbg_debug_mode(s51_dbg);
481 enable_breakpoints();
482 return command_success;
486 command_status(int argc, char **argv)
490 status = ccdbg_read_status(s51_dbg);
491 if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
492 s51_printf("\tChip erase in progress\n");
493 if (status & CC_STATUS_PCON_IDLE)
494 s51_printf("\tCPU is idle (clock gated)\n");
495 if (status & CC_STATUS_CPU_HALTED)
496 s51_printf("\tCPU halted\n");
498 s51_printf("\tCPU running\n");
499 if ((status & CC_STATUS_POWER_MODE_0) == 0)
500 s51_printf("\tPower Mode 1-3 selected\n");
501 if (status & CC_STATUS_HALT_STATUS)
502 s51_printf("\tHalted by software or hw breakpoint\n");
504 s51_printf("\tHalted by debug command\n");
505 if (status & CC_STATUS_DEBUG_LOCKED)
506 s51_printf("\tDebug interface is locked\n");
507 if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
508 s51_printf("\tOscillators are not stable\n");
509 if (status & CC_STATUS_STACK_OVERFLOW)
510 s51_printf("\tStack overflow\n");
511 return command_success;
519 status = ccdbg_read_status(s51_dbg);
520 if (status & CC_STATUS_CPU_HALTED) {
522 return command_success;
524 if (s51_interrupted || s51_check_input()) {
527 status = ccdbg_read_status(s51_dbg);
529 return command_interrupt;