comparison debug.c @ 2175:8c28c5466d70

Minor cleanup of debugger changes
author Michael Pavone <pavone@retrodev.com>
date Sat, 06 Aug 2022 22:10:42 -0700
parents eff7bedfc838
children 44596610b2a0
comparison
equal deleted inserted replaced
2174:eff7bedfc838 2175:8c28c5466d70
624 *end = after_first; 624 *end = after_first;
625 return ret; 625 return ret;
626 } 626 }
627 } 627 }
628 628
629 typedef struct debug_context debug_context; 629 uint8_t eval_expr(debug_root *root, expr *e, uint32_t *out)
630 typedef uint8_t (*resolver)(debug_context *context, const char *name, uint32_t *out);
631 typedef uint8_t (*reader)(debug_context *context, uint32_t *out, char size);
632
633 struct debug_context {
634 resolver resolve;
635 reader read_mem;
636 void *system;
637 uint32_t address;
638 };
639
640 uint8_t eval_expr(debug_context *context, expr *e, uint32_t *out)
641 { 630 {
642 uint32_t right; 631 uint32_t right;
643 switch(e->type) 632 switch(e->type)
644 { 633 {
645 case EXPR_SCALAR: 634 case EXPR_SCALAR:
646 if (e->op.type == TOKEN_NAME) { 635 if (e->op.type == TOKEN_NAME) {
647 return context->resolve(context, e->op.v.str, out); 636 return root->resolve(root, e->op.v.str, out);
648 } else { 637 } else {
649 *out = e->op.v.num; 638 *out = e->op.v.num;
650 return 1; 639 return 1;
651 } 640 }
652 case EXPR_UNARY: 641 case EXPR_UNARY:
653 if (!eval_expr(context, e->left, out)) { 642 if (!eval_expr(root, e->left, out)) {
654 return 0; 643 return 0;
655 } 644 }
656 switch (e->op.v.op[0]) 645 switch (e->op.v.op[0])
657 { 646 {
658 case '!': 647 case '!':
667 default: 656 default:
668 return 0; 657 return 0;
669 } 658 }
670 return 1; 659 return 1;
671 case EXPR_BINARY: 660 case EXPR_BINARY:
672 if (!eval_expr(context, e->left, out) || !eval_expr(context, e->right, &right)) { 661 if (!eval_expr(root, e->left, out) || !eval_expr(root, e->right, &right)) {
673 return 0; 662 return 0;
674 } 663 }
675 switch (e->op.v.op[0]) 664 switch (e->op.v.op[0])
676 { 665 {
677 case '+': 666 case '+':
704 default: 693 default:
705 return 0; 694 return 0;
706 } 695 }
707 return 1; 696 return 1;
708 case EXPR_SIZE: 697 case EXPR_SIZE:
709 if (!eval_expr(context, e->left, out)) { 698 if (!eval_expr(root, e->left, out)) {
710 return 0; 699 return 0;
711 } 700 }
712 switch (e->op.v.op[0]) 701 switch (e->op.v.op[0])
713 { 702 {
714 case 'b': 703 case 'b':
718 *out &= 0xFFFF; 707 *out &= 0xFFFF;
719 break; 708 break;
720 } 709 }
721 return 1; 710 return 1;
722 case EXPR_MEM: 711 case EXPR_MEM:
723 if (!eval_expr(context, e->left, out)) { 712 if (!eval_expr(root, e->left, out)) {
724 return 0; 713 return 0;
725 } 714 }
726 return context->read_mem(context, out, e->op.v.op[0]); 715 return root->read_mem(root, out, e->op.v.op[0]);
727 default: 716 default:
728 return 0; 717 return 0;
729 } 718 }
730 } 719 }
731 720
789 static uint32_t m68k_read_long(uint32_t address, m68k_context *context) 778 static uint32_t m68k_read_long(uint32_t address, m68k_context *context)
790 { 779 {
791 return m68k_read_word(address, context) << 16 | m68k_read_word(address + 2, context); 780 return m68k_read_word(address, context) << 16 | m68k_read_word(address + 2, context);
792 } 781 }
793 782
794 static uint8_t read_m68k(m68k_context *context, uint32_t *out, char size) 783 static uint8_t read_m68k(debug_root *root, uint32_t *out, char size)
795 { 784 {
785 m68k_context *context = root->cpu_context;
796 if (size == 'b') { 786 if (size == 'b') {
797 *out = m68k_read_byte(*out, context); 787 *out = m68k_read_byte(*out, context);
798 } else if (size == 'l') { 788 } else if (size == 'l') {
799 *out = m68k_read_long(*out, context); 789 *out = m68k_read_long(*out, context);
800 } else { 790 } else {
801 *out = m68k_read_word(*out, context); 791 *out = m68k_read_word(*out, context);
802 } 792 }
803 return 1; 793 return 1;
804 } 794 }
805 795
806 static uint8_t read_genesis(debug_context *context, uint32_t *out, char size) 796 static uint8_t resolve_m68k(debug_root *root, const char *name, uint32_t *out)
807 { 797 {
808 genesis_context *gen = context->system; 798 m68k_context *context = root->cpu_context;
809 return read_m68k(gen->m68k, out, size);
810 }
811
812 static uint8_t resolve_m68k(debug_context *debug, m68k_context *context, const char *name, uint32_t *out)
813 {
814 if ((name[0] == 'd' || name[0] == 'D') && name[1] >= '0' && name[1] <= '7' && !name[2]) { 799 if ((name[0] == 'd' || name[0] == 'D') && name[1] >= '0' && name[1] <= '7' && !name[2]) {
815 *out = context->dregs[name[1]-'0']; 800 *out = context->dregs[name[1]-'0'];
816 } else if ((name[0] == 'a' || name[0] == 'A') && name[1] >= '0' && name[1] <= '7' && !name[2]) { 801 } else if ((name[0] == 'a' || name[0] == 'A') && name[1] >= '0' && name[1] <= '7' && !name[2]) {
817 *out = context->aregs[name[1]-'0']; 802 *out = context->aregs[name[1]-'0'];
818 } else if (!strcasecmp(name, "sr")) { 803 } else if (!strcasecmp(name, "sr")) {
821 *out |= context->flags[flag] << (4-flag); 806 *out |= context->flags[flag] << (4-flag);
822 } 807 }
823 } else if(!strcasecmp(name, "cycle")) { 808 } else if(!strcasecmp(name, "cycle")) {
824 *out = context->current_cycle; 809 *out = context->current_cycle;
825 } else if (!strcasecmp(name, "pc")) { 810 } else if (!strcasecmp(name, "pc")) {
826 *out = debug->address; 811 *out = root->address;
827 } else if (!strcasecmp(name, "usp")) { 812 } else if (!strcasecmp(name, "usp")) {
828 *out = context->status & 0x20 ? context->aregs[8] : context->aregs[7]; 813 *out = context->status & 0x20 ? context->aregs[8] : context->aregs[7];
829 } else if (!strcasecmp(name, "ssp")) { 814 } else if (!strcasecmp(name, "ssp")) {
830 *out = context->status & 0x20 ? context->aregs[7] : context->aregs[8]; 815 *out = context->status & 0x20 ? context->aregs[7] : context->aregs[8];
831 } else { 816 } else {
832 return 0; 817 return 0;
833 } 818 }
834 return 1; 819 return 1;
835 } 820 }
836 821
837 static uint8_t resolve_genesis(debug_context *context, const char *name, uint32_t *out) 822 static uint8_t resolve_genesis(debug_root *root, const char *name, uint32_t *out)
838 { 823 {
839 genesis_context *gen = context->system; 824 if (resolve_m68k(root, name, out)) {
840 if (resolve_m68k(context, gen->m68k, name, out)) {
841 return 1; 825 return 1;
842 } 826 }
827 m68k_context *m68k = root->cpu_context;
828 genesis_context *gen = m68k->system;
843 if (!strcmp(name, "f") || !strcmp(name, "frame")) { 829 if (!strcmp(name, "f") || !strcmp(name, "frame")) {
844 *out = gen->vdp->frame; 830 *out = gen->vdp->frame;
845 return 1; 831 return 1;
846 } 832 }
847 return 0; 833 return 0;
848 } 834 }
849 835
850 void debugger_print(m68k_context *context, char format_char, char *param, uint32_t address) 836 void debugger_print(debug_root *root, char format_char, char *param)
851 { 837 {
852 uint32_t value; 838 uint32_t value;
853 char format[8]; 839 char format[8];
854 strcpy(format, "%s: %d\n"); 840 strcpy(format, "%s: %d\n");
855 switch (format_char) 841 switch (format_char)
864 case '\0': 850 case '\0':
865 break; 851 break;
866 default: 852 default:
867 fprintf(stderr, "Unrecognized format character: %c\n", format_char); 853 fprintf(stderr, "Unrecognized format character: %c\n", format_char);
868 } 854 }
869 debug_context c = {
870 .resolve = resolve_genesis,
871 .read_mem = read_genesis,
872 .system = context->system,
873 .address = address
874 };
875 char *after; 855 char *after;
876 uint8_t at_least_one = 0; 856 uint8_t at_least_one = 0;
877 while (*param && *param != '\n') 857 while (*param && *param != '\n')
878 { 858 {
879 at_least_one = 1; 859 at_least_one = 1;
880 expr *e = parse_expression(param, &after); 860 expr *e = parse_expression(param, &after);
881 if (e) { 861 if (e) {
882 if (!eval_expr(&c, e, &value)) { 862 if (!eval_expr(root, e, &value)) {
883 fprintf(stderr, "Failed to eval %s\n", param); 863 fprintf(stderr, "Failed to eval %s\n", param);
884 } 864 }
885 free_expr(e); 865 free_expr(e);
886 } else { 866 } else {
887 fprintf(stderr, "Failed to parse %s\n", param); 867 fprintf(stderr, "Failed to parse %s\n", param);
893 if (format_char == 's') { 873 if (format_char == 's') {
894 char tmp[128]; 874 char tmp[128];
895 int i; 875 int i;
896 for (i = 0; i < sizeof(tmp)-1; i++, value++) 876 for (i = 0; i < sizeof(tmp)-1; i++, value++)
897 { 877 {
898 char c = m68k_read_byte(value, context); 878 uint32_t addr = value;
879 root->read_mem(root, &addr, 'b');
880 char c = addr;
899 if (c < 0x20 || c > 0x7F) { 881 if (c < 0x20 || c > 0x7F) {
900 break; 882 break;
901 } 883 }
902 tmp[i] = c; 884 tmp[i] = c;
903 } 885 }
1438 bp_def *new_bp, **this_bp; 1420 bp_def *new_bp, **this_bp;
1439 debug_root *root = find_root(context); 1421 debug_root *root = find_root(context);
1440 if (!root) { 1422 if (!root) {
1441 return 0; 1423 return 0;
1442 } 1424 }
1425 root->address = address;
1443 switch(input_buf[0]) 1426 switch(input_buf[0])
1444 { 1427 {
1445 case 'c': 1428 case 'c':
1446 if (input_buf[1] == 0 || input_buf[1] == 'o' && input_buf[2] == 'n') 1429 if (input_buf[1] == 0 || input_buf[1] == 'o' && input_buf[2] == 'n')
1447 { 1430 {
1540 param = find_param(input_buf); 1523 param = find_param(input_buf);
1541 if (!param) { 1524 if (!param) {
1542 fputs("display command requires a parameter\n", stderr); 1525 fputs("display command requires a parameter\n", stderr);
1543 break; 1526 break;
1544 } 1527 }
1545 debugger_print(context, format_char, param, address); 1528 debugger_print(root, format_char, param);
1546 add_display(&root->displays, &root->disp_index, format_char, param); 1529 add_display(&root->displays, &root->disp_index, format_char, param);
1547 } else { 1530 } else {
1548 param = find_param(input_buf); 1531 param = find_param(input_buf);
1549 if (!param) { 1532 if (!param) {
1550 fputs("d command requires a parameter\n", stderr); 1533 fputs("d command requires a parameter\n", stderr);
1572 break; 1555 break;
1573 } 1556 }
1574 } 1557 }
1575 param = find_param(input_buf); 1558 param = find_param(input_buf);
1576 if (param) { 1559 if (param) {
1577 debugger_print(context, format_char, param, address); 1560 debugger_print(root, format_char, param);
1578 } else { 1561 } else {
1579 m68k_disasm(&inst, input_buf); 1562 m68k_disasm(&inst, input_buf);
1580 printf("%X: %s\n", address, input_buf); 1563 printf("%X: %s\n", address, input_buf);
1581 } 1564 }
1582 1565
1844 } 1827 }
1845 } else { 1828 } else {
1846 remove_breakpoint(context, address); 1829 remove_breakpoint(context, address);
1847 } 1830 }
1848 for (disp_def * cur = root->displays; cur; cur = cur->next) { 1831 for (disp_def * cur = root->displays; cur; cur = cur->next) {
1849 debugger_print(context, cur->format_char, cur->param, address); 1832 debugger_print(root, cur->format_char, cur->param);
1850 } 1833 }
1851 m68k_disasm(&inst, input_buf); 1834 m68k_disasm(&inst, input_buf);
1852 printf("%X: %s\n", address, input_buf); 1835 printf("%X: %s\n", address, input_buf);
1853 #ifdef _WIN32 1836 #ifdef _WIN32
1854 #define prompt 1 1837 #define prompt 1