Mercurial > repos > blastem
comparison debug.c @ 2107:f80c6111e1ae
Move some debugger state to a per-CPU structure. Add m command for returning to main CPU from sub CPU
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 12 Feb 2022 15:20:43 -0800 |
parents | ff32a90260c9 |
children | 3abb64bd0da6 |
comparison
equal
deleted
inserted
replaced
2106:d2989e32c026 | 2107:f80c6111e1ae |
---|---|
17 #define Z80_OPTS opts | 17 #define Z80_OPTS opts |
18 #else | 18 #else |
19 #define Z80_OPTS options | 19 #define Z80_OPTS options |
20 #endif | 20 #endif |
21 | 21 |
22 static bp_def * breakpoints = NULL; | 22 |
23 static bp_def * zbreakpoints = NULL; | 23 |
24 static uint32_t bp_index = 0; | 24 static debug_root roots[5]; |
25 static uint32_t zbp_index = 0; | 25 static uint32_t num_roots; |
26 #define MAX_DEBUG_ROOTS (sizeof(roots)/sizeof(*roots)) | |
27 | |
28 debug_root *find_root(void *cpu) | |
29 { | |
30 for (uint32_t i = 0; i < num_roots; i++) | |
31 { | |
32 if (roots[i].cpu_context == cpu) { | |
33 return roots + i; | |
34 } | |
35 } | |
36 if (num_roots < MAX_DEBUG_ROOTS) { | |
37 num_roots++; | |
38 memset(roots + num_roots - 1, 0, sizeof(debug_root)); | |
39 roots[num_roots-1].cpu_context = cpu; | |
40 return roots + num_roots - 1; | |
41 } | |
42 return NULL; | |
43 } | |
26 | 44 |
27 bp_def ** find_breakpoint(bp_def ** cur, uint32_t address) | 45 bp_def ** find_breakpoint(bp_def ** cur, uint32_t address) |
28 { | 46 { |
29 while (*cur) { | 47 while (*cur) { |
30 if ((*cur)->address == address) { | 48 if ((*cur)->address == address) { |
43 } | 61 } |
44 cur = &((*cur)->next); | 62 cur = &((*cur)->next); |
45 } | 63 } |
46 return cur; | 64 return cur; |
47 } | 65 } |
48 | |
49 disp_def * displays = NULL; | |
50 disp_def * zdisplays = NULL; | |
51 uint32_t disp_index = 0; | |
52 uint32_t zdisp_index = 0; | |
53 | 66 |
54 void add_display(disp_def ** head, uint32_t *index, char format_char, char * param) | 67 void add_display(disp_def ** head, uint32_t *index, char format_char, char * param) |
55 { | 68 { |
56 disp_def * ndisp = malloc(sizeof(*ndisp)); | 69 disp_def * ndisp = malloc(sizeof(*ndisp)); |
57 ndisp->format_char = format_char; | 70 ndisp->format_char = format_char; |
371 | 384 |
372 z80_context * zdebugger(z80_context * context, uint16_t address) | 385 z80_context * zdebugger(z80_context * context, uint16_t address) |
373 { | 386 { |
374 static char last_cmd[1024]; | 387 static char last_cmd[1024]; |
375 char input_buf[1024]; | 388 char input_buf[1024]; |
376 static uint16_t branch_t; | |
377 static uint16_t branch_f; | |
378 z80inst inst; | 389 z80inst inst; |
379 genesis_context *system = context->system; | 390 genesis_context *system = context->system; |
380 init_terminal(); | 391 init_terminal(); |
381 //Check if this is a user set breakpoint, or just a temporary one | 392 //Check if this is a user set breakpoint, or just a temporary one |
382 bp_def ** this_bp = find_breakpoint(&zbreakpoints, address); | 393 debug_root *root = find_root(context); |
394 if (!root) { | |
395 return context; | |
396 } | |
397 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address); | |
383 if (*this_bp) { | 398 if (*this_bp) { |
384 printf("Z80 Breakpoint %d hit\n", (*this_bp)->index); | 399 printf("Z80 Breakpoint %d hit\n", (*this_bp)->index); |
385 } else { | 400 } else { |
386 zremove_breakpoint(context, address); | 401 zremove_breakpoint(context, address); |
387 } | 402 } |
388 uint8_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen); | 403 uint8_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen); |
389 if (!pc) { | 404 if (!pc) { |
390 fatal_error("Failed to get native pointer on entering Z80 debugger at address %X\n", address); | 405 fatal_error("Failed to get native pointer on entering Z80 debugger at address %X\n", address); |
391 } | 406 } |
392 for (disp_def * cur = zdisplays; cur; cur = cur->next) { | 407 for (disp_def * cur = root->displays; cur; cur = cur->next) { |
393 zdebugger_print(context, cur->format_char, cur->param); | 408 zdebugger_print(context, cur->format_char, cur->param); |
394 } | 409 } |
395 uint8_t * after_pc = z80_decode(pc, &inst); | 410 uint8_t * after_pc = z80_decode(pc, &inst); |
396 z80_disasm(&inst, input_buf, address); | 411 z80_disasm(&inst, input_buf, address); |
397 printf("%X:\t%s\n", address, input_buf); | 412 printf("%X:\t%s\n", address, input_buf); |
433 break; | 448 break; |
434 } | 449 } |
435 value = strtol(param, NULL, 16); | 450 value = strtol(param, NULL, 16); |
436 zinsert_breakpoint(context, value, (uint8_t *)zdebugger); | 451 zinsert_breakpoint(context, value, (uint8_t *)zdebugger); |
437 new_bp = malloc(sizeof(bp_def)); | 452 new_bp = malloc(sizeof(bp_def)); |
438 new_bp->next = zbreakpoints; | 453 new_bp->next = root->breakpoints; |
439 new_bp->address = value; | 454 new_bp->address = value; |
440 new_bp->index = zbp_index++; | 455 new_bp->index = root->bp_index++; |
441 new_bp->commands = NULL; | 456 new_bp->commands = NULL; |
442 zbreakpoints = new_bp; | 457 root->breakpoints = new_bp; |
443 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value); | 458 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value); |
444 break; | 459 break; |
445 case 'c': | 460 case 'c': |
446 puts("Continuing"); | 461 puts("Continuing"); |
447 debugging = 0; | 462 debugging = 0; |
459 if (!param) { | 474 if (!param) { |
460 fputs("display command requires a parameter\n", stderr); | 475 fputs("display command requires a parameter\n", stderr); |
461 break; | 476 break; |
462 } | 477 } |
463 zdebugger_print(context, format_char, param); | 478 zdebugger_print(context, format_char, param); |
464 add_display(&zdisplays, &zdisp_index, format_char, param); | 479 add_display(&root->displays, &root->disp_index, format_char, param); |
465 } else if (input_buf[1] == 'e' || input_buf[1] == ' ') { | 480 } else if (input_buf[1] == 'e' || input_buf[1] == ' ') { |
466 param = find_param(input_buf); | 481 param = find_param(input_buf); |
467 if (!param) { | 482 if (!param) { |
468 fputs("delete command requires a parameter\n", stderr); | 483 fputs("delete command requires a parameter\n", stderr); |
469 break; | 484 break; |
470 } | 485 } |
471 if (param[0] >= '0' && param[0] <= '9') { | 486 if (param[0] >= '0' && param[0] <= '9') { |
472 value = atoi(param); | 487 value = atoi(param); |
473 this_bp = find_breakpoint_idx(&zbreakpoints, value); | 488 this_bp = find_breakpoint_idx(&root->breakpoints, value); |
474 if (!*this_bp) { | 489 if (!*this_bp) { |
475 fprintf(stderr, "Breakpoint %d does not exist\n", value); | 490 fprintf(stderr, "Breakpoint %d does not exist\n", value); |
476 break; | 491 break; |
477 } | 492 } |
478 new_bp = *this_bp; | 493 new_bp = *this_bp; |
483 param = find_param(param); | 498 param = find_param(param); |
484 if (!param) { | 499 if (!param) { |
485 fputs("delete display command requires a parameter\n", stderr); | 500 fputs("delete display command requires a parameter\n", stderr); |
486 break; | 501 break; |
487 } | 502 } |
488 remove_display(&zdisplays, atoi(param)); | 503 remove_display(&root->displays, atoi(param)); |
489 } | 504 } |
490 } | 505 } |
491 break; | 506 break; |
492 case 'n': | 507 case 'n': |
493 //TODO: Handle conditional branch instructions | 508 //TODO: Handle conditional branch instructions |
641 #ifndef NO_Z80 | 656 #ifndef NO_Z80 |
642 case 'z': | 657 case 'z': |
643 //Z80 debug commands | 658 //Z80 debug commands |
644 switch(input_buf[1]) | 659 switch(input_buf[1]) |
645 { | 660 { |
646 case 'b': | 661 case 'b': { |
647 param = find_param(input_buf); | 662 param = find_param(input_buf); |
648 if (!param) { | 663 if (!param) { |
649 fputs("zb command requires a parameter\n", stderr); | 664 fputs("zb command requires a parameter\n", stderr); |
650 break; | 665 break; |
651 } | 666 } |
652 value = strtol(param, NULL, 16); | 667 value = strtol(param, NULL, 16); |
668 debug_root *zroot = find_root(gen->z80); | |
653 zinsert_breakpoint(gen->z80, value, (uint8_t *)zdebugger); | 669 zinsert_breakpoint(gen->z80, value, (uint8_t *)zdebugger); |
654 new_bp = malloc(sizeof(bp_def)); | 670 new_bp = malloc(sizeof(bp_def)); |
655 new_bp->next = zbreakpoints; | 671 new_bp->next = zroot->breakpoints; |
656 new_bp->address = value; | 672 new_bp->address = value; |
657 new_bp->index = zbp_index++; | 673 new_bp->index = zroot->bp_index++; |
658 zbreakpoints = new_bp; | 674 zroot->breakpoints = new_bp; |
659 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value); | 675 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, value); |
660 break; | 676 break; |
677 } | |
661 case 'p': | 678 case 'p': |
662 param = find_param(input_buf); | 679 param = find_param(input_buf); |
663 if (!param) { | 680 if (!param) { |
664 fputs("zp command requires a parameter\n", stderr); | 681 fputs("zp command requires a parameter\n", stderr); |
665 break; | 682 break; |
673 break; | 690 break; |
674 } | 691 } |
675 return 1; | 692 return 1; |
676 } | 693 } |
677 | 694 |
678 static uint32_t branch_t; | 695 int run_subcpu_debugger_command(m68k_context *context, uint32_t address, char *input_buf) |
679 static uint32_t branch_f; | 696 { |
697 segacd_context *cd = context->system; | |
698 switch (input_buf[0]) | |
699 { | |
700 case 'm': | |
701 if (input_buf[1]) { | |
702 //TODO: filter out commands that are unsafe to run when we don't have the current Main CPU address | |
703 return run_debugger_command(cd->genesis->m68k, 0, input_buf + 1, (m68kinst){}, 0); | |
704 } else { | |
705 cd->genesis->header.enter_debugger = 1; | |
706 return 0; | |
707 } | |
708 break; | |
709 default: | |
710 fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf); | |
711 break; | |
712 } | |
713 return 1; | |
714 } | |
680 | 715 |
681 int run_debugger_command(m68k_context *context, uint32_t address, char *input_buf, m68kinst inst, uint32_t after) | 716 int run_debugger_command(m68k_context *context, uint32_t address, char *input_buf, m68kinst inst, uint32_t after) |
682 { | 717 { |
683 char * param; | 718 char * param; |
684 char format_char; | 719 char format_char; |
685 genesis_context *system = context->system; | 720 genesis_context *system = context->system; |
686 uint32_t value; | 721 uint32_t value; |
687 bp_def *new_bp, **this_bp; | 722 bp_def *new_bp, **this_bp; |
723 debug_root *root = find_root(context); | |
724 if (!root) { | |
725 return 0; | |
726 } | |
688 switch(input_buf[0]) | 727 switch(input_buf[0]) |
689 { | 728 { |
690 case 'c': | 729 case 'c': |
691 if (input_buf[1] == 0 || input_buf[1] == 'o' && input_buf[2] == 'n') | 730 if (input_buf[1] == 0 || input_buf[1] == 'o' && input_buf[2] == 'n') |
692 { | 731 { |
696 param = find_param(input_buf); | 735 param = find_param(input_buf); |
697 if (!param) { | 736 if (!param) { |
698 fputs("com command requires a parameter\n", stderr); | 737 fputs("com command requires a parameter\n", stderr); |
699 break; | 738 break; |
700 } | 739 } |
701 bp_def **target = find_breakpoint_idx(&breakpoints, atoi(param)); | 740 bp_def **target = find_breakpoint_idx(&root->breakpoints, atoi(param)); |
702 if (!target) { | 741 if (!target) { |
703 fprintf(stderr, "Breakpoint %s does not exist!\n", param); | 742 fprintf(stderr, "Breakpoint %s does not exist!\n", param); |
704 break; | 743 break; |
705 } | 744 } |
706 printf("Enter commands for breakpoing %d, type end when done\n", atoi(param)); | 745 printf("Enter commands for breakpoing %d, type end when done\n", atoi(param)); |
763 break; | 802 break; |
764 } | 803 } |
765 value = strtol(param, NULL, 16); | 804 value = strtol(param, NULL, 16); |
766 insert_breakpoint(context, value, debugger); | 805 insert_breakpoint(context, value, debugger); |
767 new_bp = malloc(sizeof(bp_def)); | 806 new_bp = malloc(sizeof(bp_def)); |
768 new_bp->next = breakpoints; | 807 new_bp->next = root->breakpoints; |
769 new_bp->address = value; | 808 new_bp->address = value; |
770 new_bp->index = bp_index++; | 809 new_bp->index = root->bp_index++; |
771 new_bp->commands = NULL; | 810 new_bp->commands = NULL; |
772 breakpoints = new_bp; | 811 root->breakpoints = new_bp; |
773 printf("68K Breakpoint %d set at %X\n", new_bp->index, value); | 812 printf("68K Breakpoint %d set at %X\n", new_bp->index, value); |
774 } | 813 } |
775 break; | 814 break; |
776 case 'a': | 815 case 'a': |
777 param = find_param(input_buf); | 816 param = find_param(input_buf); |
795 if (!param) { | 834 if (!param) { |
796 fputs("display command requires a parameter\n", stderr); | 835 fputs("display command requires a parameter\n", stderr); |
797 break; | 836 break; |
798 } | 837 } |
799 debugger_print(context, format_char, param, address); | 838 debugger_print(context, format_char, param, address); |
800 add_display(&displays, &disp_index, format_char, param); | 839 add_display(&root->displays, &root->disp_index, format_char, param); |
801 } else { | 840 } else { |
802 param = find_param(input_buf); | 841 param = find_param(input_buf); |
803 if (!param) { | 842 if (!param) { |
804 fputs("d command requires a parameter\n", stderr); | 843 fputs("d command requires a parameter\n", stderr); |
805 break; | 844 break; |
806 } | 845 } |
807 value = atoi(param); | 846 value = atoi(param); |
808 this_bp = find_breakpoint_idx(&breakpoints, value); | 847 this_bp = find_breakpoint_idx(&root->breakpoints, value); |
809 if (!*this_bp) { | 848 if (!*this_bp) { |
810 fprintf(stderr, "Breakpoint %d does not exist\n", value); | 849 fprintf(stderr, "Breakpoint %d does not exist\n", value); |
811 break; | 850 break; |
812 } | 851 } |
813 new_bp = *this_bp; | 852 new_bp = *this_bp; |
840 after = m68k_read_long(context->aregs[7], context); | 879 after = m68k_read_long(context->aregs[7], context); |
841 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { | 880 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { |
842 after = m68k_read_long(context->aregs[7] + 2, context); | 881 after = m68k_read_long(context->aregs[7] + 2, context); |
843 } else if(m68k_is_noncall_branch(&inst)) { | 882 } else if(m68k_is_noncall_branch(&inst)) { |
844 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { | 883 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { |
845 branch_f = after; | 884 root->branch_f = after; |
846 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs); | 885 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs); |
847 insert_breakpoint(context, branch_t, debugger); | 886 insert_breakpoint(context, root->branch_t, debugger); |
848 } else if(inst.op == M68K_DBCC) { | 887 } else if(inst.op == M68K_DBCC) { |
849 if ( inst.extra.cond == COND_FALSE) { | 888 if ( inst.extra.cond == COND_FALSE) { |
850 if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) { | 889 if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) { |
851 after = m68k_branch_target(&inst, context->dregs, context->aregs); | 890 after = m68k_branch_target(&inst, context->dregs, context->aregs); |
852 } | 891 } |
853 } else { | 892 } else { |
854 branch_t = after; | 893 root->branch_t = after; |
855 branch_f = m68k_branch_target(&inst, context->dregs, context->aregs); | 894 root->branch_f = m68k_branch_target(&inst, context->dregs, context->aregs); |
856 insert_breakpoint(context, branch_f, debugger); | 895 insert_breakpoint(context, root->branch_f, debugger); |
857 } | 896 } |
858 } else { | 897 } else { |
859 after = m68k_branch_target(&inst, context->dregs, context->aregs); | 898 after = m68k_branch_target(&inst, context->dregs, context->aregs); |
860 } | 899 } |
861 } | 900 } |
866 after = m68k_read_long(context->aregs[7], context); | 905 after = m68k_read_long(context->aregs[7], context); |
867 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { | 906 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { |
868 after = m68k_read_long(context->aregs[7] + 2, context); | 907 after = m68k_read_long(context->aregs[7] + 2, context); |
869 } else if(m68k_is_noncall_branch(&inst)) { | 908 } else if(m68k_is_noncall_branch(&inst)) { |
870 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { | 909 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { |
871 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 910 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
872 if (branch_t < after) { | 911 if (root->branch_t < after) { |
873 branch_t = 0; | 912 root->branch_t = 0; |
874 } else { | 913 } else { |
875 branch_f = after; | 914 root->branch_f = after; |
876 insert_breakpoint(context, branch_t, debugger); | 915 insert_breakpoint(context, root->branch_t, debugger); |
877 } | 916 } |
878 } else if(inst.op == M68K_DBCC) { | 917 } else if(inst.op == M68K_DBCC) { |
879 uint32_t target = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 918 uint32_t target = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
880 if (target > after) { | 919 if (target > after) { |
881 if (inst.extra.cond == COND_FALSE) { | 920 if (inst.extra.cond == COND_FALSE) { |
882 after = target; | 921 after = target; |
883 } else { | 922 } else { |
884 branch_f = target; | 923 root->branch_f = target; |
885 branch_t = after; | 924 root->branch_t = after; |
886 insert_breakpoint(context, branch_f, debugger); | 925 insert_breakpoint(context, root->branch_f, debugger); |
887 } | 926 } |
888 } | 927 } |
889 } else { | 928 } else { |
890 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 929 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
891 } | 930 } |
951 after = m68k_read_long(context->aregs[7], context); | 990 after = m68k_read_long(context->aregs[7], context); |
952 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { | 991 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { |
953 after = m68k_read_long(context->aregs[7] + 2, context); | 992 after = m68k_read_long(context->aregs[7] + 2, context); |
954 } else if(m68k_is_branch(&inst)) { | 993 } else if(m68k_is_branch(&inst)) { |
955 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { | 994 if (inst.op == M68K_BCC && inst.extra.cond != COND_TRUE) { |
956 branch_f = after; | 995 root->branch_f = after; |
957 branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 996 root->branch_t = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
958 insert_breakpoint(context, branch_t, debugger); | 997 insert_breakpoint(context, root->branch_t, debugger); |
959 } else if(inst.op == M68K_DBCC) { | 998 } else if(inst.op == M68K_DBCC) { |
960 if (inst.extra.cond == COND_FALSE) { | 999 if (inst.extra.cond == COND_FALSE) { |
961 if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) { | 1000 if (context->dregs[inst.dst.params.regs.pri] & 0xFFFF) { |
962 after = m68k_branch_target(&inst, context->dregs, context->aregs); | 1001 after = m68k_branch_target(&inst, context->dregs, context->aregs); |
963 } | 1002 } |
964 } else { | 1003 } else { |
965 branch_t = after; | 1004 root->branch_t = after; |
966 branch_f = m68k_branch_target(&inst, context->dregs, context->aregs); | 1005 root->branch_f = m68k_branch_target(&inst, context->dregs, context->aregs); |
967 insert_breakpoint(context, branch_f, debugger); | 1006 insert_breakpoint(context, root->branch_f, debugger); |
968 } | 1007 } |
969 } else { | 1008 } else { |
970 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; | 1009 after = m68k_branch_target(&inst, context->dregs, context->aregs) & 0xFFFFFF; |
971 } | 1010 } |
972 } | 1011 } |
985 //primary 68K for current system | 1024 //primary 68K for current system |
986 return run_genesis_debugger_command(context, address, input_buf); | 1025 return run_genesis_debugger_command(context, address, input_buf); |
987 } else { | 1026 } else { |
988 //presumably Sega CD sub CPU | 1027 //presumably Sega CD sub CPU |
989 //TODO: consider making this more generic | 1028 //TODO: consider making this more generic |
990 fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf); | 1029 return run_subcpu_debugger_command(context, address, input_buf); |
991 } | 1030 } |
992 break; | 1031 break; |
993 } | 1032 } |
994 } | 1033 } |
995 return 1; | 1034 return 1; |
1049 context->options->sync_components(context, 0); | 1088 context->options->sync_components(context, 0); |
1050 if (context->system == current_system) { | 1089 if (context->system == current_system) { |
1051 genesis_context *gen = context->system; | 1090 genesis_context *gen = context->system; |
1052 vdp_force_update_framebuffer(gen->vdp); | 1091 vdp_force_update_framebuffer(gen->vdp); |
1053 } | 1092 } |
1093 debug_root *root = find_root(context); | |
1094 if (!root) { | |
1095 return; | |
1096 } | |
1054 //probably not necessary, but let's play it safe | 1097 //probably not necessary, but let's play it safe |
1055 address &= 0xFFFFFF; | 1098 address &= 0xFFFFFF; |
1056 if (address == branch_t) { | 1099 if (address == root->branch_t) { |
1057 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); | 1100 bp_def ** f_bp = find_breakpoint(&root->breakpoints, root->branch_f); |
1058 if (!*f_bp) { | 1101 if (!*f_bp) { |
1059 remove_breakpoint(context, branch_f); | 1102 remove_breakpoint(context, root->branch_f); |
1060 } | 1103 } |
1061 branch_t = branch_f = 0; | 1104 root->branch_t = root->branch_f = 0; |
1062 } else if(address == branch_f) { | 1105 } else if(address == root->branch_f) { |
1063 bp_def ** t_bp = find_breakpoint(&breakpoints, branch_t); | 1106 bp_def ** t_bp = find_breakpoint(&root->breakpoints, root->branch_t); |
1064 if (!*t_bp) { | 1107 if (!*t_bp) { |
1065 remove_breakpoint(context, branch_t); | 1108 remove_breakpoint(context, root->branch_t); |
1066 } | 1109 } |
1067 branch_t = branch_f = 0; | 1110 root->branch_t = root->branch_f = 0; |
1068 } | 1111 } |
1069 | 1112 |
1070 uint16_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->options->gen); | 1113 uint16_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->options->gen); |
1071 if (!pc) { | 1114 if (!pc) { |
1072 fatal_error("Entered 68K debugger at address %X\n", address); | 1115 fatal_error("Entered 68K debugger at address %X\n", address); |
1073 } | 1116 } |
1074 uint16_t * after_pc = m68k_decode(pc, &inst, address); | 1117 uint16_t * after_pc = m68k_decode(pc, &inst, address); |
1075 uint32_t after = address + (after_pc-pc)*2; | 1118 uint32_t after = address + (after_pc-pc)*2; |
1076 int debugging = 1; | 1119 int debugging = 1; |
1077 //Check if this is a user set breakpoint, or just a temporary one | 1120 //Check if this is a user set breakpoint, or just a temporary one |
1078 bp_def ** this_bp = find_breakpoint(&breakpoints, address); | 1121 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address); |
1079 if (*this_bp) { | 1122 if (*this_bp) { |
1080 | 1123 |
1081 if ((*this_bp)->commands) | 1124 if ((*this_bp)->commands) |
1082 { | 1125 { |
1083 char *commands = strdup((*this_bp)->commands); | 1126 char *commands = strdup((*this_bp)->commands); |
1098 return; | 1141 return; |
1099 } | 1142 } |
1100 } else { | 1143 } else { |
1101 remove_breakpoint(context, address); | 1144 remove_breakpoint(context, address); |
1102 } | 1145 } |
1103 for (disp_def * cur = displays; cur; cur = cur->next) { | 1146 for (disp_def * cur = root->displays; cur; cur = cur->next) { |
1104 debugger_print(context, cur->format_char, cur->param, address); | 1147 debugger_print(context, cur->format_char, cur->param, address); |
1105 } | 1148 } |
1106 m68k_disasm(&inst, input_buf); | 1149 m68k_disasm(&inst, input_buf); |
1107 printf("%X: %s\n", address, input_buf); | 1150 printf("%X: %s\n", address, input_buf); |
1108 #ifdef _WIN32 | 1151 #ifdef _WIN32 |