comparison debug.c @ 1931:374a5ae694e8 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 18 Apr 2020 11:42:53 -0700
parents 0a26f3657295 23394a890508
children a7b753e260a2
comparison
equal deleted inserted replaced
1843:13abdc98379e 1931:374a5ae694e8
9 #include "render.h" 9 #include "render.h"
10 #include "util.h" 10 #include "util.h"
11 #include "terminal.h" 11 #include "terminal.h"
12 #include "z80inst.h" 12 #include "z80inst.h"
13 13
14 #ifndef USE_NATIVE 14 #ifdef NEW_CORE
15 #define Z80_OPTS opts 15 #define Z80_OPTS opts
16 #else 16 #else
17 #define Z80_OPTS options 17 #define Z80_OPTS options
18 #endif 18 #endif
19 19
103 uint32_t m68k_read_long(uint32_t address, m68k_context *context) 103 uint32_t m68k_read_long(uint32_t address, m68k_context *context)
104 { 104 {
105 return m68k_read_word(address, context) << 16 | m68k_read_word(address + 2, context); 105 return m68k_read_word(address, context) << 16 | m68k_read_word(address + 2, context);
106 } 106 }
107 107
108 void debugger_print(m68k_context *context, char format_char, char *param) 108 void debugger_print(m68k_context *context, char format_char, char *param, uint32_t address)
109 { 109 {
110 uint32_t value; 110 uint32_t value;
111 char format[8]; 111 char format[8];
112 strcpy(format, "%s: %d\n"); 112 strcpy(format, "%s: %d\n");
113 switch (format_char) 113 switch (format_char)
139 value &= 0xFFFF; 139 value &= 0xFFFF;
140 } else if (param[3] == 'b') { 140 } else if (param[3] == 'b') {
141 value &= 0xFF; 141 value &= 0xFF;
142 } 142 }
143 } 143 }
144 } else if (param[0] == 'S' && param[1] == 'R') { 144 } else if (param[0] == 's' && param[1] == 'r') {
145 value = (context->status << 8); 145 value = (context->status << 8);
146 for (int flag = 0; flag < 5; flag++) { 146 for (int flag = 0; flag < 5; flag++) {
147 value |= context->flags[flag] << (4-flag); 147 value |= context->flags[flag] << (4-flag);
148 } 148 }
149 } else if(param[0] == 'c') { 149 } else if(param[0] == 'c') {
150 value = context->current_cycle; 150 value = context->current_cycle;
151 } else if(param[0] == 'f') { 151 } else if(param[0] == 'f') {
152 genesis_context *gen = context->system; 152 genesis_context *gen = context->system;
153 value = gen->vdp->frame; 153 value = gen->vdp->frame;
154 } else if (param[0] == 'p' && param[1] == 'c') {
155 value = address;
154 } else if ((param[0] == '0' && param[1] == 'x') || param[0] == '$') { 156 } else if ((param[0] == '0' && param[1] == 'x') || param[0] == '$') {
155 char *after; 157 char *after;
156 uint32_t p_addr = strtol(param+(param[0] == '0' ? 2 : 1), &after, 16); 158 uint32_t p_addr = strtol(param+(param[0] == '0' ? 2 : 1), &after, 16);
157 if (after[0] == '.' && after[1] == 'l') { 159 if (after[0] == '.' && after[1] == 'l') {
158 value = m68k_read_long(p_addr, context); 160 value = m68k_read_long(p_addr, context);
195 default: 197 default:
196 fprintf(stderr, "Unrecognized format character: %c\n", format_char); 198 fprintf(stderr, "Unrecognized format character: %c\n", format_char);
197 } 199 }
198 switch (param[0]) 200 switch (param[0])
199 { 201 {
200 #ifdef USE_NATIVE 202 #ifndef NEW_CORE
201 case 'a': 203 case 'a':
202 if (param[1] == 'f') { 204 if (param[1] == 'f') {
203 if(param[2] == '\'') { 205 if(param[2] == '\'') {
204 value = context->alt_regs[Z80_A] << 8; 206 value = context->alt_regs[Z80_A] << 8;
205 value |= context->alt_flags[ZF_S] << 7; 207 value |= context->alt_flags[ZF_S] << 7;
346 } 348 }
347 break; 349 break;
348 case '0': 350 case '0':
349 if (param[1] == 'x') { 351 if (param[1] == 'x') {
350 uint16_t p_addr = strtol(param+2, NULL, 16); 352 uint16_t p_addr = strtol(param+2, NULL, 16);
351 if (p_addr < 0x4000) { 353 value = read_byte(p_addr, (void **)context->mem_pointers, &context->options->gen, context);
352 value = system->zram[p_addr & 0x1FFF];
353 } else if(p_addr >= 0x8000) {
354 uint32_t v_addr = system->z80_bank_reg << 15;
355 v_addr += p_addr & 0x7FFF;
356 if (v_addr < 0x400000) {
357 value = system->cart[v_addr/2];
358 } else if(v_addr > 0xE00000) {
359 value = system->work_ram[(v_addr & 0xFFFF)/2];
360 }
361 if (v_addr & 1) {
362 value &= 0xFF;
363 } else {
364 value >>= 8;
365 }
366 }
367 } 354 }
368 break; 355 break;
369 } 356 }
370 printf(format, param, value); 357 printf(format, param, value);
371 } 358 }
494 //TODO: Handle conditional branch instructions 481 //TODO: Handle conditional branch instructions
495 if (inst.op == Z80_JP) { 482 if (inst.op == Z80_JP) {
496 if (inst.addr_mode == Z80_IMMED) { 483 if (inst.addr_mode == Z80_IMMED) {
497 after = inst.immed; 484 after = inst.immed;
498 } else if (inst.ea_reg == Z80_HL) { 485 } else if (inst.ea_reg == Z80_HL) {
499 #ifdef USE_NATIVE 486 #ifndef NEW_CORE
500 after = context->regs[Z80_H] << 8 | context->regs[Z80_L]; 487 after = context->regs[Z80_H] << 8 | context->regs[Z80_L];
501 } else if (inst.ea_reg == Z80_IX) { 488 } else if (inst.ea_reg == Z80_IX) {
502 after = context->regs[Z80_IXH] << 8 | context->regs[Z80_IXL]; 489 after = context->regs[Z80_IXH] << 8 | context->regs[Z80_IXL];
503 } else if (inst.ea_reg == Z80_IY) { 490 } else if (inst.ea_reg == Z80_IY) {
504 after = context->regs[Z80_IYH] << 8 | context->regs[Z80_IYL]; 491 after = context->regs[Z80_IYH] << 8 | context->regs[Z80_IYL];
565 } else { 552 } else {
566 fputs("Failed to find a RAM memory chunk\n", stderr); 553 fputs("Failed to find a RAM memory chunk\n", stderr);
567 } 554 }
568 break; 555 break;
569 } 556 }
557 case '?':
558 print_z80_help();
559 break;
570 default: 560 default:
571 if ( 561 if (
572 !context->Z80_OPTS->gen.debug_cmd_handler 562 !context->Z80_OPTS->gen.debug_cmd_handler
573 || !context->Z80_OPTS->gen.debug_cmd_handler(&system->header, input_buf) 563 || !context->Z80_OPTS->gen.debug_cmd_handler(&system->header, input_buf)
574 ) { 564 ) {
575 fprintf(stderr, "Unrecognized debugger command %s\n", input_buf); 565 fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf);
576 } 566 }
577 break; 567 break;
578 } 568 }
579 } 569 }
580 return context; 570 return context;
583 #endif 573 #endif
584 574
585 static uint32_t branch_t; 575 static uint32_t branch_t;
586 static uint32_t branch_f; 576 static uint32_t branch_f;
587 577
588 int run_debugger_command(m68k_context *context, char *input_buf, m68kinst inst, uint32_t after) 578 int run_debugger_command(m68k_context *context, uint32_t address, char *input_buf, m68kinst inst, uint32_t after)
589 { 579 {
590 char * param; 580 char * param;
591 char format_char; 581 char format_char;
592 genesis_context *system = context->system; 582 genesis_context *system = context->system;
593 uint32_t value; 583 uint32_t value;
701 param = find_param(input_buf); 691 param = find_param(input_buf);
702 if (!param) { 692 if (!param) {
703 fputs("display command requires a parameter\n", stderr); 693 fputs("display command requires a parameter\n", stderr);
704 break; 694 break;
705 } 695 }
706 debugger_print(context, format_char, param); 696 debugger_print(context, format_char, param, address);
707 add_display(&displays, &disp_index, format_char, param); 697 add_display(&displays, &disp_index, format_char, param);
708 } else { 698 } else {
709 param = find_param(input_buf); 699 param = find_param(input_buf);
710 if (!param) { 700 if (!param) {
711 fputs("d command requires a parameter\n", stderr); 701 fputs("d command requires a parameter\n", stderr);
732 format_char = input_buf[i+1]; 722 format_char = input_buf[i+1];
733 break; 723 break;
734 } 724 }
735 } 725 }
736 param = find_param(input_buf); 726 param = find_param(input_buf);
737 if (!param) { 727 if (param) {
738 fputs("p command requires a parameter\n", stderr); 728 debugger_print(context, format_char, param, address);
739 break; 729 } else {
740 } 730 m68k_disasm(&inst, input_buf);
741 debugger_print(context, format_char, param); 731 printf("%X: %s\n", address, input_buf);
732 }
733
742 break; 734 break;
743 case 'n': 735 case 'n':
744 if (inst.op == M68K_RTS) { 736 if (inst.op == M68K_RTS) {
745 after = m68k_read_long(context->aregs[7], context); 737 after = m68k_read_long(context->aregs[7], context);
746 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { 738 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
800 case 's': 792 case 's':
801 if (input_buf[1] == 'e') { 793 if (input_buf[1] == 'e') {
802 param = find_param(input_buf); 794 param = find_param(input_buf);
803 if (!param) { 795 if (!param) {
804 fputs("Missing destination parameter for set\n", stderr); 796 fputs("Missing destination parameter for set\n", stderr);
797 return 1;
805 } 798 }
806 char *val = find_param(param); 799 char *val = find_param(param);
807 if (!val) { 800 if (!val) {
808 fputs("Missing value parameter for set\n", stderr); 801 fputs("Missing value parameter for set\n", stderr);
802 return 1;
809 } 803 }
810 long int_val; 804 long int_val;
811 int reg_num; 805 int reg_num;
812 switch (val[0]) 806 switch (val[0])
813 { 807 {
844 break; 838 break;
845 default: 839 default:
846 fprintf(stderr, "Invalid destinatino %s\n", param); 840 fprintf(stderr, "Invalid destinatino %s\n", param);
847 } 841 }
848 break; 842 break;
843 } else if (input_buf[1] == 'r') {
844 system->header.soft_reset(&system->header);
845 return 0;
849 } else { 846 } else {
850 if (inst.op == M68K_RTS) { 847 if (inst.op == M68K_RTS) {
851 after = m68k_read_long(context->aregs[7], context); 848 after = m68k_read_long(context->aregs[7], context);
852 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) { 849 } else if (inst.op == M68K_RTE || inst.op == M68K_RTR) {
853 after = m68k_read_long(context->aregs[7] + 2, context); 850 after = m68k_read_long(context->aregs[7] + 2, context);
938 zdebugger_print(gen->z80, input_buf[2] == '/' ? input_buf[3] : 0, param); 935 zdebugger_print(gen->z80, input_buf[2] == '/' ? input_buf[3] : 0, param);
939 } 936 }
940 break; 937 break;
941 } 938 }
942 #endif 939 #endif
940 case '?':
941 print_m68k_help();
942 break;
943 case 'q': 943 case 'q':
944 puts("Quitting"); 944 puts("Quitting");
945 exit(0); 945 exit(0);
946 break; 946 break;
947 default: 947 default:
948 fprintf(stderr, "Unrecognized debugger command %s\n", input_buf); 948 fprintf(stderr, "Unrecognized debugger command %s\nUse '?' for help.\n", input_buf);
949 break; 949 break;
950 } 950 }
951 return 1; 951 return 1;
952 } 952 }
953 953
954 void print_m68k_help()
955 {
956 printf("M68k Debugger Commands\n");
957 printf(" b ADDRESS - Set a breakpoint at ADDRESS\n");
958 printf(" d BREAKPOINT - Delete a 68K breakpoint\n");
959 printf(" co BREAKPOINT - Run a list of debugger commands each time\n");
960 printf(" BREAKPOINT is hit\n");
961 printf(" a ADDRESS - Advance to address\n");
962 printf(" n - Advance to next instruction\n");
963 printf(" o - Advance to next instruction ignoring branches to\n");
964 printf(" lower addresses (good for breaking out of loops)\n");
965 printf(" s - Advance to next instruction (follows bsr/jsr)\n");
966 printf(" se REG|ADDRESS VALUE - Set value\n");
967 printf(" sr - Soft reset\n");
968 printf(" c - Continue\n");
969 printf(" bt - Print a backtrace\n");
970 printf(" p[/(x|X|d|c)] VALUE - Print a register or memory location\n");
971 printf(" di[/(x|X|d|c)] VALUE - Print a register or memory location each time\n");
972 printf(" a breakpoint is hit\n");
973 printf(" vs - Print VDP sprite list\n");
974 printf(" vr - Print VDP register info\n");
975 printf(" yc [CHANNEL NUM] - Print YM-2612 channel info\n");
976 printf(" yt - Print YM-2612 timer info\n");
977 printf(" zb ADDRESS - Set a Z80 breakpoint\n");
978 printf(" zp[/(x|X|d|c)] VALUE - Display a Z80 value\n");
979 printf(" ? - Display help\n");
980 printf(" q - Quit BlastEm\n");
981 }
982
983 void print_z80_help()
984 {
985 printf("Z80 Debugger Commands\n");
986 printf(" b ADDRESS - Set a breakpoint at ADDRESS\n");
987 printf(" de BREAKPOINT - Delete a Z80 breakpoint\n");
988 printf(" a ADDRESS - Advance to address\n");
989 printf(" n - Advance to next instruction\n");
990 printf(" c - Continue\n");
991 printf(" p[/(x|X|d|c)] VALUE - Print a register or memory location\n");
992 printf(" di[/(x|X|d|c)] VALUE - Print a register or memory location each time\n");
993 printf(" a breakpoint is hit\n");
994 printf(" q - Quit BlastEm\n");
995 }
954 996
955 void debugger(m68k_context * context, uint32_t address) 997 void debugger(m68k_context * context, uint32_t address)
956 { 998 {
957 static char last_cmd[1024]; 999 static char last_cmd[1024];
958 char input_buf[1024]; 1000 char input_buf[1024];
998 while (debugging && *commands) 1040 while (debugging && *commands)
999 { 1041 {
1000 char *cmd = commands; 1042 char *cmd = commands;
1001 strip_nl(cmd); 1043 strip_nl(cmd);
1002 commands += strlen(cmd) + 1; 1044 commands += strlen(cmd) + 1;
1003 debugging = run_debugger_command(context, cmd, inst, after); 1045 debugging = run_debugger_command(context, address, cmd, inst, after);
1004 } 1046 }
1005 free(copy); 1047 free(copy);
1006 } 1048 }
1007 if (debugging) { 1049 if (debugging) {
1008 printf("68K Breakpoint %d hit\n", (*this_bp)->index); 1050 printf("68K Breakpoint %d hit\n", (*this_bp)->index);
1011 } 1053 }
1012 } else { 1054 } else {
1013 remove_breakpoint(context, address); 1055 remove_breakpoint(context, address);
1014 } 1056 }
1015 for (disp_def * cur = displays; cur; cur = cur->next) { 1057 for (disp_def * cur = displays; cur; cur = cur->next) {
1016 debugger_print(context, cur->format_char, cur->param); 1058 debugger_print(context, cur->format_char, cur->param, address);
1017 } 1059 }
1018 m68k_disasm(&inst, input_buf); 1060 m68k_disasm(&inst, input_buf);
1019 printf("%X: %s\n", address, input_buf); 1061 printf("%X: %s\n", address, input_buf);
1020 #ifdef _WIN32 1062 #ifdef _WIN32
1021 #define prompt 1 1063 #define prompt 1
1051 if (input_buf[0]) { 1093 if (input_buf[0]) {
1052 strcpy(last_cmd, input_buf); 1094 strcpy(last_cmd, input_buf);
1053 } else { 1095 } else {
1054 strcpy(input_buf, last_cmd); 1096 strcpy(input_buf, last_cmd);
1055 } 1097 }
1056 debugging = run_debugger_command(context, input_buf, inst, after); 1098 debugging = run_debugger_command(context, address, input_buf, inst, after);
1057 } 1099 }
1058 return; 1100 return;
1059 } 1101 }