+ int b;
+ uint8_t status;
+
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++) {
+ if (breakpoints[b].enabled != 0 &&
+ ((breakpoints[b].temporary != 0) == (temporary != 0)) &&
+ breakpoints[b].address == address)
+ break;
+ }
+ if (b == CC_NUM_BREAKPOINTS) {
+ s51_printf("Error: no matching breakpoint found\n");
+ return command_success;
+ }
+ --breakpoints[b].enabled;
+ breakpoints[b].temporary -= temporary;
+ if (breakpoints[b].enabled == 0) {
+ disable_breakpoint(b);
+ breakpoints[b].address = -1;
+ }
+ return command_success;
+}
+
+
+int
+find_breakpoint(uint16_t address)
+{
+ int b;
+
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled && breakpoints[b].address == address)
+ break;
+ if (b == CC_NUM_BREAKPOINTS)
+ return -1;
+ return b;
+}
+
+enum command_result
+command_break (int argc, char **argv)
+{
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc == 1) {
+ for (b = 0; b < CC_NUM_BREAKPOINTS; b++)
+ if (breakpoints[b].enabled)
+ s51_printf("Breakpoint %d 0x%04x\n",
+ b, breakpoints[b].address);
+ return command_success;
+ }
+ if (argc != 2)
+ return command_error;
+ result = parse_uint16(argv[1], &address);
+ if (result != command_success)
+ return result;
+
+ return set_breakpoint(address, 0);
+}
+
+enum command_result
+command_clear (int argc, char **argv)
+{
+ int b;
+ uint16_t address;
+ enum command_result result;
+
+ if (argc != 2)
+ return command_error;
+ result = parse_uint16(argv[1], &address);
+ if (result != command_success)
+ return result;
+ return clear_breakpoint(address, 0);
+}
+
+void
+cc_stopped(uint8_t status)
+{
+ uint16_t pc;
+ int b;
+ int code;
+ char *reason;
+
+ pc = ccdbg_get_pc(s51_dbg);
+ if (status & CC_STATUS_CPU_HALTED) {
+ if ((status & CC_STATUS_HALT_STATUS) != 0) {
+ pc = pc - 1;
+ code = 104;
+ reason = "Breakpoint";
+ b = find_breakpoint(pc);
+ if (b != -1 && breakpoints[b].temporary)
+ clear_breakpoint(pc, 1);
+ ccdbg_set_pc(s51_dbg, pc);
+ } else {
+ code = 105;
+ reason = "Interrupt";
+ }
+ s51_printf("Stop at 0x%04x: (%d) %s\n",
+ pc, code, reason);
+ }
+}
+
+uint8_t
+cc_step(uint16_t pc)
+{
+ int b;
+ uint8_t status;
+
+ b = find_breakpoint(pc);
+ if (b != -1)
+ disable_breakpoint(b);
+ status = ccdbg_step_instr(s51_dbg);
+ if (b != -1)
+ enable_breakpoint(b);
+ return status;