2 // Tooling to help debug.
3 // (C) 2012 Edd Barrett <vext01@gmail.com>
15 #include "musa/m68k.h"
20 #include "dz80/types.h"
21 #include "dz80/dissz80.h"
28 #include "linenoise/linenoise.h"
30 static const char *debug_context_names
[] = {
31 "M68K", "Z80", "YM2612", "SN76489"
35 * Aliases for the various cores.
38 /** Aliases for SN76489 core. */
39 const char *psg_aliases
[] = { "sn", "sn76489", "psg", NULL
};
40 /** Aliases for YM2612 core. */
41 const char *fm_aliases
[] = { "fm", "ym", "ym2612", NULL
};
42 /** Aliases for Z80 core. */
43 const char *z80_aliases
[] = { "z80", "z", NULL
};
44 /** Aliases for M68K core. */
45 const char *m68k_aliases
[] = { "m68k", "m", "68000", "m68000", NULL
};
48 #define CURRENT_DEBUG_CONTEXT_NAME debug_context_names[debug_context]
50 // ===[ C Functions ]=========================================================
53 * Linenoise completion callback.
55 * @param buf String so far.
56 * @param lc List of linenoise completions.
59 void completion(const char *buf
, linenoiseCompletions
*lc
) {
61 const struct md::dgen_debugger_cmd
*cmd
= md::debug_cmd_list
;
63 while (cmd
->cmd
!= NULL
) {
64 if (strlen(cmd
->cmd
) != 1) {
65 if (buf
[0] == cmd
->cmd
[0]) {
66 linenoiseAddCompletion(lc
, cmd
->cmd
);
75 /** @{ Callbacks for Musashi. */
76 uint32_t m68k_read_disassembler_8(unsigned int addr
)
78 return m68k_read_memory_8(addr
);
81 uint32_t m68k_read_disassembler_16(unsigned int addr
)
83 return m68k_read_memory_16(addr
);
86 uint32_t m68k_read_disassembler_32(unsigned int addr
)
88 return m68k_read_memory_32(addr
);
94 * A simple wrapper around strtoul() with error check.
96 * @param[in] str String to convert to number.
97 * @param[out] ret Number "str" represents.
98 * @return -1 on error.
100 static int debug_strtou32(const char *str
, uint32_t *ret
)
105 *ret
= (uint32_t)strtoul(str
, &end
, 0);
119 * Check if at least one M68K breakpoint is set.
121 * @return 1 if true, 0 otherwise.
123 bool md::debug_is_m68k_bp_set()
125 if (debug_bp_m68k
[0].flags
& BP_FLAG_USED
)
132 * Check if at least one Z80 breakpoint is set.
134 * @return 1 if true, 0 otherwise.
136 bool md::debug_is_z80_bp_set()
138 if (debug_bp_z80
[0].flags
& BP_FLAG_USED
)
144 * Check if at least one M68K watchpoint is set.
146 * @return 1 if true, 0 otherwise.
148 bool md::debug_is_m68k_wp_set()
150 if (debug_wp_m68k
[0].flags
& BP_FLAG_USED
)
157 * Check if at least one Z80 watchpoint is set.
159 * @return 1 if true, 0 otherwise.
161 bool md::debug_is_z80_wp_set()
163 if (debug_wp_z80
[0].flags
& BP_FLAG_USED
)
169 * Get the ID of the next free M68K watchpoint.
171 * @return ID or -1 if none free.
173 int md::debug_next_free_wp_m68k()
177 for (i
= 0; i
< MAX_WATCHPOINTS
; i
++) {
178 if (!(debug_wp_m68k
[i
].flags
& WP_FLAG_USED
))
182 return (-1); // no free slots
186 * Get the ID of the next free Z80 watchpoint.
188 * @return ID or -1 if none free.
190 int md::debug_next_free_wp_z80()
194 for (i
= 0; (i
< MAX_WATCHPOINTS
); ++i
)
195 if (!(debug_wp_z80
[i
].flags
& WP_FLAG_USED
))
201 * Get the ID of the next free M68K breakpoint.
203 * @return ID or -1 if none free.
205 int md::debug_next_free_bp_m68k()
209 for (i
= 0; i
< MAX_BREAKPOINTS
; i
++) {
210 if (!(debug_bp_m68k
[i
].flags
& BP_FLAG_USED
))
214 return (-1); // no free slots
219 static BYTE
disz80_read(void *ctx
, WORD addr
)
221 class md
*md
= (class md
*)ctx
;
223 return md
->z80_read(addr
);
229 * Get the ID of the next free Z80 breakpoint.
231 * @return ID or -1 if none free.
233 int md::debug_next_free_bp_z80()
237 for (i
= 0; (i
< MAX_BREAKPOINTS
); ++i
)
238 if (!(debug_bp_z80
[i
].flags
& BP_FLAG_USED
))
244 * Initialise the debugger.
246 * All breakpoints are disabled by default.
248 void md::debug_init()
250 // start with all breakpoints and watchpoints disabled
251 memset(debug_bp_m68k
, 0, sizeof(debug_bp_m68k
));
252 memset(debug_wp_m68k
, 0, sizeof(debug_wp_m68k
));
253 memset(debug_bp_z80
, 0, sizeof(debug_bp_z80
));
254 memset(debug_wp_z80
, 0, sizeof(debug_wp_z80
));
256 #ifndef NO_COMPLETION
257 linenoiseSetCompletionCallback(completion
);
261 debug_trace_m68k
= 0;
264 debug_context
= DBG_CONTEXT_M68K
;
266 debug_m68k_instr_count
= 0;
267 debug_z80_instr_count
= 0;
268 debug_instr_count_enabled
= false;
271 memset(&disz80
, 0, sizeof(disz80
));
272 dZ80_SetDefaultOptions(&disz80
);
273 disz80
.cpuType
= DCPU_Z80
;
274 disz80
.flags
= (DISFLAG_SINGLE
| DISFLAG_CALLBACK
);
275 disz80
.mem0Start
= (BYTE
*)this;
276 disz80
.memCB
= disz80_read
;
281 * Find the index of a M68K breakpoint.
283 * @param addr Address to look for.
284 * @return -1 if no breakpoint is found, otherwise its index in
287 int md::debug_find_bp_m68k(uint32_t addr
)
291 for (i
= 0; i
< MAX_BREAKPOINTS
; i
++) {
293 if (!(debug_bp_m68k
[i
].flags
& BP_FLAG_USED
))
296 if (debug_bp_m68k
[i
].addr
== addr
)
300 return (-1); // not found
304 * Find the index of a Z80 breakpoint.
306 * @param addr Address to look for.
307 * @return -1 if no breakpoint is found, otherwise its index in
310 int md::debug_find_bp_z80(uint16_t addr
)
314 for (i
= 0; (i
< MAX_BREAKPOINTS
); ++i
) {
315 if (!(debug_bp_z80
[i
].flags
& BP_FLAG_USED
))
317 if (debug_bp_z80
[i
].addr
== addr
)
324 * Find the index of a M68K watchpoint by its start address.
326 * @param addr Address to look for.
327 * @return -1 if no watchpoint at the given address, otherwise its index in
330 int md::debug_find_wp_m68k(uint32_t addr
)
334 for (i
= 0; i
< MAX_WATCHPOINTS
; i
++) {
336 if (!(debug_wp_m68k
[i
].flags
& WP_FLAG_USED
))
339 if (debug_wp_m68k
[i
].start_addr
== addr
)
343 return (-1); // not found
347 * Find the index of a Z80 watchpoint by its start address.
349 * @param addr Address to look for.
350 * @return -1 if no watchpoint at the given address, otherwise its index in
353 int md::debug_find_wp_z80(uint16_t addr
)
357 for (i
= 0; (i
< MAX_WATCHPOINTS
); ++i
) {
358 if (!(debug_wp_z80
[i
].flags
& WP_FLAG_USED
))
360 if (debug_wp_z80
[i
].start_addr
== addr
)
367 * Pretty prints hex dump.
369 * @param[in] buf Buffer to pretty print.
370 * @param len Number of bytes to print.
371 * @param addr_label_start The address of the first byte.
373 static void debug_print_hex_buf(
374 unsigned char *buf
, size_t len
, size_t addr_label_start
)
376 uint32_t i
, done
= 0;
378 char ascii
[17], *ap
, *hp
;
380 char hex
[] = "0123456789abcdef";
383 for (i
= 0; i
< 16; i
++) {
384 hp
= strchr(hdr
, '\0');
385 hp
[0] = hex
[(addr_label_start
+ i
) % 16];
392 // process lines of 16 bytes
394 for (i
= 0; i
< len
; i
++, done
++, ap
++) {
400 printf(" |%s|\n", ascii
);
402 printf("0x%08x: ", (uint32_t) addr_label_start
+ i
);
407 // 0x20 to 0x7e is printable ascii
408 if ((byte
>= 0x20) && (byte
<= 0x7e))
413 printf("%02x ", byte
);
416 // make it all line up
418 ascii
[(i
% 16)] = '\0';
426 // print rest of ascii
427 printf(" |%s|\n", ascii
);
432 * Print a M68K watchpoint in a human-readable form.
434 * @param idx Index of watchpoint to print.
436 void md::debug_print_m68k_wp(int idx
)
438 struct dgen_wp
*w
= &(debug_wp_m68k
[idx
]);
440 printf("#%0d:\t0x%08x-%08x (%u bytes)\n", idx
,
441 w
->start_addr
, w
->end_addr
, w
->end_addr
- w
->start_addr
+ 1);
443 debug_print_hex_buf(w
->bytes
, w
->end_addr
- w
->start_addr
+ 1, w
->start_addr
);
448 * Print a Z80 watchpoint in a human-readable form.
450 * @param idx Index of watchpoint to print.
452 void md::debug_print_z80_wp(int idx
)
454 struct dgen_wp
*w
= &debug_wp_z80
[idx
];
456 printf("#%0d:\t0x%04x-%04x (%u bytes)\n", idx
, w
->start_addr
,
457 w
->end_addr
, (w
->end_addr
- w
->start_addr
+ 1));
458 debug_print_hex_buf(w
->bytes
, (w
->end_addr
- w
->start_addr
+ 1),
464 * Check the given M68K watchpoint against cached memory to see if it should
467 * @param[in] w Watch point to check.
468 * @return 1 if true, else 0.
470 int md::debug_should_m68k_wp_fire(struct dgen_wp
*w
)
475 for (i
= w
->start_addr
, p
= w
->bytes
; i
<= w
->end_addr
; i
++, p
++) {
476 if (misc_readbyte(i
) != *p
)
484 * Check the given Z80 watchpoint against cached memory to see if it should
487 * @param[in] w Watch point to check.
488 * @return 1 if true, else 0.
490 int md::debug_should_z80_wp_fire(struct dgen_wp
*w
)
492 unsigned int i
= w
->start_addr
;
493 unsigned char *p
= w
->bytes
;
495 while (i
<= w
->end_addr
)
496 if (z80_read(i
++) != *p
++)
504 * @return Current PC.
506 uint32_t md::m68k_get_pc()
509 return le2h32(m68k_state
.pc
);
515 * @return Current PC.
517 uint16_t md::z80_get_pc()
520 return le2h16(z80_state
.pc
);
524 * Breakpoint handler fired before every M68K instruction.
526 bool md::debug_m68k_check_bps()
528 uint32_t pc
= m68k_get_pc();
532 if (debug_step_m68k
) {
533 if ((--debug_step_m68k
) == 0) {
539 for (i
= 0; (i
< MAX_BREAKPOINTS
); i
++) {
540 if (!(debug_bp_m68k
[i
].flags
& BP_FLAG_USED
))
541 break; // no bps after first disabled one
542 if (pc
== debug_bp_m68k
[i
].addr
) {
543 if (debug_bp_m68k
[i
].flags
& BP_FLAG_FIRED
) {
544 debug_bp_m68k
[i
].flags
&= ~BP_FLAG_FIRED
;
547 debug_bp_m68k
[i
].flags
|= BP_FLAG_FIRED
;
548 printf("m68k breakpoint hit @ 0x%08x\n", pc
);
555 if (debug_trace_m68k
) {
557 debug_print_m68k_disassemble(pc
, 1);
565 * Watchpoint handler fired after every M68K instruction.
567 bool md::debug_m68k_check_wps()
572 for (i
= 0; (i
< MAX_WATCHPOINTS
); i
++) {
573 if (!(debug_wp_m68k
[i
].flags
& BP_FLAG_USED
))
574 break; // no wps after first disabled one
575 if (debug_should_m68k_wp_fire(&(debug_wp_m68k
[i
]))) {
576 printf("m68k watchpoint #%d fired\n", i
);
577 debug_wp_m68k
[i
].flags
|= WP_FLAG_FIRED
;
578 debug_print_m68k_wp(i
);
580 debug_update_fired_m68k_wps();
590 * Breakpoint handler fired before every Z80 instruction.
592 bool md::debug_z80_check_bps()
594 uint16_t pc
= z80_get_pc();
598 if (debug_step_z80
) {
599 if ((--debug_step_z80
) == 0) {
605 for (i
= 0; (i
< MAX_BREAKPOINTS
); i
++) {
606 if (!(debug_bp_z80
[i
].flags
& BP_FLAG_USED
))
607 break; // no bps after first disabled one
608 if (pc
== debug_bp_z80
[i
].addr
) {
609 if (debug_bp_z80
[i
].flags
& BP_FLAG_FIRED
) {
610 debug_bp_z80
[i
].flags
&= ~BP_FLAG_FIRED
;
613 debug_bp_z80
[i
].flags
|= BP_FLAG_FIRED
;
614 printf("z80 breakpoint hit @ 0x%04x\n", pc
);
621 if (debug_trace_z80
) {
623 debug_print_z80_disassemble(pc
, 1);
631 * Watchpoint handler fired after every Z80 instruction.
633 bool md::debug_z80_check_wps()
638 for (i
= 0; (i
< MAX_WATCHPOINTS
); i
++) {
639 if (!(debug_wp_z80
[i
].flags
& BP_FLAG_USED
))
641 if (debug_should_z80_wp_fire(&(debug_wp_z80
[i
]))) {
642 printf("z80 watchpoint #%d fired\n", i
);
643 debug_wp_z80
[i
].flags
|= WP_FLAG_FIRED
;
644 debug_print_z80_wp(i
);
646 debug_update_fired_z80_wps();
656 * Remove a M68K breakpoint.
658 * @param index Index of breakpoint to remove.
660 void md::debug_rm_bp_m68k(int index
)
662 if (!(debug_bp_m68k
[index
].flags
& BP_FLAG_USED
)) {
663 printf("breakpoint not set\n");
668 // shift everything down one
669 if (index
== MAX_BREAKPOINTS
- 1) {
670 debug_bp_m68k
[index
].addr
= 0;
671 debug_bp_m68k
[index
].flags
= 0;
673 memmove(&(debug_bp_m68k
[index
]),
674 &(debug_bp_m68k
[index
+1]),
675 sizeof(struct dgen_bp
) * (MAX_BREAKPOINTS
- index
- 1));
677 debug_bp_m68k
[MAX_BREAKPOINTS
- 1].addr
= 0;
678 debug_bp_m68k
[MAX_BREAKPOINTS
- 1].flags
= 0;
683 * Remove a Z80 breakpoint.
685 * @param index Index of breakpoint to remove.
687 void md::debug_rm_bp_z80(int index
)
689 if (!(debug_bp_z80
[index
].flags
& BP_FLAG_USED
)) {
690 printf("breakpoint not set\n");
694 if (index
== (MAX_BREAKPOINTS
- 1)) {
695 debug_bp_z80
[index
].addr
= 0;
696 debug_bp_z80
[index
].flags
= 0;
699 memmove(&debug_bp_z80
[index
],
700 &debug_bp_z80
[index
+ 1],
701 (sizeof(struct dgen_bp
) *
702 (MAX_BREAKPOINTS
- index
- 1)));
703 debug_bp_z80
[MAX_BREAKPOINTS
- 1].addr
= 0;
704 debug_bp_z80
[MAX_BREAKPOINTS
- 1].flags
= 0;
709 * Remove a M68K watchpoint.
711 * @param index Index of watchpoint to remove.
713 void md::debug_rm_wp_m68k(int index
)
715 if (!(debug_wp_m68k
[index
].flags
& WP_FLAG_USED
)) {
716 printf("watchpoint not set\n");
721 free(debug_wp_m68k
[index
].bytes
);
723 // shift everything down one
724 if (index
== MAX_WATCHPOINTS
- 1) {
725 debug_wp_m68k
[index
].start_addr
= 0;
726 debug_wp_m68k
[index
].flags
= 0;
728 memmove(&(debug_wp_m68k
[index
]),
729 &(debug_wp_m68k
[index
+1]),
730 sizeof(struct dgen_bp
) * (MAX_WATCHPOINTS
- index
- 1));
732 debug_wp_m68k
[MAX_WATCHPOINTS
- 1].start_addr
= 0;
733 debug_wp_m68k
[MAX_WATCHPOINTS
- 1].flags
= 0;
738 * Remove a Z80 watchpoint.
740 * @param index Index of watchpoint to remove.
742 void md::debug_rm_wp_z80(int index
)
744 if (!(debug_wp_z80
[index
].flags
& WP_FLAG_USED
)) {
745 printf("watchpoint not set\n");
749 free(debug_wp_z80
[index
].bytes
);
750 if (index
== (MAX_WATCHPOINTS
- 1)) {
751 debug_wp_z80
[index
].start_addr
= 0;
752 debug_wp_z80
[index
].flags
= 0;
755 memmove(&debug_wp_z80
[index
],
756 &debug_wp_z80
[index
+ 1],
757 (sizeof(struct dgen_bp
) *
758 (MAX_WATCHPOINTS
- index
- 1)));
759 debug_wp_z80
[MAX_WATCHPOINTS
- 1].start_addr
= 0;
760 debug_wp_z80
[MAX_WATCHPOINTS
- 1].flags
= 0;
765 * Pretty print M68K breakpoints.
767 void md::debug_list_bps_m68k()
771 printf("m68k breakpoints:\n");
772 for (i
= 0; i
< MAX_BREAKPOINTS
; i
++) {
773 if (!(debug_bp_m68k
[i
].flags
& BP_FLAG_USED
))
774 break; // can be no more after first disabled bp
776 printf("#%0d:\t0x%08x\n", i
, debug_bp_m68k
[i
].addr
);
780 printf("\tno m68k breakpoints set\n");
785 * Pretty print Z80 breakpoints.
787 void md::debug_list_bps_z80()
791 printf("z80 breakpoints:\n");
792 for (i
= 0; (i
< MAX_BREAKPOINTS
); i
++) {
793 if (!(debug_bp_z80
[i
].flags
& BP_FLAG_USED
))
795 printf("#%0d:\t0x%04x\n", i
, debug_bp_z80
[i
].addr
);
798 printf("\tno z80 breakpoints set\n");
803 * Pretty print M68K watchpoints.
805 void md::debug_list_wps_m68k()
809 printf("m68k watchpoints:\n");
810 for (i
= 0; i
< MAX_WATCHPOINTS
; i
++) {
811 if (!(debug_wp_m68k
[i
].flags
& WP_FLAG_USED
))
812 break; // can be no more after first disabled
813 debug_print_m68k_wp(i
);
817 printf("\tno m68k watchpoints set\n");
822 * Pretty print Z80 watchpoints.
824 void md::debug_list_wps_z80()
828 printf("z80 watchpoints:\n");
829 for (i
= 0; (i
< MAX_WATCHPOINTS
); i
++) {
830 if (!(debug_wp_z80
[i
].flags
& WP_FLAG_USED
))
832 debug_print_z80_wp(i
);
835 printf("\tno z80 watchpoints set\n");
840 * Add a M68K breakpoint.
842 * @param addr Address to break on.
845 int md::debug_set_bp_m68k(uint32_t addr
)
849 if ((debug_find_bp_m68k(addr
)) != -1) {
850 printf("breakpoint already set at this address\n");
854 slot
= debug_next_free_bp_m68k();
856 printf("No space for another break point\n");
860 debug_bp_m68k
[slot
].addr
= addr
;
861 debug_bp_m68k
[slot
].flags
= BP_FLAG_USED
;
862 printf("m68k breakpoint #%d set @ 0x%08x\n", slot
, addr
);
869 * Add a Z80 breakpoint.
871 * @param addr Address to break on.
874 int md::debug_set_bp_z80(uint16_t addr
)
878 if ((debug_find_bp_z80(addr
)) != -1) {
879 printf("breakpoint already set at this address\n");
882 slot
= debug_next_free_bp_z80();
884 printf("No space for another break point\n");
887 debug_bp_z80
[slot
].addr
= addr
;
888 debug_bp_z80
[slot
].flags
= BP_FLAG_USED
;
889 printf("z80 breakpoint #%d set @ 0x%04x\n", slot
, addr
);
896 * Convert a core name to a context ID.
898 * @param[in] arg NUL-terminated core name.
899 * @return Core context ID or -1 on error.
901 static int debug_parse_cpu(char *arg
)
907 for (p
= z80_aliases
; *p
!= NULL
; p
++) {
908 if (strcmp(arg
, *p
) == 0)
909 return (DBG_CONTEXT_Z80
);
912 for (p
= m68k_aliases
; *p
!= NULL
; p
++) {
913 if (strcmp(arg
, *p
) == 0)
914 return (DBG_CONTEXT_M68K
);
917 for (p
= fm_aliases
; *p
!= NULL
; p
++) {
918 if (strcmp(arg
, *p
) == 0)
919 return (DBG_CONTEXT_YM2612
);
922 for (p
= psg_aliases
; *p
!= NULL
; p
++) {
923 if (strcmp(arg
, *p
) == 0)
924 return (DBG_CONTEXT_SN76489
);
928 if ((debug_strtou32(arg
, &num
)) < 0)
931 if (num
> DBG_CONTEXT_SN76489
)
937 // ===[ C++ Methods ]=========================================================
940 * Add a M68K watchpoint to a range of addresses.
942 * @param start_addr Start address of watchpoint range.
943 * @param end_addr End address of watchpoint range.
945 void md::debug_set_wp_m68k(uint32_t start_addr
, uint32_t end_addr
)
949 slot
= debug_next_free_wp_m68k();
951 printf("No space for another watch point\n");
955 debug_wp_m68k
[slot
].start_addr
= start_addr
;
956 debug_wp_m68k
[slot
].end_addr
= end_addr
;
957 debug_wp_m68k
[slot
].flags
= WP_FLAG_USED
;
958 debug_wp_m68k
[slot
].bytes
= (unsigned char *) malloc(end_addr
- start_addr
+ 1);
959 if (debug_wp_m68k
[slot
].bytes
== NULL
) {
964 debug_update_m68k_wp_cache(&(debug_wp_m68k
[slot
]));
966 printf("m68k watchpoint #%d set @ 0x%08x-0x%08x (%u bytes)\n",
967 slot
, start_addr
, end_addr
, end_addr
- start_addr
+ 1);
973 * Update the data pointer of a single M68K watchpoint.
975 * @param w Watchpoint to update.
977 void md::debug_update_m68k_wp_cache(struct dgen_wp
*w
)
983 for (addr
= w
->start_addr
; addr
<= w
->end_addr
; addr
++) {
984 *(p
++) = misc_readbyte(addr
);
989 * Resynchronise all M68K watchpoints based on actual data.
991 void md::debug_update_fired_m68k_wps()
995 for (i
= 0; i
< MAX_WATCHPOINTS
; i
++) {
997 if (!(debug_wp_m68k
[i
].flags
& WP_FLAG_USED
))
1000 if (!(debug_wp_m68k
[i
].flags
& WP_FLAG_FIRED
))
1003 debug_update_m68k_wp_cache(&(debug_wp_m68k
[i
]));
1004 debug_wp_m68k
[i
].flags
&= ~WP_FLAG_FIRED
;
1009 * Add a Z80 watchpoint to a range of addresses.
1011 * @param start_addr Start address of watchpoint range.
1012 * @param end_addr End address of watchpoint range.
1014 void md::debug_set_wp_z80(uint16_t start_addr
, uint16_t end_addr
)
1018 slot
= debug_next_free_wp_z80();
1020 printf("No space for another watch point\n");
1023 debug_wp_z80
[slot
].start_addr
= start_addr
;
1024 debug_wp_z80
[slot
].end_addr
= end_addr
;
1025 debug_wp_z80
[slot
].flags
= WP_FLAG_USED
;
1026 debug_wp_z80
[slot
].bytes
=
1027 (unsigned char *)malloc(end_addr
- start_addr
+ 1);
1028 if (debug_wp_z80
[slot
].bytes
== NULL
) {
1032 debug_update_z80_wp_cache(&(debug_wp_z80
[slot
]));
1033 printf("z80 watchpoint #%d set @ 0x%04x-0x%04x (%u bytes)\n",
1034 slot
, start_addr
, end_addr
, (end_addr
- start_addr
+ 1));
1040 * Update the data pointer of a single Z80 watchpoint.
1042 * @param w Watchpoint to update.
1044 void md::debug_update_z80_wp_cache(struct dgen_wp
*w
)
1047 unsigned char *p
= w
->bytes
;
1049 for (addr
= w
->start_addr
; (addr
<= w
->end_addr
); addr
++)
1050 *(p
++) = z80_read(addr
);
1054 * Resynchronise all Z80 watchpoints based on actual data.
1056 void md::debug_update_fired_z80_wps()
1060 for (i
= 0; (i
< MAX_WATCHPOINTS
); i
++) {
1061 if (!(debug_wp_z80
[i
].flags
& WP_FLAG_USED
))
1063 if (!(debug_wp_z80
[i
].flags
& WP_FLAG_FIRED
))
1065 debug_update_z80_wp_cache(&(debug_wp_z80
[i
]));
1066 debug_wp_z80
[i
].flags
&= ~WP_FLAG_FIRED
;
1071 * Watchpoints (watch) command handler.
1073 * - If n_args == 0 then list watchpoints.
1074 * - If n_args == 1 then add a watchpoint with length 1 with start address
1075 * defined in args[0].
1076 * - If n_args == 2 then add a watch point with start address args[0] and
1079 * @param n_args Number of arguments.
1080 * @param args Arguments, see above.
1083 int md::debug_cmd_watch(int n_args
, char **args
)
1085 uint32_t start
, len
= 1;
1087 if (debug_context
!= DBG_CONTEXT_M68K
){
1088 printf("watchpoints not supported on %s core\n",
1089 CURRENT_DEBUG_CONTEXT_NAME
);
1095 if ((debug_strtou32(args
[1], &len
)) < 0) {
1096 printf("length malformed: %s\n", args
[1]);
1101 if ((debug_strtou32(args
[0], &start
)) < 0) {
1102 printf("address malformed: %s\n", args
[0]);
1105 debug_set_wp_m68k(start
, start
+len
-1); // one byte
1109 debug_list_wps_m68k();
1118 * Pretty print a block of memory as a hex dump.
1120 * @param addr Start address.
1121 * @param len Length (in bytes) to dump.
1123 void md::debug_dump_mem(uint32_t addr
, uint32_t len
)
1128 // we have to make a buffer to pass down
1129 buf
= (unsigned char *) malloc(len
);
1135 for (i
= 0; i
< len
; i
++) {
1136 buf
[i
] = misc_readbyte(addr
+ i
);
1139 debug_print_hex_buf(buf
, len
, addr
);
1144 * Memory dump (mem) command handler.
1146 * - If n_args == 1 then args[0] is start address to dump from for
1147 * DEBUG_DFLT_MEMDUMP_LEN bytes.
1148 * - If n_args == 2 then args[0] is start address and args[1] is number of
1151 * @param n_args Number of arguments.
1152 * @param args Arguments, see above.
1155 int md::debug_cmd_mem(int n_args
, char **args
)
1157 uint32_t addr
, len
= DEBUG_DFLT_MEMDUMP_LEN
;
1159 if (debug_context
!= DBG_CONTEXT_M68K
) {
1160 printf("memory dumping not implemented on %s core\n",
1161 CURRENT_DEBUG_CONTEXT_NAME
);
1166 case 2: /* specified length */
1167 if ((debug_strtou32(args
[1], &len
)) < 0) {
1168 printf("length malformed: %s\n", args
[1]);
1172 case 1: /* default length */
1173 if ((debug_strtou32(args
[0], &addr
)) < 0) {
1174 printf("addr malformed: %s\n", args
[0]);
1178 debug_dump_mem(addr
, len
);
1187 * Memory/registers write (setb/setw/setl/setr) commands handler.
1189 * - args[1] is the numerical value to write to registers/memory.
1190 * - If type == ~0u, args[0] is a register name.
1191 * - If type == 1, args[0] is the address of a byte.
1192 * - If type == 2, args[0] is the address of a word.
1193 * - If type == 4, args[0] is the address of a long word.
1195 * @param n_args Number of arguments (ignored, always 2).
1196 * @param args Arguments, see above.
1197 * @param type Data type to write, see above.
1200 int md::debug_cmd_setbwlr(int n_args
, char **args
, unsigned int type
)
1208 } reg_ptr
= { NULL
};
1209 unsigned int reg
= -1;
1213 assert(n_args
== 2);
1214 if ((debug_context
!= DBG_CONTEXT_M68K
) &&
1215 (debug_context
!= DBG_CONTEXT_Z80
)) {
1216 printf("memory setting not implemented on %s core\n",
1217 CURRENT_DEBUG_CONTEXT_NAME
);
1221 static const struct {
1223 #define REG0(id, idx) { \
1225 ((uintptr_t)&m68k_state.id[idx] - (uintptr_t)&m68k_state), \
1226 sizeof(m68k_state.id[idx]) \
1229 #define REG1(id) { # id, offsetof(m68k_state_t, id), sizeof(m68k_state.id) }
1231 #define REG2(id, idx, name) { \
1233 ((uintptr_t)&z80_state.alt[idx].id - (uintptr_t)&z80_state), \
1234 sizeof(z80_state.alt[idx].id) \
1237 #define REG3(id) { # id, offsetof(z80_state_t, id), sizeof(z80_state.id) }
1245 REG0(a
, 0), REG0(a
, 1), REG0(a
, 2), REG0(a
, 3),
1246 REG0(a
, 4), REG0(a
, 5), REG0(a
, 6), REG0(a
, 7),
1247 REG0(d
, 0), REG0(d
, 1), REG0(d
, 2), REG0(d
, 3),
1248 REG0(d
, 4), REG0(d
, 5), REG0(d
, 6), REG0(d
, 7),
1253 REG2(fa
, 0, "af"), REG2(fa
, 1, "af'"),
1254 REG2(cb
, 0, "bc"), REG2(cb
, 1, "bc'"),
1255 REG2(ed
, 0, "de"), REG2(ed
, 1, "de'"),
1256 REG2(lh
, 0, "hl"), REG2(lh
, 1, "hl'"),
1257 REG3(ix
), REG3(iy
), REG3(sp
), REG3(pc
),
1258 REG3(r
), REG3(i
), REG3(iff
), REG3(im
)
1264 if (debug_context
== DBG_CONTEXT_M68K
) {
1266 state
= (uint8_t *)&m68k_state
;
1268 else if (debug_context
== DBG_CONTEXT_Z80
) {
1270 state
= (uint8_t *)&z80_state
;
1275 (addr
!= (sizeof(regid
[idx
]) / sizeof(regid
[idx
][0])));
1277 if (regid
[idx
][addr
].name
== NULL
)
1279 if (strcasecmp(regid
[idx
][addr
].name
, args
[0]))
1282 (void *)(state
+ regid
[idx
][addr
].offset
);
1283 reg
= regid
[idx
][addr
].size
;
1287 printf("unknown register %s\n", args
[0]);
1291 else if (debug_strtou32(args
[0], &addr
) < 0) {
1292 printf("addr malformed: %s\n", args
[0]);
1295 if (debug_strtou32(args
[1], &val
) < 0) {
1296 printf("value malformed: %s\n", args
[1]);
1302 misc_writebyte(addr
, val
);
1306 misc_writeword(addr
, val
);
1310 misc_writeword(addr
, ((val
>> 16) & 0xffff));
1311 misc_writeword((addr
+ 2), (val
& 0xffff));
1318 *reg_ptr
.r16
= le2h16(val
);
1320 *reg_ptr
.r32
= le2h32(val
);
1323 m68k_state_restore();
1324 z80_state_restore();
1327 printf("unknown type size %u\n", type
);
1335 * Set byte (setb) command handler, see debug_cmd_setbwlr().
1339 int md::debug_cmd_setb(int n_args
, char **args
)
1341 return debug_cmd_setbwlr(n_args
, args
, 1);
1345 * Set word (setw) command handler, see debug_cmd_setbwlr().
1349 int md::debug_cmd_setw(int n_args
, char **args
)
1351 return debug_cmd_setbwlr(n_args
, args
, 2);
1355 * Set long word (setl) command handler, see debug_cmd_setbwlr().
1359 int md::debug_cmd_setl(int n_args
, char **args
)
1361 return debug_cmd_setbwlr(n_args
, args
, 4);
1365 * Set register (setr) command handler, see debug_cmd_setbwlr().
1369 int md::debug_cmd_setr(int n_args
, char **args
)
1371 return debug_cmd_setbwlr(n_args
, args
, ~0u);
1375 * Disassemble (dis) command handler.
1377 * - If n_args == 0, do nothing.
1378 * - If n_args == 1 start disassembling from address args[0] for
1379 * DEBUG_DFLT_DASM_LEN instructions.
1380 * - If n_args == 2 start disassembling from address args[0] for args[1]
1383 * @param n_args Number of arguments.
1384 * @param[in] args Arguments list.
1387 int md::debug_cmd_dis(int n_args
, char **args
)
1390 uint32_t length
= DEBUG_DFLT_DASM_LEN
;
1392 if (debug_context
== DBG_CONTEXT_M68K
)
1393 addr
= m68k_get_pc();
1394 else if (debug_context
== DBG_CONTEXT_Z80
)
1395 addr
= z80_get_pc();
1397 printf("disassembly is not implemented on %s core\n",
1398 CURRENT_DEBUG_CONTEXT_NAME
);
1407 if ((debug_strtou32(args
[1], &length
)) < 0) {
1408 printf("length malformed: %s\n", args
[1]);
1413 if ((debug_strtou32(args
[0], &addr
)) < 0) {
1414 printf("address malformed: %s\n", args
[0]);
1420 if (debug_context
== DBG_CONTEXT_M68K
)
1421 debug_print_m68k_disassemble(addr
, length
);
1422 else if (debug_context
== DBG_CONTEXT_Z80
)
1423 debug_print_z80_disassemble(addr
, length
);
1430 * Continue (cont) command handler. This command drops out of debug mode.
1432 * @param n_args Number of arguments (ignored).
1433 * @param args Arguments (ignored).
1434 * @return Always 0 (debugger should exit).
1436 int md::debug_cmd_cont(int n_args
, char **args
)
1442 return (0); // causes debugger to exit
1446 * Pretty print the M68K registers using m68k_state from class md.
1448 void md::debug_show_m68k_regs()
1454 sr
= le2h16(m68k_state
.sr
);
1456 if (debug_instr_count_enabled
)
1457 printf("m68k (%lu instructions):\n", debug_m68k_instr_count
);
1461 printf("\tpc:\t0x%08x\n\tsr:\t0x%08x\n", le2h32(m68k_state
.pc
), sr
);
1463 // print SR register - user byte
1464 printf("\t user sr : <X=%u, N=%u, Z=%u, V=%u, C=%u>\n",
1465 (sr
& M68K_SR_EXTEND
) ? 1 : 0,
1466 (sr
& M68K_SR_NEGATIVE
) ? 1 : 0,
1467 (sr
& M68K_SR_ZERO
) ? 1 : 0,
1468 (sr
& M68K_SR_OVERFLOW
) ? 1 : 0,
1469 (sr
& M68K_SR_CARRY
) ? 1 : 0);
1471 // print SR register - system byte
1472 printf("\t sys sr : <TE=%u%u, SUS=%u, MIS=%u, IPM=%u%u%u>\n",
1473 (sr
& M68K_SR_TRACE_EN1
) ? 1 : 0,
1474 (sr
& M68K_SR_TRACE_EN2
) ? 1 : 0,
1475 (sr
& M68K_SR_SUP_STATE
) ? 1 : 0,
1476 (sr
& M68K_SR_MI_STATE
) ? 1 : 0,
1477 (sr
& M68K_SR_IP_MASK1
) ? 1 : 0,
1478 (sr
& M68K_SR_IP_MASK2
) ? 1 : 0,
1479 (sr
& M68K_SR_IP_MASK3
) ? 1 : 0);
1482 for (i
= 0; i
< 8; i
++)
1483 printf("\td%d:\t0x%08x\n", i
, le2h32(m68k_state
.d
[i
]));
1485 for (i
= 0; i
< 8; i
++)
1486 printf("\ta%d:\t0x%08x\n", i
, le2h32(m68k_state
.a
[i
]));
1490 #define PRINT_Z80_FLAGS(x) \
1491 printf("\t <S=%u, Z= %u, H=%u, P/V=%u, N=%u, C=%u>\n", \
1492 (x & Z80_SR_SIGN) ? 1 : 0, \
1493 (x & Z80_SR_ZERO) ? 1 : 0, \
1494 (x & Z80_SR_HALF_CARRY) ? 1 : 0, \
1495 (x & Z80_SR_PARITY_OVERFLOW) ? 1 : 0, \
1496 (x & Z80_SR_ADD_SUB) ? 1 : 0, \
1497 (x & Z80_SR_CARRY) ? 1 : 0);
1499 * Pretty print Z80 registers using z80_state from class md.
1501 void md::debug_show_z80_regs()
1508 for (i
= 0; i
< 2; i
++) {
1509 const char *alt
= (i
? "'" : "");
1511 printf("\t af%s:\t0x%04x\n",
1512 alt
, le2h16(z80_state
.alt
[i
].fa
));
1513 PRINT_Z80_FLAGS(z80_state
.alt
[i
].fa
>> 1);
1514 printf("\t bc%s:\t0x%04x\n"
1515 "\t de%s:\t0x%04x\n"
1516 "\t hl%s:\t0x%04x\n",
1517 alt
, le2h16(z80_state
.alt
[i
].cb
),
1518 alt
, le2h16(z80_state
.alt
[i
].ed
),
1519 alt
, le2h16(z80_state
.alt
[i
].lh
));
1522 printf("\t ix:\t0x%04x\n"
1530 le2h16(z80_state
.ix
),
1531 le2h16(z80_state
.iy
),
1532 le2h16(z80_state
.sp
),
1533 le2h16(z80_state
.pc
),
1542 * Help (help) command handler.
1544 * @param n_args Number of arguments (ignored).
1545 * @param args List of arguments (ignored).
1548 int md::debug_cmd_help(int n_args
, char **args
)
1553 printf("commands:\n"
1554 "\tC/cpu <cpu>\t\tswitch to cpu context\n"
1555 "\t-b/-break <#num/addr>\tremove breakpoint for current cpu\n"
1556 "\tb/break <addr>\t\tset breakpoint for current cpu\n"
1557 "\tb/break\t\t\tshow breakpoints for current cpu\n"
1558 "\tc/cont\t\t\texit debugger and continue execution\n"
1559 "\td/dis <addr> <num>\tdisasm 'num' instrs starting at 'addr'\n"
1560 "\td/dis <addr>\t\tdisasm %u instrs starting at 'addr'\n"
1561 "\td/dis\t\t\tdisasm %u instrs starting at the current instr\n"
1562 "\tm/mem <addr> <len>\tdump 'len' bytes of memory at 'addr'\n"
1563 "\tm/mem <addr>\t\tdump %u bytes of memory at 'addr'\n"
1564 "\tset/setb <addr> <val>\twrite byte 'val' to memory at 'addr'\n"
1565 "\tsetw <addr> <val>\twrite word 'val' to memory at 'addr'\n"
1566 "\tsetl <addr> <val>\twrite long 'val' to memory at 'addr'\n"
1567 "\tsetr <reg> <val>\twrite 'val' to register 'reg'\n"
1568 "\th/help/?\t\tshow this message\n"
1569 "\tr/reg\t\t\tshow registers of current cpu\n"
1570 "\tcount\t\t\ttoggle instructions counters\n"
1571 "\ts/step\t\t\tstep one instruction\n"
1572 "\ts/step <num>\t\tstep 'num' instructions\n"
1573 "\tt/trace [bool|num]\ttoggle instructions tracing\n"
1574 "\t-w/-watch <#num/addr>\tremove watchpoint for current cpu\n"
1575 "\tw/watch <addr> <len>\tset multi-byte watchpoint for current cpu\n"
1576 "\tw/watch <addr>\t\tset 1-byte watchpoint for current cpu\n"
1577 "\tw/watch\t\t\tshow watchpoints for current cpu\n"
1578 "\ncpu names/numbers:\n"
1579 "\t'm68k', 'm', '68000', 'm68000' or '%d' refers to the main m68000 chip\n"
1580 "\t'z80', 'z' or '%d' refers to the secondary z80 chip\n"
1581 "\t'ym', 'fm', 'ym2612' or '%d' refers to the fm2616 sound chip\n"
1582 "\t'sn', 'sn76489', 'psg' or '%d' refers to the sn76489 sound chip\n",
1583 DEBUG_DFLT_DASM_LEN
, DEBUG_DFLT_DASM_LEN
, DEBUG_DFLT_MEMDUMP_LEN
,
1584 DBG_CONTEXT_M68K
, DBG_CONTEXT_Z80
, DBG_CONTEXT_YM2612
, DBG_CONTEXT_SN76489
);
1590 * Dump registers (reg) command handler.
1591 * This command pretty prints registers for the current context.
1593 * @param n_args Number of arguments (ignored).
1594 * @param[in] args List of arguments (ignored).
1597 int md::debug_cmd_reg(int n_args
, char **args
)
1602 switch (debug_context
) {
1603 case DBG_CONTEXT_M68K
:
1604 debug_show_m68k_regs();
1606 case DBG_CONTEXT_Z80
:
1607 debug_show_z80_regs();
1609 case DBG_CONTEXT_YM2612
:
1610 debug_show_ym2612_regs();
1613 printf("register dump not implemented on %s core\n",
1614 CURRENT_DEBUG_CONTEXT_NAME
);
1622 * Instructions counters toggle (count) command handler.
1624 * - If n_args == 0, toggle (enable/disable) instructions counters.
1625 * - If n_args == 1 and args[0] is a boolean string, toggle instructions
1626 * counters accordingly.
1628 * @param n_args Number of arguments.
1629 * @param args Arguments.
1632 int md::debug_cmd_count(int n_args
, char **args
)
1634 static const struct {
1638 { "true", true }, { "false", false },
1639 { "yes", true }, { "no", false },
1640 { "on", true }, { "off", false },
1641 { "enable", true }, { "disable", false }
1647 for (i
= 0; (i
!= (sizeof(opt
) / sizeof(opt
[0]))); ++i
)
1648 if (!strcasecmp(args
[0], opt
[i
].param
)) {
1649 debug_instr_count_enabled
= opt
[i
].value
;
1652 if (i
== (sizeof(opt
) / sizeof(opt
[0]))) {
1653 if (debug_strtou32(args
[0], &i
) == -1) {
1654 printf("invalid argument: %s\n", args
[0]);
1657 debug_instr_count_enabled
= !!i
;
1661 debug_instr_count_enabled
= !debug_instr_count_enabled
;
1662 printf("instructions counters ");
1663 if (!debug_instr_count_enabled
)
1664 printf("disabled.\n");
1666 debug_m68k_instr_count
= 0;
1667 debug_z80_instr_count
= 0;
1668 printf("enabled.\n");
1676 * Breakpoint (break) command handler.
1678 * - If n_args == 0, list breakpoints.
1679 * - If n_args == 1, set a breakpoint at address args[0].
1681 * @param n_args Number of arguments.
1682 * @param[in] args List of arguments.
1685 int md::debug_cmd_break(int n_args
, char **args
)
1689 if ((debug_context
!= DBG_CONTEXT_M68K
) &&
1690 (debug_context
!= DBG_CONTEXT_Z80
)) {
1691 printf("breakpoints are not supported on %s\n",
1692 CURRENT_DEBUG_CONTEXT_NAME
);
1699 if ((debug_strtou32(args
[0], &num
)) < 0) {
1700 printf("address malformed: %s\n", args
[0]);
1703 if (debug_context
== DBG_CONTEXT_M68K
)
1704 debug_set_bp_m68k(num
);
1705 else if (debug_context
== DBG_CONTEXT_Z80
)
1706 debug_set_bp_z80(num
);
1710 if (debug_context
== DBG_CONTEXT_M68K
)
1711 debug_list_bps_m68k();
1712 else if (debug_context
== DBG_CONTEXT_Z80
)
1713 debug_list_bps_z80();
1722 * Quit (quit) command handler.
1723 * This command makes DGen/SDL quit.
1725 * @param n_args Number of arguments (ignored).
1726 * @param args List of arguments (ignored).
1727 * @return Always -1.
1729 int md::debug_cmd_quit(int n_args
, char **args
)
1738 * Core/CPU selection (cpu) command.
1739 * Switch to the core/CPU given in args[0].
1741 * @param n_args Number of arguments (should always be 1).
1742 * @param args List of arguments.
1745 int md::debug_cmd_cpu(int n_args
, char **args
)
1751 ctx
= debug_parse_cpu(args
[0]);
1753 printf("unknown cpu: %s\n", args
[0]);
1757 debug_context
= ctx
;
1764 * Step (step) command handler for the current core.
1766 * - If n_args == 0, step one instruction.
1767 * - If n_args == 1, step args[0] instructions.
1769 * @param n_args Number of arguments.
1770 * @param args List of arguments.
1771 * @return 0 if execution should continue, 1 otherwise.
1773 int md::debug_cmd_step(int n_args
, char **args
)
1777 if ((n_args
>= 1) && (debug_strtou32(args
[0], &num
) < 0)) {
1778 printf("malformed number: %s\n", args
[0]);
1781 if (debug_context
== DBG_CONTEXT_M68K
)
1782 debug_step_m68k
= (num
+ 1); /* triggered when 0 */
1783 else if (debug_context
== DBG_CONTEXT_Z80
)
1784 debug_step_z80
= (num
+ 1);
1786 printf("stepping not supported on %s\n",
1787 CURRENT_DEBUG_CONTEXT_NAME
);
1792 return (0); // continue executing
1799 * Trace toggle (trace) command handler.
1801 * - If n_args == 0, toggle (enable/disable) instructions tracing permanently.
1802 * - If n_args == 1 and args[0] is a number, enable instructions tracing for
1803 * this number of instructions.
1804 * - If n_args == 1 and args[0] is a boolean string, toggle instructions
1805 * tracing accordingly.
1807 * @param n_args Number of arguments.
1808 * @param args Arguments.
1811 int md::debug_cmd_trace(int n_args
, char **args
)
1813 static const struct {
1817 { "true", ~0u }, { "false", 0 },
1818 { "yes", ~0u }, { "no", 0 },
1819 { "on", ~0u }, { "off", 0 },
1820 { "enable", ~0u }, { "disable", 0 }
1822 unsigned int *which
;
1824 if ((which
= &debug_trace_m68k
, debug_context
!= DBG_CONTEXT_M68K
) &&
1825 (which
= &debug_trace_z80
, debug_context
!= DBG_CONTEXT_Z80
)) {
1826 printf("instructions tracing not supported on %s\n",
1827 CURRENT_DEBUG_CONTEXT_NAME
);
1833 for (i
= 0; (i
!= (sizeof(opt
) / sizeof(opt
[0]))); ++i
)
1834 if (!strcasecmp(args
[0], opt
[i
].param
)) {
1835 *which
= opt
[i
].value
;
1838 if (i
== (sizeof(opt
) / sizeof(opt
[0]))) {
1839 if (debug_strtou32(args
[0], &i
) == -1) {
1840 printf("invalid argument: %s\n", args
[0]);
1847 *which
= (!*which
* ~0u);
1848 printf("instructions tracing ");
1851 printf("disabled.\n");
1854 printf("enabled permanently.\n");
1857 printf("enabled for the next %u instruction(s).\n", *which
);
1866 * Watchpoint removal (-watch) command handler.
1868 * If args[0] starts with a #, remove a watchpoint by ID. Otherwise, remove
1871 * @param n_args Number of arguments (always 1).
1872 * @param[in] args List of arguments.
1875 int md::debug_cmd_minus_watch(int n_args
, char **args
)
1882 if ((debug_context
!= DBG_CONTEXT_M68K
) &&
1883 (debug_context
!= DBG_CONTEXT_Z80
)) {
1884 printf("watchpoints not supported on %s\n",
1885 CURRENT_DEBUG_CONTEXT_NAME
);
1889 if (args
[0][0] == '#') { // remove by index
1891 if (strlen(args
[0]) < 2) {
1892 printf("parse error\n");
1896 if ((debug_strtou32(args
[0]+1, &num
)) < 0) {
1897 printf("address malformed: %s\n", args
[0]);
1902 if ((index
< 0) || (index
>= MAX_BREAKPOINTS
)) {
1903 printf("breakpoint out of range\n");
1906 } else { // remove by address
1907 if ((debug_strtou32(args
[0], &num
)) < 0) {
1908 printf("address malformed: %s\n", args
[0]);
1911 if (debug_context
== DBG_CONTEXT_M68K
)
1912 index
= debug_find_wp_m68k(num
);
1913 else if (debug_context
== DBG_CONTEXT_Z80
)
1914 index
= debug_find_wp_z80(num
);
1916 if (debug_context
== DBG_CONTEXT_M68K
)
1917 debug_rm_wp_m68k(index
);
1918 else if (debug_context
== DBG_CONTEXT_Z80
)
1919 debug_rm_wp_z80(index
);
1927 * Breakpoint removal (-break) command handler.
1929 * If args[0] starts with a #, remove a breakpoint by ID. Otherwise, remove
1932 * @param n_args Number of arguments (always 1).
1933 * @param args List of arguments.
1936 int md::debug_cmd_minus_break(int n_args
, char **args
)
1943 if ((debug_context
!= DBG_CONTEXT_M68K
) &&
1944 (debug_context
!= DBG_CONTEXT_Z80
)) {
1945 printf("breakpoints not supported on %s\n",
1946 CURRENT_DEBUG_CONTEXT_NAME
);
1950 if (args
[0][0] == '#') { // remove by index
1952 if (strlen(args
[0]) < 2) {
1953 printf("parse error\n");
1957 if ((debug_strtou32(args
[0]+1, &num
)) < 0) {
1958 printf("address malformed: %s\n", args
[0]);
1963 if ((index
< 0) || (index
>= MAX_BREAKPOINTS
)) {
1964 printf("breakpoint out of range\n");
1968 } else { // remove by address
1969 if ((debug_strtou32(args
[0], &num
)) < 0) {
1970 printf("address malformed: %s\n", args
[0]);
1973 if (debug_context
== DBG_CONTEXT_M68K
)
1974 index
= debug_find_bp_m68k(num
);
1975 else if (debug_context
== DBG_CONTEXT_Z80
)
1976 index
= debug_find_bp_z80(num
);
1978 printf("no breakpoint here: %s\n", args
[0]);
1982 // we now have an index into our bp array
1983 if (debug_context
== DBG_CONTEXT_M68K
)
1984 debug_rm_bp_m68k(index
);
1985 else if (debug_context
== DBG_CONTEXT_Z80
)
1986 debug_rm_bp_z80(index
);
1993 * Dispatch a command to the relevant handler method.
1995 * @param n_toks Number of tokens (arguments).
1996 * @param toks List of tokens (arguments).
1997 * @return 1 if n_toks is 0, otherwise the command handler's return value.
1999 int md::debug_despatch_cmd(int n_toks
, char **toks
)
2002 struct md::dgen_debugger_cmd
*d
= (struct md::dgen_debugger_cmd
*)
2003 md::debug_cmd_list
, *found
= NULL
;
2007 while (d
->cmd
!= NULL
) {
2008 if ((strcmp(toks
[0], d
->cmd
) == 0) && (n_toks
-1 == d
->n_args
)) {
2015 if (found
== NULL
) {
2016 printf("unknown command/wrong argument count (type '?' for help)\n");
2021 // all is well, call
2022 return ((this->*found
->handler
)(n_toks
-1, &toks
[1]));
2025 #define MAX_DISASM 128
2027 * Pretty print a M68K disassembly.
2029 * @param from Address to start disassembling from.
2030 * @param len Number of instructions to disassemble.
2032 void md::debug_print_m68k_disassemble(uint32_t from
, int len
)
2036 char disasm
[MAX_DISASM
];
2038 md_set_musa(1); // assign static in md:: so C can get at it (HACK)
2039 for (i
= 0; i
< len
; i
++) {
2042 sz
= m68k_disassemble(disasm
, from
, M68K_CPU_TYPE_68040
);
2043 printf(" 0x%06x: %s\n", from
, disasm
);
2049 printf(" 0x%06x: %02x %02x [...]\n", from
,
2050 misc_readbyte(from
), misc_readbyte(from
+ 1));
2056 * Pretty print a Z80 disassembly.
2058 * @param from Address to start disassembling from.
2059 * @param num Number of instructions to disassemble.
2061 void md::debug_print_z80_disassemble(uint16_t from
, unsigned int num
)
2066 for (i
= 0; (i
< num
); ++i
) {
2069 disz80
.start
= from
;
2071 err
= dZ80_Disassemble(&disz80
);
2072 if (err
!= DERR_NONE
)
2073 printf(" 0x%04x: ??? error: %s\n",
2074 from
, dZ80_GetErrorText(err
));
2076 printf(" 0x%04x: %8s %s\n",
2077 from
, disz80
.hexDisBuf
, disz80
.disBuf
);
2078 from
+= disz80
.bytesProcessed
;
2082 printf(" 0x%04x: %02x [...]\n", from
, z80_read(from
));
2090 void md::debug_leave()
2092 if (debug_trap
== false)
2094 linenoise_nb_clean();
2099 * Enter debugger and show command prompt.
2101 int md::debug_enter()
2103 char *cmd
, prompt
[32];
2105 char *toks
[MAX_DEBUG_TOKS
];
2107 uint32_t m68k_pc
= m68k_get_pc();
2108 uint16_t z80_pc
= z80_get_pc();
2111 if (debug_trap
== false) {
2112 pd_message("Debug trap.");
2115 if (debug_context
== DBG_CONTEXT_M68K
)
2116 debug_print_m68k_disassemble(m68k_pc
, 1);
2117 else if (debug_context
== DBG_CONTEXT_Z80
)
2118 debug_print_z80_disassemble(z80_pc
, 1);
2121 switch (debug_context
) {
2122 case DBG_CONTEXT_M68K
:
2123 snprintf(prompt
, sizeof(prompt
), "m68k:0x%08x> ", m68k_pc
);
2125 case DBG_CONTEXT_Z80
:
2126 snprintf(prompt
, sizeof(prompt
), "z80:0x%04x> ", z80_pc
);
2128 case DBG_CONTEXT_YM2612
:
2129 snprintf(prompt
, sizeof(prompt
), "ym2612> ");
2131 case DBG_CONTEXT_SN76489
:
2132 snprintf(prompt
, sizeof(prompt
), "sn76489> ");
2135 printf("unknown cpu. should not happen\n");
2140 if ((cmd
= linenoise_nb(prompt
)) == NULL
) {
2141 if (!linenoise_nb_eol())
2143 linenoise_nb_clean();
2147 linenoiseHistoryAdd((const char *)cmd
);
2152 while ((n_toks
< MAX_DEBUG_TOKS
) &&
2153 ((p
= strtok(next
, " \t")) != NULL
)) {
2158 ret
= debug_despatch_cmd(n_toks
, toks
);
2167 const struct md::dgen_debugger_cmd
md::debug_cmd_list
[] = {
2169 {(char *) "break", 1, &md::debug_cmd_break
},
2170 {(char *) "b", 1, &md::debug_cmd_break
},
2171 {(char *) "break", 0, &md::debug_cmd_break
},
2172 {(char *) "b", 0, &md::debug_cmd_break
},
2173 {(char *) "-break", 1, &md::debug_cmd_minus_break
},
2174 {(char *) "-b", 1, &md::debug_cmd_minus_break
},
2175 // switch debug context
2176 {(char *) "C", 1, &md::debug_cmd_cpu
},
2177 {(char *) "cpu", 1, &md::debug_cmd_cpu
},
2178 // continue emulation
2179 {(char *) "cont", 0, &md::debug_cmd_cont
},
2180 {(char *) "c", 0, &md::debug_cmd_cont
},
2182 {(char *) "dis", 0, &md::debug_cmd_dis
},
2183 {(char *) "d", 0, &md::debug_cmd_dis
},
2184 {(char *) "dis", 1, &md::debug_cmd_dis
},
2185 {(char *) "d", 1, &md::debug_cmd_dis
},
2186 {(char *) "dis", 2, &md::debug_cmd_dis
},
2187 {(char *) "d", 2, &md::debug_cmd_dis
},
2189 {(char *) "help", 0, &md::debug_cmd_help
},
2190 {(char *) "h", 0, &md::debug_cmd_help
},
2191 {(char *) "?", 0, &md::debug_cmd_help
},
2193 {(char *) "m", 1, &md::debug_cmd_mem
},
2194 {(char *) "mem", 1, &md::debug_cmd_mem
},
2195 {(char *) "m", 2, &md::debug_cmd_mem
},
2196 {(char *) "mem", 2, &md::debug_cmd_mem
},
2197 {(char *) "set", 2, &md::debug_cmd_setb
},
2198 {(char *) "setb", 2, &md::debug_cmd_setb
},
2199 {(char *) "setw", 2, &md::debug_cmd_setw
},
2200 {(char *) "setl", 2, &md::debug_cmd_setl
},
2201 {(char *) "setr", 2, &md::debug_cmd_setr
},
2203 {(char *) "quit", 0, &md::debug_cmd_quit
},
2204 {(char *) "q", 0, &md::debug_cmd_quit
},
2205 {(char *) "exit", 0, &md::debug_cmd_quit
},
2206 {(char *) "e", 0, &md::debug_cmd_quit
},
2208 {(char *) "reg", 0, &md::debug_cmd_reg
},
2209 {(char *) "r", 0, &md::debug_cmd_reg
},
2210 {(char *) "count", 1, &md::debug_cmd_count
},
2211 {(char *) "count", 0, &md::debug_cmd_count
},
2213 {(char *) "step", 1, &md::debug_cmd_step
},
2214 {(char *) "s", 1, &md::debug_cmd_step
},
2215 {(char *) "step", 0, &md::debug_cmd_step
},
2216 {(char *) "s", 0, &md::debug_cmd_step
},
2217 {(char *) "trace", 1, &md::debug_cmd_trace
},
2218 {(char *) "t", 1, &md::debug_cmd_trace
},
2219 {(char *) "trace", 0, &md::debug_cmd_trace
},
2220 {(char *) "t", 0, &md::debug_cmd_trace
},
2222 {(char *) "watch", 2, &md::debug_cmd_watch
},
2223 {(char *) "w", 2, &md::debug_cmd_watch
},
2224 {(char *) "watch", 1, &md::debug_cmd_watch
},
2225 {(char *) "w", 1, &md::debug_cmd_watch
},
2226 {(char *) "watch", 0, &md::debug_cmd_watch
},
2227 {(char *) "w", 0, &md::debug_cmd_watch
},
2228 {(char *) "-watch", 1, &md::debug_cmd_minus_watch
},
2229 {(char *) "-w", 1, &md::debug_cmd_minus_watch
},