Mercurial > repos > blastem
comparison debug.c @ 803:236a184bf6f0
Merge
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 26 Jul 2015 16:51:03 -0700 |
parents | 792be135d3af |
children | cc05444a4a4e |
comparison
equal
deleted
inserted
replaced
802:6811f601008f | 803:236a184bf6f0 |
---|---|
1 #include "debug.h" | 1 #include "debug.h" |
2 #include "blastem.h" | 2 #include "blastem.h" |
3 #include "68kinst.h" | 3 #include "68kinst.h" |
4 #include <stdlib.h> | 4 #include <stdlib.h> |
5 #include <string.h> | 5 #include <string.h> |
6 #ifndef _WIN32 | |
7 #include <sys/select.h> | |
8 #endif | |
9 #include "render.h" | |
10 #include "util.h" | |
11 #include "terminal.h" | |
6 | 12 |
7 static bp_def * breakpoints = NULL; | 13 static bp_def * breakpoints = NULL; |
8 static bp_def * zbreakpoints = NULL; | 14 static bp_def * zbreakpoints = NULL; |
9 static uint32_t bp_index = 0; | 15 static uint32_t bp_index = 0; |
10 static uint32_t zbp_index = 0; | 16 static uint32_t zbp_index = 0; |
280 static char last_cmd[1024]; | 286 static char last_cmd[1024]; |
281 char input_buf[1024]; | 287 char input_buf[1024]; |
282 static uint16_t branch_t; | 288 static uint16_t branch_t; |
283 static uint16_t branch_f; | 289 static uint16_t branch_f; |
284 z80inst inst; | 290 z80inst inst; |
291 init_terminal(); | |
285 //Check if this is a user set breakpoint, or just a temporary one | 292 //Check if this is a user set breakpoint, or just a temporary one |
286 bp_def ** this_bp = find_breakpoint(&zbreakpoints, address); | 293 bp_def ** this_bp = find_breakpoint(&zbreakpoints, address); |
287 if (*this_bp) { | 294 if (*this_bp) { |
288 printf("Z80 Breakpoint %d hit\n", (*this_bp)->index); | 295 printf("Z80 Breakpoint %d hit\n", (*this_bp)->index); |
289 } else { | 296 } else { |
292 uint8_t * pc; | 299 uint8_t * pc; |
293 if (address < 0x4000) { | 300 if (address < 0x4000) { |
294 pc = z80_ram + (address & 0x1FFF); | 301 pc = z80_ram + (address & 0x1FFF); |
295 } else if (address >= 0x8000) { | 302 } else if (address >= 0x8000) { |
296 if (context->bank_reg < (0x400000 >> 15)) { | 303 if (context->bank_reg < (0x400000 >> 15)) { |
297 fprintf(stderr, "Entered Z80 debugger in banked memory address %X, which is not yet supported\n", address); | 304 fatal_error("Entered Z80 debugger in banked memory address %X, which is not yet supported\n", address); |
298 exit(1); | 305 } else { |
299 } else { | 306 fatal_error("Entered Z80 debugger in banked memory address %X, but the bank is not pointed to a cartridge address\n", address); |
300 fprintf(stderr, "Entered Z80 debugger in banked memory address %X, but the bank is not pointed to a cartridge address\n", address); | |
301 exit(1); | |
302 } | 307 } |
303 } else { | 308 } else { |
304 fprintf(stderr, "Entered Z80 debugger at address %X\n", address); | 309 fatal_error("Entered Z80 debugger at address %X\n", address); |
305 exit(1); | |
306 } | 310 } |
307 for (disp_def * cur = zdisplays; cur; cur = cur->next) { | 311 for (disp_def * cur = zdisplays; cur; cur = cur->next) { |
308 zdebugger_print(context, cur->format_char, cur->param); | 312 zdebugger_print(context, cur->format_char, cur->param); |
309 } | 313 } |
310 uint8_t * after_pc = z80_decode(pc, &inst); | 314 uint8_t * after_pc = z80_decode(pc, &inst); |
469 static char last_cmd[1024]; | 473 static char last_cmd[1024]; |
470 char input_buf[1024]; | 474 char input_buf[1024]; |
471 static uint32_t branch_t; | 475 static uint32_t branch_t; |
472 static uint32_t branch_f; | 476 static uint32_t branch_f; |
473 m68kinst inst; | 477 m68kinst inst; |
478 | |
479 init_terminal(); | |
480 | |
481 sync_components(context, 0); | |
474 //probably not necessary, but let's play it safe | 482 //probably not necessary, but let's play it safe |
475 address &= 0xFFFFFF; | 483 address &= 0xFFFFFF; |
476 if (address == branch_t) { | 484 if (address == branch_t) { |
477 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); | 485 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); |
478 if (!*f_bp) { | 486 if (!*f_bp) { |
497 if (address < 0x400000) { | 505 if (address < 0x400000) { |
498 pc = cart + address/2; | 506 pc = cart + address/2; |
499 } else if(address > 0xE00000) { | 507 } else if(address > 0xE00000) { |
500 pc = ram + (address & 0xFFFF)/2; | 508 pc = ram + (address & 0xFFFF)/2; |
501 } else { | 509 } else { |
502 fprintf(stderr, "Entered 68K debugger at address %X\n", address); | 510 fatal_error("Entered 68K debugger at address %X\n", address); |
503 exit(1); | |
504 } | 511 } |
505 uint16_t * after_pc = m68k_decode(pc, &inst, address); | 512 uint16_t * after_pc = m68k_decode(pc, &inst, address); |
506 m68k_disasm(&inst, input_buf); | 513 m68k_disasm(&inst, input_buf); |
507 printf("%X: %s\n", address, input_buf); | 514 printf("%X: %s\n", address, input_buf); |
508 uint32_t after = address + (after_pc-pc)*2; | 515 uint32_t after = address + (after_pc-pc)*2; |
509 int debugging = 1; | 516 int debugging = 1; |
517 #ifdef _WIN32 | |
518 #define prompt 1 | |
519 #else | |
520 int prompt = 1; | |
521 fd_set read_fds; | |
522 FD_ZERO(&read_fds); | |
523 struct timeval timeout; | |
524 #endif | |
510 while (debugging) { | 525 while (debugging) { |
511 fputs(">", stdout); | 526 if (prompt) { |
527 fputs(">", stdout); | |
528 fflush(stdout); | |
529 } | |
530 process_events(); | |
531 #ifndef _WIN32 | |
532 timeout.tv_sec = 0; | |
533 timeout.tv_usec = 16667; | |
534 FD_SET(fileno(stdin), &read_fds); | |
535 if(select(fileno(stdin) + 1, &read_fds, NULL, NULL, &timeout) < 1) { | |
536 prompt = 0; | |
537 continue; | |
538 } else { | |
539 prompt = 1; | |
540 } | |
541 #endif | |
512 if (!fgets(input_buf, sizeof(input_buf), stdin)) { | 542 if (!fgets(input_buf, sizeof(input_buf), stdin)) { |
513 fputs("fgets failed", stderr); | 543 fputs("fgets failed", stderr); |
514 break; | 544 break; |
515 } | 545 } |
516 strip_nl(input_buf); | 546 strip_nl(input_buf); |
630 for (int flag = 0; flag < 5; flag++) { | 660 for (int flag = 0; flag < 5; flag++) { |
631 value |= context->flags[flag] << (4-flag); | 661 value |= context->flags[flag] << (4-flag); |
632 } | 662 } |
633 } else if(param[0] == 'c') { | 663 } else if(param[0] == 'c') { |
634 value = context->current_cycle; | 664 value = context->current_cycle; |
635 } else if (param[0] == '0' && param[1] == 'x') { | 665 } else if ((param[0] == '0' && param[1] == 'x') || param[0] == '$') { |
636 uint32_t p_addr = strtol(param+2, NULL, 16); | 666 uint32_t p_addr = strtol(param+(param[0] == '0' ? 2 : 1), NULL, 16); |
637 value = read_dma_value(p_addr/2); | 667 if ((p_addr & 0xFFFFFF) == 0xC00004) { |
668 genesis_context * gen = context->system; | |
669 value = vdp_hv_counter_read(gen->vdp); | |
670 } else { | |
671 value = read_dma_value(p_addr/2); | |
672 } | |
638 } else { | 673 } else { |
639 fprintf(stderr, "Unrecognized parameter to p: %s\n", param); | 674 fprintf(stderr, "Unrecognized parameter to p: %s\n", param); |
640 break; | 675 break; |
641 } | 676 } |
642 printf(format, param, value); | 677 printf(format, param, value); |
733 vdp_print_reg_explain(gen->vdp); | 768 vdp_print_reg_explain(gen->vdp); |
734 break; | 769 break; |
735 } | 770 } |
736 break; | 771 break; |
737 } | 772 } |
773 case 'y': { | |
774 genesis_context * gen = context->system; | |
775 //YM-2612 debug commands | |
776 switch(input_buf[1]) | |
777 { | |
778 case 'c': | |
779 if (input_buf[2] == ' ') { | |
780 int channel = atoi(input_buf+3)-1; | |
781 ym_print_channel_info(gen->ym, channel); | |
782 } else { | |
783 for (int i = 0; i < 6; i++) { | |
784 ym_print_channel_info(gen->ym, i); | |
785 } | |
786 } | |
787 } | |
788 break; | |
789 } | |
738 #ifndef NO_Z80 | 790 #ifndef NO_Z80 |
739 case 'z': { | 791 case 'z': { |
740 genesis_context * gen = context->system; | 792 genesis_context * gen = context->system; |
741 //Z80 debug commands | 793 //Z80 debug commands |
742 switch(input_buf[1]) | 794 switch(input_buf[1]) |