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;
50 command_quit (int argc, char **argv)
57 dump_bytes(uint8_t *memory, int length, uint16_t start)
61 for (group = 0; group < length; group += 8) {
62 s51_printf("0x%04x ", start + group);
63 for (i = group; i < length && i < group + 8; i++)
64 s51_printf("%02x ", memory[i]);
65 for (; i < group + 8; i++)
67 for (i = group; i < length && i < group + 8; i++) {
68 if (isascii(memory[i]) && isprint(memory[i]))
69 s51_printf("%c", memory[i]);
78 command_di (int argc, char **argv)
81 uint8_t memory[65536];
87 if (parse_uint16(argv[1], &start) != command_success)
89 if (parse_uint16(argv[2], &end) != command_success)
91 length = (int) end - (int) start + 1;
92 status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
93 dump_bytes(memory, length, start);
94 return command_success;
98 command_ds (int argc, char **argv)
101 uint8_t memory[65536];
106 return command_error;
107 if (parse_uint16(argv[1], &start) != command_success)
108 return command_error;
109 if (parse_uint16(argv[2], &end) != command_success)
110 return command_error;
111 length = (int) end - (int) start + 1;
112 status = ccdbg_read_memory(s51_dbg, start + 0xdf00, memory, length);
113 dump_bytes(memory, length, start);
114 return command_success;
118 command_dx (int argc, char **argv)
121 uint8_t memory[65536];
126 return command_error;
127 if (parse_uint16(argv[1], &start) != command_success)
128 return command_error;
129 if (parse_uint16(argv[2], &end) != command_success)
130 return command_error;
131 length = (int) end - (int) start + 1;
132 status = ccdbg_read_memory(s51_dbg, start, memory, length);
133 dump_bytes(memory, length, start);
134 return command_success;
138 command_set (int argc, char **argv)
140 return command_error;
144 command_dump (int argc, char **argv)
146 return command_error;
150 command_file (int argc, char **argv)
152 struct hex_file *hex;
156 return command_error;
157 file = fopen (argv[1], "r");
159 return command_error;
160 hex = ccdbg_hex_file_read(file, argv[1]);
163 return command_error;
164 if (hex->nrecord == 0) {
165 ccdbg_hex_file_free(hex);
166 return command_error;
168 start_address = hex->records[0]->address;
169 return command_success;
173 command_pc (int argc, char **argv)
177 enum command_result result;
178 result = parse_uint16(argv[1], &pc);
179 if (result != command_success)
181 ccdbg_set_pc(s51_dbg, pc);
183 pc = ccdbg_get_pc(s51_dbg);
184 s51_printf(" 0x%04x 00\n", pc);
186 return command_success;
195 #define CC_NUM_BREAKPOINTS 4
197 static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
200 disable_breakpoint(int b)
204 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
205 if (status != 0x00 && status != 0xff)
206 s51_printf("disable_breakpoint status 0x%02x\n", status);
210 enable_breakpoint(int b)
214 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
216 s51_printf("enable_breakpoint status 0x%02x\n", status);
220 enable_breakpoints(void)
223 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
224 if (breakpoints[b].enabled)
225 enable_breakpoint(b);
229 set_breakpoint(uint16_t address, int temporary)
233 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
234 if (breakpoints[b].enabled == 0)
236 if (breakpoints[b].address == address)
239 if (b == CC_NUM_BREAKPOINTS) {
240 s51_printf("Error: too many breakpoints requested\n");
241 return command_success;
243 if (breakpoints[b].enabled == 0) {
244 breakpoints[b].address = address;
245 enable_breakpoint(b);
247 ++breakpoints[b].enabled;
248 s51_printf("Breakpoint %d at 0x%04x\n", b, address);
249 breakpoints[b].temporary += temporary;
250 return command_success;
254 clear_breakpoint(uint16_t address, int temporary)
259 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
260 if (breakpoints[b].enabled != 0 &&
261 ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
262 breakpoints[b].address == address)
265 if (b == CC_NUM_BREAKPOINTS) {
266 s51_printf("Error: no matching breakpoint found\n");
267 return command_success;
269 --breakpoints[b].enabled;
270 breakpoints[b].temporary -= temporary;
271 if (breakpoints[b].enabled == 0) {
272 disable_breakpoint(b);
273 breakpoints[b].address = -1;
275 return command_success;
280 find_breakpoint(uint16_t address)
284 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
285 if (breakpoints[b].enabled && breakpoints[b].address == address)
287 if (b == CC_NUM_BREAKPOINTS)
293 command_break (int argc, char **argv)
297 enum command_result result;
300 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
301 if (breakpoints[b].enabled)
302 s51_printf("Breakpoint %d 0x%04x\n",
303 b, breakpoints[b].address);
304 return command_success;
307 return command_error;
308 result = parse_uint16(argv[1], &address);
309 if (result != command_success)
312 return set_breakpoint(address, 0);
316 command_clear (int argc, char **argv)
320 enum command_result result;
323 return command_error;
324 result = parse_uint16(argv[1], &address);
325 if (result != command_success)
327 return clear_breakpoint(address, 0);
331 cc_stopped(uint8_t status)
338 pc = ccdbg_get_pc(s51_dbg);
339 if (status & CC_STATUS_CPU_HALTED) {
340 if ((status & CC_STATUS_HALT_STATUS) != 0) {
343 reason = "Breakpoint";
344 b = find_breakpoint(pc);
345 if (b != -1 && breakpoints[b].temporary)
346 clear_breakpoint(pc, 1);
347 ccdbg_set_pc(s51_dbg, pc);
350 reason = "Interrupt";
352 s51_printf("Stop at 0x%04x: (%d) %s\n",
363 b = find_breakpoint(pc);
365 disable_breakpoint(b);
366 status = ccdbg_step_instr(s51_dbg);
368 enable_breakpoint(b);
373 command_run (int argc, char **argv)
376 enum command_result result;
382 result = parse_uint16(argv[1], &start);
383 if (result != command_success)
386 result = parse_uint16(argv[2], &end);
387 if (result != command_success)
390 if (start_address && start == 0) {
391 start = start_address;
392 s51_printf("Starting at 0x%04x\n", start);
394 ccdbg_set_pc(s51_dbg, start);
397 start = ccdbg_get_pc(s51_dbg);
398 s51_printf("Resume at 0x%04x\n", start);
400 b = find_breakpoint(pc);
403 pc = ccdbg_get_pc(s51_dbg);
404 if (find_breakpoint(pc) != -1) {
405 status = ccdbg_read_status(s51_dbg);
407 return command_success;
410 ccdbg_resume(s51_dbg);
416 command_next (int argc, char **argv)
418 return command_step(argc, argv);
422 command_step (int argc, char **argv)
428 a = cc_step(ccdbg_get_pc(s51_dbg));
429 s51_printf(" ACC= 0x%02x\n", a);
430 pc = ccdbg_get_pc(s51_dbg);
431 ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
432 s51_printf(" ? 0x%04x %02x\n", pc, opcode);
433 return command_success;
437 command_load (int argc, char **argv)
439 return command_error;
443 command_halt (int argc, char **argv)
447 pc = ccdbg_get_pc(s51_dbg);
448 s51_printf("Halted at 0x%04x\n", pc);
449 return command_success;
453 command_reset (int argc, char **argv)
455 ccdbg_debug_mode(s51_dbg);
457 enable_breakpoints();
458 return command_success;
462 command_status(int argc, char **argv)
466 status = ccdbg_read_status(s51_dbg);
467 if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
468 s51_printf("\tChip erase in progress\n");
469 if (status & CC_STATUS_PCON_IDLE)
470 s51_printf("\tCPU is idle (clock gated)\n");
471 if (status & CC_STATUS_CPU_HALTED)
472 s51_printf("\tCPU halted\n");
474 s51_printf("\tCPU running\n");
475 if ((status & CC_STATUS_POWER_MODE_0) == 0)
476 s51_printf("\tPower Mode 1-3 selected\n");
477 if (status & CC_STATUS_HALT_STATUS)
478 s51_printf("\tHalted by software or hw breakpoint\n");
480 s51_printf("\tHalted by debug command\n");
481 if (status & CC_STATUS_DEBUG_LOCKED)
482 s51_printf("\tDebug interface is locked\n");
483 if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
484 s51_printf("\tOscillators are not stable\n");
485 if (status & CC_STATUS_STACK_OVERFLOW)
486 s51_printf("\tStack overflow\n");
487 return command_success;
495 status = ccdbg_read_status(s51_dbg);
496 if (status & CC_STATUS_CPU_HALTED) {
498 return command_success;
500 if (s51_interrupted || s51_check_input()) {
503 status = ccdbg_read_status(s51_dbg);
505 return command_interrupt;