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 enum command_result
22 parse_int(char *value, int *result)
26 *result = strtol(value, &endptr, 0);
28 return command_syntax;
29 return command_success;
32 static enum command_result
33 parse_uint16(char *value, uint16_t *uint16)
36 enum command_result result;
38 result = parse_int(value, &v);
39 if (result != command_success)
41 if (v < 0 || v > 0xffff)
44 return command_success;
48 command_quit (int argc, char **argv)
55 dump_bytes(uint8_t *memory, int length, uint16_t start)
59 for (group = 0; group < length; group += 8) {
60 s51_printf("0x%04x ", start + group);
61 for (i = group; i < length && i < group + 8; i++)
62 s51_printf("%02x ", memory[i]);
63 for (; i < group + 8; i++)
65 for (i = group; i < length && i < group + 8; i++) {
66 if (isascii(memory[i]) && isprint(memory[i]))
67 s51_printf("%c", memory[i]);
76 command_di (int argc, char **argv)
79 uint8_t memory[65536];
85 if (parse_uint16(argv[1], &start) != command_success)
87 if (parse_uint16(argv[2], &end) != command_success)
89 length = (int) end - (int) start + 1;
90 status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
91 dump_bytes(memory, length, start);
92 return command_success;
96 command_ds (int argc, char **argv)
99 uint8_t memory[65536];
104 return command_error;
105 if (parse_uint16(argv[1], &start) != command_success)
106 return command_error;
107 if (parse_uint16(argv[2], &end) != command_success)
108 return command_error;
109 length = (int) end - (int) start + 1;
110 status = ccdbg_read_memory(s51_dbg, start + 0xdf00, memory, length);
111 dump_bytes(memory, length, start);
112 return command_success;
116 command_dx (int argc, char **argv)
119 uint8_t memory[65536];
124 return command_error;
125 if (parse_uint16(argv[1], &start) != command_success)
126 return command_error;
127 if (parse_uint16(argv[2], &end) != command_success)
128 return command_error;
129 length = (int) end - (int) start + 1;
130 status = ccdbg_read_memory(s51_dbg, start, memory, length);
131 dump_bytes(memory, length, start);
132 return command_success;
136 command_set (int argc, char **argv)
138 return command_error;
142 command_dump (int argc, char **argv)
144 return command_error;
148 command_file (int argc, char **argv)
151 return command_error;
152 s51_printf("some words read from %s\n", argv[1]);
153 return command_success;
157 command_pc (int argc, char **argv)
161 enum command_result result;
162 result = parse_uint16(argv[1], &pc);
163 if (result != command_success)
165 ccdbg_set_pc(s51_dbg, pc);
167 pc = ccdbg_get_pc(s51_dbg);
168 s51_printf(" 0x%04x 00\n", pc);
170 return command_success;
179 #define CC_NUM_BREAKPOINTS 4
181 static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
184 disable_breakpoint(int b)
188 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 0, breakpoints[b].address);
189 if (status != 0x00 && status != 0xff)
190 s51_printf("disable_breakpoint status 0x%02x\n", status);
194 enable_breakpoint(int b)
198 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, breakpoints[b].address);
200 s51_printf("enable_breakpoint status 0x%02x\n", status);
204 set_breakpoint(uint16_t address, int temporary)
208 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
209 if (breakpoints[b].enabled == 0)
211 if (breakpoints[b].address == address)
214 if (b == CC_NUM_BREAKPOINTS) {
215 s51_printf("Error: too many breakpoints requested\n");
216 return command_success;
218 if (breakpoints[b].enabled == 0) {
219 breakpoints[b].address = address;
220 enable_breakpoint(b);
222 ++breakpoints[b].enabled;
223 s51_printf("Breakpoint %d at 0x%04x\n", b, address);
224 breakpoints[b].temporary += temporary;
225 return command_success;
229 clear_breakpoint(uint16_t address, int temporary)
234 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
235 if (breakpoints[b].enabled != 0 &&
236 ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
237 breakpoints[b].address == address)
240 if (b == CC_NUM_BREAKPOINTS) {
241 s51_printf("Error: no matching breakpoint found\n");
242 return command_success;
244 --breakpoints[b].enabled;
245 breakpoints[b].temporary -= temporary;
246 if (breakpoints[b].enabled == 0) {
247 disable_breakpoint(b);
248 breakpoints[b].address = -1;
250 return command_success;
255 find_breakpoint(uint16_t address)
259 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
260 if (breakpoints[b].enabled && breakpoints[b].address == address)
262 if (b == CC_NUM_BREAKPOINTS)
264 if (breakpoints[b].temporary)
265 clear_breakpoint(address, 1);
269 command_break (int argc, char **argv)
273 enum command_result result;
276 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
277 if (breakpoints[b].enabled)
278 s51_printf("Breakpoint %d 0x%04x\n",
279 b, breakpoints[b].address);
280 return command_success;
283 return command_error;
284 result = parse_uint16(argv[1], &address);
285 if (result != command_success)
288 return set_breakpoint(address, 0);
292 command_clear (int argc, char **argv)
296 enum command_result result;
299 return command_error;
300 result = parse_uint16(argv[1], &address);
301 if (result != command_success)
303 return clear_breakpoint(address, 0);
307 cc_stopped(uint8_t status)
314 pc = ccdbg_get_pc(s51_dbg);
315 if (status & CC_STATUS_CPU_HALTED) {
316 if ((status & CC_STATUS_HALT_STATUS) != 0) {
319 reason = "Breakpoint";
320 ccdbg_set_pc(s51_dbg, pc);
323 reason = "Interrupt";
325 s51_printf("Stop at 0x%04x: (%d) %s\n",
336 b = find_breakpoint(pc);
338 disable_breakpoint(b);
339 status = ccdbg_step_instr(s51_dbg);
341 enable_breakpoint(b);
346 command_run (int argc, char **argv)
349 enum command_result result;
355 result = parse_uint16(argv[1], &start);
356 if (result != command_success)
359 result = parse_uint16(argv[2], &end);
360 if (result != command_success)
363 ccdbg_set_pc(s51_dbg, start);
366 start = ccdbg_get_pc(s51_dbg);
367 s51_printf("Resume at 0x%04x\n", start);
369 b = find_breakpoint(pc);
372 pc = ccdbg_get_pc(s51_dbg);
373 if (find_breakpoint(pc) != -1) {
374 status = ccdbg_read_status(s51_dbg);
376 return command_success;
379 ccdbg_resume(s51_dbg);
385 command_next (int argc, char **argv)
387 return command_step(argc, argv);
391 command_step (int argc, char **argv)
397 a = cc_step(ccdbg_get_pc(s51_dbg));
398 s51_printf(" ACC= 0x%02x\n", a);
399 pc = ccdbg_get_pc(s51_dbg);
400 ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
401 s51_printf(" ? 0x%04x %02x\n", pc, opcode);
402 return command_success;
406 command_load (int argc, char **argv)
408 return command_error;
412 command_halt (int argc, char **argv)
416 pc = ccdbg_get_pc(s51_dbg);
417 s51_printf("Halted at 0x%04x\n", pc);
418 return command_success;
422 command_reset (int argc, char **argv)
424 ccdbg_debug_mode(s51_dbg);
425 return command_success;
429 command_status(int argc, char **argv)
433 status = ccdbg_read_status(s51_dbg);
434 if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
435 s51_printf("\tChip erase in progress\n");
436 if (status & CC_STATUS_PCON_IDLE)
437 s51_printf("\tCPU is idle (clock gated)\n");
438 if (status & CC_STATUS_CPU_HALTED)
439 s51_printf("\tCPU halted\n");
441 s51_printf("\tCPU running\n");
442 if ((status & CC_STATUS_POWER_MODE_0) == 0)
443 s51_printf("\tPower Mode 1-3 selected\n");
444 if (status & CC_STATUS_HALT_STATUS)
445 s51_printf("\tHalted by software or hw breakpoint\n");
447 s51_printf("\tHalted by debug command\n");
448 if (status & CC_STATUS_DEBUG_LOCKED)
449 s51_printf("\tDebug interface is locked\n");
450 if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
451 s51_printf("\tOscillators are not stable\n");
452 if (status & CC_STATUS_STACK_OVERFLOW)
453 s51_printf("\tStack overflow\n");
454 return command_success;
462 status = ccdbg_read_status(s51_dbg);
463 if (status & CC_STATUS_CPU_HALTED) {
465 return command_success;
467 if (s51_interrupted || s51_check_input()) {
470 status = ccdbg_read_status(s51_dbg);
472 return command_interrupt;