# HG changeset patch # User Michael Pavone # Date 1644650470 28800 # Node ID ff32a90260c96bcfc34de688dd29e67212de58db # Parent 522d04e2adcd940db9be1e86ef678e61196092a6 Initial support for using debugger on sub CPU diff -r 522d04e2adcd -r ff32a90260c9 debug.c --- a/debug.c Fri Feb 11 22:55:01 2022 -0800 +++ b/debug.c Fri Feb 11 23:21:10 2022 -0800 @@ -1,6 +1,8 @@ #include "debug.h" #include "genesis.h" #include "68kinst.h" +#include "segacd.h" +#include "blastem.h" #include #include #ifndef _WIN32 @@ -582,6 +584,97 @@ #endif +int run_debugger_command(m68k_context *context, uint32_t address, char *input_buf, m68kinst inst, uint32_t after); +int run_genesis_debugger_command(m68k_context *context, uint32_t address, char *input_buf) +{ + genesis_context * gen = context->system; + char *param; + uint32_t value; + bp_def *new_bp; + switch (input_buf[0]) + { + case 'v': + //VDP debug commands + switch(input_buf[1]) + { + case 's': + vdp_print_sprite_table(gen->vdp); + break; + case 'r': + vdp_print_reg_explain(gen->vdp); + break; + } + break; + case 'y': + //YM-2612 debug commands + switch(input_buf[1]) + { + case 'c': + if (input_buf[2] == ' ') { + int channel = atoi(input_buf+3)-1; + ym_print_channel_info(gen->ym, channel); + } else { + for (int i = 0; i < 6; i++) { + ym_print_channel_info(gen->ym, i); + } + } + break; + case 't': + ym_print_timer_info(gen->ym); + break; + } + break; + case 'u': + if (gen->expansion) { + segacd_context *cd = gen->expansion; + if (input_buf[1]) { + //TODO: filter out commands that are unsafe to run when we don't have the current Sub CPU address + run_debugger_command(cd->m68k, 0, input_buf + 1, (m68kinst){}, 0); + } else { + cd->enter_debugger = 1; + return 0; + } + } else { + fputs("u command only valid when Sega/Mega CD is active\n", stderr); + } + break; +#ifndef NO_Z80 + case 'z': + //Z80 debug commands + switch(input_buf[1]) + { + case 'b': + param = find_param(input_buf); + if (!param) { + fputs("zb command requires a parameter\n", stderr); + break; + } + value = strtol(param, NULL, 16); + zinsert_breakpoint(gen->z80, value, (uint8_t *)zdebugger); + new_bp = malloc(sizeof(bp_def)); + new_bp->next = zbreakpoints; + new_bp->address = value; + new_bp->index = zbp_index++; + zbreakpoints = new_bp; + printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value); + break; + case 'p': + param = find_param(input_buf); + if (!param) { + fputs("zp command requires a parameter\n", stderr); + break; + } + zdebugger_print(gen->z80, input_buf[2] == '/' ? input_buf[3] : 0, param); + } + break; +#endif + default: + fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf); + break; + } + return 1; +} + static uint32_t branch_t; static uint32_t branch_f; @@ -880,73 +973,6 @@ insert_breakpoint(context, after, debugger); return 0; } - case 'v': { - genesis_context * gen = context->system; - //VDP debug commands - switch(input_buf[1]) - { - case 's': - vdp_print_sprite_table(gen->vdp); - break; - case 'r': - vdp_print_reg_explain(gen->vdp); - break; - } - break; - } - case 'y': { - genesis_context * gen = context->system; - //YM-2612 debug commands - switch(input_buf[1]) - { - case 'c': - if (input_buf[2] == ' ') { - int channel = atoi(input_buf+3)-1; - ym_print_channel_info(gen->ym, channel); - } else { - for (int i = 0; i < 6; i++) { - ym_print_channel_info(gen->ym, i); - } - } - break; - case 't': - ym_print_timer_info(gen->ym); - break; - } - break; - } -#ifndef NO_Z80 - case 'z': { - genesis_context * gen = context->system; - //Z80 debug commands - switch(input_buf[1]) - { - case 'b': - param = find_param(input_buf); - if (!param) { - fputs("zb command requires a parameter\n", stderr); - break; - } - value = strtol(param, NULL, 16); - zinsert_breakpoint(gen->z80, value, (uint8_t *)zdebugger); - new_bp = malloc(sizeof(bp_def)); - new_bp->next = zbreakpoints; - new_bp->address = value; - new_bp->index = zbp_index++; - zbreakpoints = new_bp; - printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value); - break; - case 'p': - param = find_param(input_buf); - if (!param) { - fputs("zp command requires a parameter\n", stderr); - break; - } - zdebugger_print(gen->z80, input_buf[2] == '/' ? input_buf[3] : 0, param); - } - break; - } -#endif case '?': print_m68k_help(); break; @@ -954,9 +980,17 @@ puts("Quitting"); exit(0); break; - default: - fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf); + default: { + if (context->system == current_system) { + //primary 68K for current system + return run_genesis_debugger_command(context, address, input_buf); + } else { + //presumably Sega CD sub CPU + //TODO: consider making this more generic + fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf); + } break; + } } return 1; } @@ -1013,8 +1047,10 @@ init_terminal(); context->options->sync_components(context, 0); - genesis_context *gen = context->system; - vdp_force_update_framebuffer(gen->vdp); + if (context->system == current_system) { + genesis_context *gen = context->system; + vdp_force_update_framebuffer(gen->vdp); + } //probably not necessary, but let's play it safe address &= 0xFFFFFF; if (address == branch_t) { diff -r 522d04e2adcd -r ff32a90260c9 segacd.c --- a/segacd.c Fri Feb 11 22:55:01 2022 -0800 +++ b/segacd.c Fri Feb 11 23:21:10 2022 -0800 @@ -3,6 +3,8 @@ #include "cd_graphics.h" #include "genesis.h" #include "util.h" +#include "debug.h" +#include "gdb_remote.h" #define SCD_MCLKS 50000000 #define SCD_PERIPH_RESET_CLKS (SCD_MCLKS / 10) @@ -875,8 +877,13 @@ { segacd_context *cd = context->system; scd_peripherals_run(cd, context->current_cycle); - if (context->int_ack) { - printf("int ack %d\n", context->int_ack); + if (address && cd->enter_debugger) { + genesis_context *gen = cd->genesis; + if (gen->header.debugger_type == DEBUGGER_NATIVE) { + debugger(context, address); + } else { + gdb_debug_enter(context, address); + } } switch (context->int_ack) { @@ -907,7 +914,7 @@ while (cycle > cd->m68k->current_cycle) { if (m68k_run) { uint32_t start = cd->m68k->current_cycle; - cd->m68k->sync_cycle = cycle; + cd->m68k->sync_cycle = cd->enter_debugger ? cd->m68k->current_cycle + 1 : cycle; if (cd->need_reset) { cd->need_reset = 0; m68k_reset(cd->m68k); diff -r 522d04e2adcd -r ff32a90260c9 segacd.h --- a/segacd.h Fri Feb 11 22:55:01 2022 -0800 +++ b/segacd.h Fri Feb 11 23:21:10 2022 -0800 @@ -43,6 +43,7 @@ uint8_t cdc_int_ack; uint8_t graphics_step; uint8_t graphics_dst_y; + uint8_t enter_debugger; } segacd_context; segacd_context *alloc_configure_segacd(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info);