comparison debug.c @ 2505:927083238a39

Z80 debugger improvements
author Michael Pavone <pavone@retrodev.com>
date Wed, 14 Aug 2024 22:14:21 -0700
parents d44fe974fb85
children b0f314b19964
comparison
equal deleted inserted replaced
2504:593a4f308335 2505:927083238a39
3826 static uint8_t cmd_ym_channel(debug_root *root, parsed_command *cmd) 3826 static uint8_t cmd_ym_channel(debug_root *root, parsed_command *cmd)
3827 { 3827 {
3828 m68k_context *context = root->cpu_context; 3828 m68k_context *context = root->cpu_context;
3829 genesis_context * gen = context->system; 3829 genesis_context * gen = context->system;
3830 if (cmd->num_args) { 3830 if (cmd->num_args) {
3831 if (cmd->args[0].value.v.u32 < 1 || cmd->args[0].value.v.u32 > 6) {
3832 printf("%d is not a valid YM2612 channel number. Valid values are 1-6\n", cmd->args[0].value.v.u32);
3833 return 1;
3834 }
3831 ym_print_channel_info(gen->ym, cmd->args[0].value.v.u32 - 1); 3835 ym_print_channel_info(gen->ym, cmd->args[0].value.v.u32 - 1);
3832 } else { 3836 } else {
3833 for (int i = 0; i < 6; i++) { 3837 for (int i = 0; i < 6; i++) {
3834 ym_print_channel_info(gen->ym, i); 3838 ym_print_channel_info(gen->ym, i);
3835 } 3839 }
4490 after = context->regs[Z80_IXH] << 8 | context->regs[Z80_IXL]; 4494 after = context->regs[Z80_IXH] << 8 | context->regs[Z80_IXL];
4491 } else if (inst->ea_reg == Z80_IY) { 4495 } else if (inst->ea_reg == Z80_IY) {
4492 after = context->regs[Z80_IYH] << 8 | context->regs[Z80_IYL]; 4496 after = context->regs[Z80_IYH] << 8 | context->regs[Z80_IYL];
4493 #endif 4497 #endif
4494 } 4498 }
4499 #ifndef NEW_CORE
4500 } else if (inst->op == Z80_JPCC) {
4501 uint8_t invert = 0;
4502 uint8_t flag = 0;
4503 switch (inst->reg)
4504 {
4505 case Z80_CC_NZ:
4506 invert = 1;
4507 case Z80_CC_Z:
4508 flag = context->flags[ZF_Z];
4509 break;
4510 case Z80_CC_NC:
4511 invert = 1;
4512 case Z80_CC_C:
4513 flag = context->flags[ZF_C];
4514 break;
4515 case Z80_CC_PO:
4516 invert = 1;
4517 case Z80_CC_PE:
4518 flag = context->flags[ZF_PV];
4519 break;
4520 case Z80_CC_P:
4521 invert = 1;
4522 case Z80_CC_M:
4523 flag = context->flags[ZF_S];
4524 break;
4525 }
4526 if (invert) {
4527 flag = !flag;
4528 }
4529 if (flag) {
4530 after = inst->immed;
4531 }
4532 } else if (inst->op == Z80_JRCC) {
4533 uint8_t invert = 0;
4534 uint8_t flag = 0;
4535 switch (inst->reg)
4536 {
4537 case Z80_CC_NZ:
4538 invert = 1;
4539 case Z80_CC_Z:
4540 flag = context->flags[ZF_Z];
4541 break;
4542 case Z80_CC_NC:
4543 invert = 1;
4544 case Z80_CC_C:
4545 flag = context->flags[ZF_C];
4546 break;
4547 }
4548 if (invert) {
4549 flag = !flag;
4550 }
4551 if (flag) {
4552 after += inst->immed;
4553 }
4554 #endif
4495 } else if(inst->op == Z80_JR) { 4555 } else if(inst->op == Z80_JR) {
4496 after += inst->immed; 4556 after += inst->immed;
4497 } else if(inst->op == Z80_RET) { 4557 } else if(inst->op == Z80_RET) {
4498 uint8_t *sp = get_native_pointer(context->sp, (void **)context->mem_pointers, &context->Z80_OPTS->gen); 4558 uint8_t *sp = get_native_pointer(context->sp, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
4499 if (sp) { 4559 if (sp) {
4504 } 4564 }
4505 } 4565 }
4506 } 4566 }
4507 zinsert_breakpoint(context, after, (uint8_t *)zdebugger); 4567 zinsert_breakpoint(context, after, (uint8_t *)zdebugger);
4508 return 0; 4568 return 0;
4509 }
4510
4511 static uint8_t cmd_over_z80(debug_root *root, parsed_command *cmd)
4512 {
4513 fputs("not implemented yet\n", stderr);
4514 return 1;
4515 } 4569 }
4516 4570
4517 static uint8_t cmd_next_z80(debug_root *root, parsed_command *cmd) 4571 static uint8_t cmd_next_z80(debug_root *root, parsed_command *cmd)
4518 { 4572 {
4519 z80inst *inst = root->inst; 4573 z80inst *inst = root->inst;
4546 } 4600 }
4547 zinsert_breakpoint(context, after, (uint8_t *)zdebugger); 4601 zinsert_breakpoint(context, after, (uint8_t *)zdebugger);
4548 return 0; 4602 return 0;
4549 } 4603 }
4550 4604
4605 static uint8_t cmd_over_z80(debug_root *root, parsed_command *cmd)
4606 {
4607 z80inst *inst = root->inst;
4608 z80_context *context = root->cpu_context;
4609 uint32_t after = root->after;
4610 #ifndef NEW_CORE
4611 if (inst->op == Z80_JPCC) {
4612 if (inst->immed < after) {
4613 zinsert_breakpoint(context, inst->immed, (uint8_t *)zdebugger);
4614 return 0;
4615 }
4616 } else if (inst->op == Z80_JRCC) {
4617 after += inst->immed;
4618 if (after < root->after) {
4619 zinsert_breakpoint(context, after, (uint8_t *)zdebugger);
4620 return 0;
4621 }
4622 }
4623 #endif
4624 return cmd_next_z80(root, cmd);
4625 }
4626
4551 static uint8_t cmd_backtrace_z80(debug_root *root, parsed_command *cmd) 4627 static uint8_t cmd_backtrace_z80(debug_root *root, parsed_command *cmd)
4552 { 4628 {
4553 z80_context *context = root->cpu_context; 4629 z80_context *context = root->cpu_context;
4554 uint32_t stack = context->sp; 4630 uint32_t stack = context->sp;
4555 uint8_t non_adr_count = 0; 4631 uint8_t non_adr_count = 0;
4634 gen->header.enter_debugger = 1; 4710 gen->header.enter_debugger = 1;
4635 return 0; 4711 return 0;
4636 } 4712 }
4637 } 4713 }
4638 4714
4715 static uint8_t cmd_ym_channel_z80(debug_root *root, parsed_command *cmd)
4716 {
4717 z80_context *context = root->cpu_context;
4718 genesis_context * gen = context->system;
4719 if (cmd->num_args) {
4720 if (cmd->args[0].value.v.u32 < 1 || cmd->args[0].value.v.u32 > 6) {
4721 printf("%d is not a valid YM2612 channel number. Valid values are 1-6\n", cmd->args[0].value.v.u32);
4722 return 1;
4723 }
4724 ym_print_channel_info(gen->ym, cmd->args[0].value.v.u32 - 1);
4725 } else {
4726 for (int i = 0; i < 6; i++) {
4727 ym_print_channel_info(gen->ym, i);
4728 }
4729 }
4730 return 1;
4731 }
4732
4639 static uint8_t cmd_vdp_sprites_sms(debug_root *root, parsed_command *cmd) 4733 static uint8_t cmd_vdp_sprites_sms(debug_root *root, parsed_command *cmd)
4640 { 4734 {
4641 z80_context *context = root->cpu_context; 4735 z80_context *context = root->cpu_context;
4642 sms_context * sms = context->system; 4736 sms_context * sms = context->system;
4643 vdp_print_sprite_table(sms->vdp); 4737 vdp_print_sprite_table(sms->vdp);
4758 .desc = "Run a M68K debugger command or switch to M68K context when no command is given", 4852 .desc = "Run a M68K debugger command or switch to M68K context when no command is given",
4759 .impl = cmd_gen_m68k, 4853 .impl = cmd_gen_m68k,
4760 .min_args = 0, 4854 .min_args = 0,
4761 .max_args = -1, 4855 .max_args = -1,
4762 .raw_args = 1 4856 .raw_args = 1
4857 },
4858 {
4859 .names = (const char *[]){
4860 "ymchannel", NULL
4861 },
4862 .usage = "ymchannel [CHANNEL]",
4863 .desc = "Print YM-2612 channel and operator params. Limited to CHANNEL if specified",
4864 .impl = cmd_ym_channel_z80,
4865 .min_args = 0,
4866 .max_args = 1
4763 } 4867 }
4764 }; 4868 };
4765 4869
4766 #define NUM_GEN_Z80 (sizeof(gen_z80_commands)/sizeof(*gen_z80_commands)) 4870 #define NUM_GEN_Z80 (sizeof(gen_z80_commands)/sizeof(*gen_z80_commands))
4767 4871
5262 #endif 5366 #endif
5263 genesis_context *gen; 5367 genesis_context *gen;
5264 sms_context *sms; 5368 sms_context *sms;
5265 coleco_context *coleco; 5369 coleco_context *coleco;
5266 debug_var *var; 5370 debug_var *var;
5267 //TODO: populate names
5268 switch (current_system->type) 5371 switch (current_system->type)
5269 { 5372 {
5270 case SYSTEM_GENESIS: 5373 case SYSTEM_GENESIS:
5271 case SYSTEM_SEGACD: 5374 case SYSTEM_SEGACD:
5272 gen = context->system; 5375 gen = context->system;
5273 add_commands(root, gen_z80_commands, NUM_GEN_Z80); 5376 add_commands(root, gen_z80_commands, NUM_GEN_Z80);
5274 root->other_roots = tern_insert_ptr(root->other_roots, "m68k", find_m68k_root(gen->m68k)); 5377 root->other_roots = tern_insert_ptr(root->other_roots, "m68k", find_m68k_root(gen->m68k));
5275 //root->resolve = resolve_z80; 5378 root->other_roots = tern_insert_ptr(root->other_roots, "io", find_io_root(&gen->io));
5379 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(gen->vdp));
5380 root->other_roots = tern_insert_ptr(root->other_roots, "psg", find_psg_root(gen->psg));
5381 root->other_roots = tern_insert_ptr(root->other_roots, "ym", find_ym2612_root(gen->ym));
5382 var = calloc(1, sizeof(debug_var));
5383 var->get = debug_frame_get;
5384 var->ptr = gen->vdp;
5385 root->variables = tern_insert_ptr(root->variables, "frame", var);
5276 break; 5386 break;
5277 case SYSTEM_SMS: 5387 case SYSTEM_SMS:
5278 sms = context->system; 5388 sms = context->system;
5279 add_commands(root, sms_commands, NUM_SMS); 5389 add_commands(root, sms_commands, NUM_SMS);
5280 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(sms->vdp)); 5390 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(sms->vdp));
5287 case SYSTEM_COLECOVISION: 5397 case SYSTEM_COLECOVISION:
5288 coleco = context->system; 5398 coleco = context->system;
5289 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(coleco->vdp)); 5399 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(coleco->vdp));
5290 root->other_roots = tern_insert_ptr(root->other_roots, "psg", find_psg_root(coleco->psg)); 5400 root->other_roots = tern_insert_ptr(root->other_roots, "psg", find_psg_root(coleco->psg));
5291 break; 5401 break;
5292 //default:
5293 //root->resolve = resolve_z80;
5294 } 5402 }
5295 root->read_mem = read_z80; 5403 root->read_mem = read_z80;
5296 root->write_mem = write_z80; 5404 root->write_mem = write_z80;
5297 root->disasm = create_z80_disasm(); 5405 root->disasm = create_z80_disasm();
5298 root->chunk_end = z80_chunk_end; 5406 root->chunk_end = z80_chunk_end;