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_proceed;
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_proceed)
41 if (v < 0 || v > 0xffff)
44 return command_proceed;
48 command_quit (FILE *output, int argc, char **argv)
55 dump_bytes(FILE *output, uint8_t *memory, int length, uint16_t start)
59 for (group = 0; group < length; group += 8) {
60 fprintf(output, "0x%04x ", start + group);
61 for (i = group; i < length && i < group + 8; i++)
62 fprintf(output, "%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 fprintf(output, "%c", memory[i]);
71 fprintf(output, "\n");
76 command_di (FILE *output, int argc, char **argv)
79 uint8_t memory[65536];
85 if (parse_uint16(argv[1], &start) != command_proceed)
87 if (parse_uint16(argv[2], &end) != command_proceed)
89 length = (int) end - (int) start + 1;
90 status = ccdbg_read_memory(s51_dbg, start + 0xff00, memory, length);
91 dump_bytes(output, memory, length, start);
92 return command_proceed;
96 command_ds (FILE *output, int argc, char **argv)
99 uint8_t memory[65536];
104 return command_error;
105 if (parse_uint16(argv[1], &start) != command_proceed)
106 return command_error;
107 if (parse_uint16(argv[2], &end) != command_proceed)
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(output, memory, length, start);
112 return command_proceed;
116 command_dx (FILE *output, int argc, char **argv)
119 uint8_t memory[65536];
124 return command_error;
125 if (parse_uint16(argv[1], &start) != command_proceed)
126 return command_error;
127 if (parse_uint16(argv[2], &end) != command_proceed)
128 return command_error;
129 length = (int) end - (int) start + 1;
130 status = ccdbg_read_memory(s51_dbg, start, memory, length);
131 dump_bytes(output, memory, length, start);
132 return command_proceed;
136 command_set (FILE *output, int argc, char **argv)
138 return command_error;
142 command_dump (FILE *output, int argc, char **argv)
144 return command_error;
148 command_pc (FILE *output, int argc, char **argv)
152 enum command_result result;
153 result = parse_uint16(argv[1], &pc);
154 if (result != command_proceed)
156 ccdbg_set_pc(s51_dbg, pc);
158 pc = ccdbg_get_pc(s51_dbg);
159 printf (" 0x%04x\n", pc);
161 return command_proceed;
170 #define CC_NUM_BREAKPOINTS 4
172 static struct cc_break breakpoints[CC_NUM_BREAKPOINTS];
175 set_breakpoint(FILE *output, uint16_t address, int temporary)
179 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
180 if (breakpoints[b].enabled == 0)
182 if (breakpoints[b].address == address)
185 if (b == CC_NUM_BREAKPOINTS) {
186 fprintf(output, "Error: too many breakpoints requested\n");
187 return command_proceed;
189 if (breakpoints[b].enabled == 0) {
190 breakpoints[b].address = address;
191 status = ccdbg_set_hw_brkpnt(s51_dbg, b, 1, address);
192 fprintf(output, "set_hw_brkpnt status 0x%02x\n", status);
194 ++breakpoints[b].enabled;
195 fprintf(output, "Breakpoint %d at 0x%04x\n", b, address);
196 breakpoints[b].temporary += temporary;
197 return command_proceed;
201 clear_breakpoint(FILE *output, uint16_t address, int temporary)
206 for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
207 if (breakpoints[b].enabled != 0 &&
208 ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
209 breakpoints[b].address == address)
212 if (b == CC_NUM_BREAKPOINTS) {
213 fprintf(output, "Error: no matching breakpoint found\n");
214 return command_proceed;
216 --breakpoints[b].enabled;
217 --breakpoints[b].temporary;
218 if (breakpoints[b].enabled == 0) {
219 breakpoints[b].address = -1;
220 ccdbg_set_hw_brkpnt(s51_dbg, b, 0, address);
221 fprintf(output, "set_hw_brkpnt status 0x%02x\n", status);
223 return command_proceed;
227 command_break (FILE *output, int argc, char **argv)
231 enum command_result result;
234 for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
235 if (breakpoints[b].enabled)
236 fprintf(output, "Breakpoint %d 0x%04x\n",
237 b, breakpoints[b].address);
238 return command_proceed;
241 return command_error;
242 result = parse_uint16(argv[1], &address);
243 if (result != command_proceed)
246 return set_breakpoint(output, address, 0);
250 command_clear (FILE *output, int argc, char **argv)
254 enum command_result result;
257 return command_error;
258 result = parse_uint16(argv[1], &address);
259 if (result != command_proceed)
261 return clear_breakpoint(output, address, 0);
265 command_run (FILE *output, int argc, char **argv)
268 enum command_result result;
271 result = parse_uint16(argv[1], &start);
272 if (result != command_proceed)
275 result = parse_uint16(argv[2], &end);
276 if (result != command_proceed)
279 ccdbg_set_pc(s51_dbg, start);
282 start = ccdbg_get_pc(s51_dbg);
283 fprintf(output, "Resume at 0x%04x\n", start);
284 ccdbg_resume(s51_dbg);
286 return command_proceed;
290 command_next (FILE *output, int argc, char **argv)
292 return command_step(output, argc, argv);
296 command_step (FILE *output, int argc, char **argv)
302 a = ccdbg_step_instr(s51_dbg);
303 fprintf(output, " ACC= 0x%02x\n", a);
304 pc = ccdbg_get_pc(s51_dbg);
305 ccdbg_read_memory(s51_dbg, pc, &opcode, 1);
306 fprintf(output, " ? 0x%04x %02x\n", pc, opcode);
307 return command_proceed;
311 command_load (FILE *output, int argc, char **argv)
313 return command_error;
317 command_halt (FILE *output, int argc, char **argv)
321 pc = ccdbg_get_pc(s51_dbg);
322 fprintf(output, "Halted at 0x%04x\n", pc);
323 return command_proceed;
327 command_reset (FILE *output, int argc, char **argv)
329 ccdbg_debug_mode(s51_dbg);
330 return command_proceed;
334 command_status(FILE *output, int argc, char **argv)
338 status = ccdbg_read_status(s51_dbg);
339 if ((status & CC_STATUS_CHIP_ERASE_DONE) == 0)
340 fprintf(output, "\tChip erase in progress\n");
341 if (status & CC_STATUS_PCON_IDLE)
342 fprintf(output, "\tCPU is idle (clock gated)\n");
343 if (status & CC_STATUS_CPU_HALTED)
344 fprintf(output, "\tCPU halted\n");
346 fprintf(output, "\tCPU running\n");
347 if ((status & CC_STATUS_POWER_MODE_0) == 0)
348 fprintf(output, "\tPower Mode 1-3 selected\n");
349 if (status & CC_STATUS_HALT_STATUS)
350 fprintf(output, "\tHalted by software or hw breakpoint\n");
352 fprintf(output, "\tHalted by debug command\n");
353 if (status & CC_STATUS_DEBUG_LOCKED)
354 fprintf(output, "\tDebug interface is locked\n");
355 if ((status & CC_STATUS_OSCILLATOR_STABLE) == 0)
356 fprintf(output, "\tOscillators are not stable\n");
357 if (status & CC_STATUS_STACK_OVERFLOW)
358 fprintf(output, "\tStack overflow\n");
359 return command_proceed;
362 uint8_t cc_wait(struct ccdbg *dbg)
366 status = ccdbg_read_status(dbg);
367 if (status & CC_STATUS_CPU_HALTED)