1 // DGen
2 // Tooling to help debug.
3 // (C) 2012 Edd Barrett <vext01@gmail.com>
4 
5 #include <errno.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdint.h>
11 #include <assert.h>
12 
13 #ifdef WITH_MUSA
14 extern "C" {
15 #include "musa/m68k.h"
16 }
17 #endif
18 
19 #ifdef WITH_DZ80
20 #include "dz80/types.h"
21 #include "dz80/dissz80.h"
22 #endif
23 
24 #include "pd.h"
25 #include "md.h"
26 #include "system.h"
27 #include "debug.h"
28 #include "linenoise/linenoise.h"
29 
30 static const char *debug_context_names[] = {
31 	"M68K", "Z80", "YM2612", "SN76489"
32 };
33 
34 /**
35  * Aliases for the various cores.
36  * @{
37  */
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};
46 /** @} */
47 
48 #define CURRENT_DEBUG_CONTEXT_NAME	debug_context_names[debug_context]
49 
50 // ===[ C Functions ]=========================================================
51 
52 /**
53  * Linenoise completion callback.
54  *
55  * @param buf String so far.
56  * @param lc List of linenoise completions.
57  */
58 #ifndef NO_COMPLETION
completion(const char * buf,linenoiseCompletions * lc)59 void completion(const char *buf, linenoiseCompletions *lc) {
60 
61 	const struct md::dgen_debugger_cmd	*cmd = md::debug_cmd_list;
62 
63 	while (cmd->cmd != NULL) {
64 		if (strlen(cmd->cmd) != 1) {
65 			if (buf[0] == cmd->cmd[0]) {
66 				linenoiseAddCompletion(lc, cmd->cmd);
67 			}
68 		}
69 		cmd++;
70 	}
71 }
72 #endif
73 
74 #ifdef WITH_MUSA
75 /** @{ Callbacks for Musashi. */
m68k_read_disassembler_8(unsigned int addr)76 uint32_t m68k_read_disassembler_8(unsigned int addr)
77 {
78 	    return m68k_read_memory_8(addr);
79 }
80 
m68k_read_disassembler_16(unsigned int addr)81 uint32_t m68k_read_disassembler_16(unsigned int addr)
82 {
83 	    return m68k_read_memory_16(addr);
84 }
85 
m68k_read_disassembler_32(unsigned int addr)86 uint32_t m68k_read_disassembler_32(unsigned int addr)
87 {
88 	    return m68k_read_memory_32(addr);
89 }
90 /** @} */
91 #endif
92 
93 /**
94  * A simple wrapper around strtoul() with error check.
95  *
96  * @param[in] str String to convert to number.
97  * @param[out] ret Number "str" represents.
98  * @return -1 on error.
99  */
debug_strtou32(const char * str,uint32_t * ret)100 static int debug_strtou32(const char *str, uint32_t *ret)
101 {
102 	char			*end = NULL;
103 
104 	errno = 0;
105 	*ret = (uint32_t)strtoul(str, &end, 0);
106 
107 	if (errno) {
108 		perror("strtoul");
109 		return (-1);
110 	}
111 
112 	if (end == str)
113 		return (-1);
114 
115 	return (0);
116 }
117 
118 /**
119  * Check if at least one M68K breakpoint is set.
120  *
121  * @return 1 if true, 0 otherwise.
122  */
debug_is_m68k_bp_set()123 bool md::debug_is_m68k_bp_set()
124 {
125 	if (debug_bp_m68k[0].flags & BP_FLAG_USED)
126 		return (1);
127 
128 	return (0);
129 }
130 
131 /**
132  * Check if at least one Z80 breakpoint is set.
133  *
134  * @return 1 if true, 0 otherwise.
135  */
debug_is_z80_bp_set()136 bool md::debug_is_z80_bp_set()
137 {
138 	if (debug_bp_z80[0].flags & BP_FLAG_USED)
139 		return 1;
140 	return 0;
141 }
142 
143 /**
144  * Check if at least one M68K watchpoint is set.
145  *
146  * @return 1 if true, 0 otherwise.
147  */
debug_is_m68k_wp_set()148 bool md::debug_is_m68k_wp_set()
149 {
150 	if (debug_wp_m68k[0].flags & BP_FLAG_USED)
151 		return (1);
152 
153 	return (0);
154 }
155 
156 /**
157  * Check if at least one Z80 watchpoint is set.
158  *
159  * @return 1 if true, 0 otherwise.
160  */
debug_is_z80_wp_set()161 bool md::debug_is_z80_wp_set()
162 {
163 	if (debug_wp_z80[0].flags & BP_FLAG_USED)
164 		return 1;
165 	return 0;
166 }
167 
168 /**
169  * Get the ID of the next free M68K watchpoint.
170  *
171  * @return ID or -1 if none free.
172  */
debug_next_free_wp_m68k()173 int md::debug_next_free_wp_m68k()
174 {
175 	int			i;
176 
177 	for (i = 0; i < MAX_WATCHPOINTS; i++) {
178 		if (!(debug_wp_m68k[i].flags & WP_FLAG_USED))
179 			return (i);
180 	}
181 
182 	return (-1); // no free slots
183 }
184 
185 /**
186  * Get the ID of the next free Z80 watchpoint.
187  *
188  * @return ID or -1 if none free.
189  */
debug_next_free_wp_z80()190 int md::debug_next_free_wp_z80()
191 {
192 	unsigned int i;
193 
194 	for (i = 0; (i < MAX_WATCHPOINTS); ++i)
195 		if (!(debug_wp_z80[i].flags & WP_FLAG_USED))
196 			return i;
197 	return -1;
198 }
199 
200 /**
201  * Get the ID of the next free M68K breakpoint.
202  *
203  * @return ID or -1 if none free.
204  */
debug_next_free_bp_m68k()205 int md::debug_next_free_bp_m68k()
206 {
207 	int			i;
208 
209 	for (i = 0; i < MAX_BREAKPOINTS; i++) {
210 		if (!(debug_bp_m68k[i].flags & BP_FLAG_USED))
211 			return (i);
212 	}
213 
214 	return (-1); // no free slots
215 }
216 
217 #ifdef WITH_DZ80
218 
disz80_read(void * ctx,WORD addr)219 static BYTE disz80_read(void *ctx, WORD addr)
220 {
221 	class md *md = (class md *)ctx;
222 
223 	return md->z80_read(addr);
224 }
225 
226 #endif
227 
228 /**
229  * Get the ID of the next free Z80 breakpoint.
230  *
231  * @return ID or -1 if none free.
232  */
debug_next_free_bp_z80()233 int md::debug_next_free_bp_z80()
234 {
235 	unsigned int i;
236 
237 	for (i = 0; (i < MAX_BREAKPOINTS); ++i)
238 		if (!(debug_bp_z80[i].flags & BP_FLAG_USED))
239 			return i;
240 	return -1;
241 }
242 
243 /**
244  * Initialise the debugger.
245  *
246  * All breakpoints are disabled by default.
247  */
debug_init()248 void md::debug_init()
249 {
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));
255 
256 #ifndef NO_COMPLETION
257 	linenoiseSetCompletionCallback(completion);
258 #endif
259 
260 	debug_step_m68k = 0;
261 	debug_trace_m68k = 0;
262 	debug_step_z80 = 0;
263 	debug_trace_z80 = 0;
264 	debug_context = DBG_CONTEXT_M68K;
265 	debug_trap = false;
266 	debug_m68k_instr_count = 0;
267 	debug_z80_instr_count = 0;
268 	debug_instr_count_enabled = false;
269 
270 #ifdef WITH_DZ80
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;
277 #endif
278 }
279 
280 /**
281  * Find the index of a M68K breakpoint.
282  *
283  * @param addr Address to look for.
284  * @return -1 if no breakpoint is found, otherwise its index in
285  * debug_bp_m68k[].
286  */
debug_find_bp_m68k(uint32_t addr)287 int md::debug_find_bp_m68k(uint32_t addr)
288 {
289 	int			i;
290 
291 	for (i = 0; i < MAX_BREAKPOINTS; i++) {
292 
293 		if (!(debug_bp_m68k[i].flags & BP_FLAG_USED))
294 			break;
295 
296 		if (debug_bp_m68k[i].addr == addr)
297 			return (i);
298 	}
299 
300 	return (-1); // not found
301 }
302 
303 /**
304  * Find the index of a Z80 breakpoint.
305  *
306  * @param addr Address to look for.
307  * @return -1 if no breakpoint is found, otherwise its index in
308  * debug_bp_z80[].
309  */
debug_find_bp_z80(uint16_t addr)310 int md::debug_find_bp_z80(uint16_t addr)
311 {
312 	unsigned int i;
313 
314 	for (i = 0; (i < MAX_BREAKPOINTS); ++i) {
315 		if (!(debug_bp_z80[i].flags & BP_FLAG_USED))
316 			break;
317 		if (debug_bp_z80[i].addr == addr)
318 			return i;
319 	}
320 	return -1;
321 }
322 
323 /**
324  * Find the index of a M68K watchpoint by its start address.
325  *
326  * @param addr Address to look for.
327  * @return -1 if no watchpoint at the given address, otherwise its index in
328  * debug_wp_m68k[].
329  */
debug_find_wp_m68k(uint32_t addr)330 int md::debug_find_wp_m68k(uint32_t addr)
331 {
332 	int			i;
333 
334 	for (i = 0; i < MAX_WATCHPOINTS; i++) {
335 
336 		if (!(debug_wp_m68k[i].flags & WP_FLAG_USED))
337 			break;
338 
339 		if (debug_wp_m68k[i].start_addr == addr)
340 			return (i);
341 	}
342 
343 	return (-1); // not found
344 }
345 
346 /**
347  * Find the index of a Z80 watchpoint by its start address.
348  *
349  * @param addr Address to look for.
350  * @return -1 if no watchpoint at the given address, otherwise its index in
351  * debug_wp_z80[].
352  */
debug_find_wp_z80(uint16_t addr)353 int md::debug_find_wp_z80(uint16_t addr)
354 {
355 	unsigned int i;
356 
357 	for (i = 0; (i < MAX_WATCHPOINTS); ++i) {
358 		if (!(debug_wp_z80[i].flags & WP_FLAG_USED))
359 			break;
360 		if (debug_wp_z80[i].start_addr == addr)
361 			return i;
362 	}
363 	return -1;
364 }
365 
366 /**
367  * Pretty prints hex dump.
368  *
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.
372  */
debug_print_hex_buf(unsigned char * buf,size_t len,size_t addr_label_start)373 static void debug_print_hex_buf(
374     unsigned char *buf, size_t len, size_t addr_label_start)
375 {
376 	uint32_t		i, done = 0;
377 	unsigned char		byte;
378 	char			ascii[17], *ap, *hp;
379 	char			hdr[60] = "            ";
380 	char			hex[] = "0123456789abcdef";
381 
382 	// header
383 	for (i = 0; i < 16; i++) {
384 		hp = strchr(hdr, '\0');
385 		hp[0] = hex[(addr_label_start + i) % 16];
386 		hp[1] = ' ';
387 		hp[2] = ' ';
388 		hp[3] = '\0';
389 	}
390 	printf("%s\n", hdr);
391 
392 	// process lines of 16 bytes
393 	ap = ascii;
394 	for (i = 0; i < len; i++, done++, ap++) {
395 
396 		if (i % 16 == 0) {
397 			ascii[16] = '\0';
398 
399 			if (i > 0)
400 				printf(" |%s|\n", ascii);
401 
402 			printf("0x%08x: ", (uint32_t) addr_label_start + i);
403 			ap = ascii;
404 		}
405 
406 		byte = buf[i];
407 		// 0x20 to 0x7e is printable ascii
408 		if ((byte >= 0x20) && (byte <= 0x7e))
409 			*ap = byte;
410 		else
411 			*ap = '.';
412 
413 		printf("%02x ",  byte);
414 	}
415 
416 	// make it all line up
417 	if (i % 16) {
418 		ascii[(i % 16)] = '\0';
419 		i = i % 16;
420 		while (i <= 15) {
421 			printf("   ");
422 			i++;
423 		}
424 	}
425 
426 	// print rest of ascii
427 	printf(" |%s|\n", ascii);
428 	fflush(stdout);
429 }
430 
431 /**
432  * Print a M68K watchpoint in a human-readable form.
433  *
434  * @param idx Index of watchpoint to print.
435  */
debug_print_m68k_wp(int idx)436 void md::debug_print_m68k_wp(int idx)
437 {
438 	struct dgen_wp		*w = &(debug_wp_m68k[idx]);
439 
440 	printf("#%0d:\t0x%08x-%08x (%u bytes)\n", idx,
441 	    w->start_addr, w->end_addr, w->end_addr - w->start_addr + 1);
442 
443 	debug_print_hex_buf(w->bytes, w->end_addr - w->start_addr + 1, w->start_addr);
444 	fflush(stdout);
445 }
446 
447 /**
448  * Print a Z80 watchpoint in a human-readable form.
449  *
450  * @param idx Index of watchpoint to print.
451  */
debug_print_z80_wp(int idx)452 void md::debug_print_z80_wp(int idx)
453 {
454 	struct dgen_wp *w = &debug_wp_z80[idx];
455 
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),
459 			    w->start_addr);
460 	fflush(stdout);
461 }
462 
463 /**
464  * Check the given M68K watchpoint against cached memory to see if it should
465  * fire.
466  *
467  * @param[in] w Watch point to check.
468  * @return 1 if true, else 0.
469  */
debug_should_m68k_wp_fire(struct dgen_wp * w)470 int md::debug_should_m68k_wp_fire(struct dgen_wp *w)
471 {
472 	unsigned int		i;
473 	unsigned char		*p;
474 
475 	for (i = w->start_addr, p = w->bytes; i <= w->end_addr; i++, p++) {
476 		if (misc_readbyte(i) != *p)
477 			return (1); // hit
478 	}
479 
480 	return (0);
481 }
482 
483 /**
484  * Check the given Z80 watchpoint against cached memory to see if it should
485  * fire.
486  *
487  * @param[in] w Watch point to check.
488  * @return 1 if true, else 0.
489  */
debug_should_z80_wp_fire(struct dgen_wp * w)490 int md::debug_should_z80_wp_fire(struct dgen_wp *w)
491 {
492 	unsigned int i = w->start_addr;
493 	unsigned char *p = w->bytes;
494 
495 	while (i <= w->end_addr)
496 		if (z80_read(i++) != *p++)
497 			return 1;
498 	return 0;
499 }
500 
501 /**
502  * Get M68K PC.
503  *
504  * @return Current PC.
505  */
m68k_get_pc()506 uint32_t md::m68k_get_pc()
507 {
508 	m68k_state_dump();
509 	return le2h32(m68k_state.pc);
510 }
511 
512 /**
513  * Get Z80 PC.
514  *
515  * @return Current PC.
516  */
z80_get_pc()517 uint16_t md::z80_get_pc()
518 {
519 	z80_state_dump();
520 	return le2h16(z80_state.pc);
521 }
522 
523 /**
524  * Breakpoint handler fired before every M68K instruction.
525  */
debug_m68k_check_bps()526 bool md::debug_m68k_check_bps()
527 {
528 	uint32_t pc = m68k_get_pc();
529 	unsigned int i;
530 	bool bp = false;
531 
532 	if (debug_step_m68k) {
533 		if ((--debug_step_m68k) == 0) {
534 			debug_enter();
535 			bp = true;
536 		}
537 		goto trace;
538 	}
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;
545 				continue;
546 			}
547 			debug_bp_m68k[i].flags |= BP_FLAG_FIRED;
548 			printf("m68k breakpoint hit @ 0x%08x\n", pc);
549 			debug_enter();
550 			bp = true;
551 			break;
552 		}
553 	}
554 trace:
555 	if (debug_trace_m68k) {
556 		if (!bp)
557 			debug_print_m68k_disassemble(pc, 1);
558 		--debug_trace_m68k;
559 	}
560 	fflush(stdout);
561 	return bp;
562 }
563 
564 /**
565  * Watchpoint handler fired after every M68K instruction.
566  */
debug_m68k_check_wps()567 bool md::debug_m68k_check_wps()
568 {
569 	unsigned int i;
570 	bool wp = false;
571 
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);
579 			debug_enter();
580 			debug_update_fired_m68k_wps();
581 			wp = true;
582 			break;
583 		}
584 	}
585 	fflush(stdout);
586 	return wp;
587 }
588 
589 /**
590  * Breakpoint handler fired before every Z80 instruction.
591  */
debug_z80_check_bps()592 bool md::debug_z80_check_bps()
593 {
594 	uint16_t pc = z80_get_pc();
595 	unsigned int i;
596 	bool bp = false;
597 
598 	if (debug_step_z80) {
599 		if ((--debug_step_z80) == 0) {
600 			debug_enter();
601 			bp = true;
602 		}
603 		goto trace;
604 	}
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;
611 				continue;
612 			}
613 			debug_bp_z80[i].flags |= BP_FLAG_FIRED;
614 			printf("z80 breakpoint hit @ 0x%04x\n", pc);
615 			debug_enter();
616 			bp = true;
617 			break;
618 		}
619 	}
620 trace:
621 	if (debug_trace_z80) {
622 		if (!bp)
623 			debug_print_z80_disassemble(pc, 1);
624 		--debug_trace_z80;
625 	}
626 	fflush(stdout);
627 	return bp;
628 }
629 
630 /**
631  * Watchpoint handler fired after every Z80 instruction.
632  */
debug_z80_check_wps()633 bool md::debug_z80_check_wps()
634 {
635 	unsigned int i;
636 	bool wp = false;
637 
638 	for (i = 0; (i < MAX_WATCHPOINTS); i++) {
639 		if (!(debug_wp_z80[i].flags & BP_FLAG_USED))
640 			break;
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);
645 			debug_enter();
646 			debug_update_fired_z80_wps();
647 			wp = true;
648 			break;
649 		}
650 	}
651 	fflush(stdout);
652 	return wp;
653 }
654 
655 /**
656  * Remove a M68K breakpoint.
657  *
658  * @param index Index of breakpoint to remove.
659  */
debug_rm_bp_m68k(int index)660 void md::debug_rm_bp_m68k(int index)
661 {
662 	if (!(debug_bp_m68k[index].flags & BP_FLAG_USED)) {
663 		printf("breakpoint not set\n");
664 		fflush(stdout);
665 		return;
666 	}
667 
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;
672 	} else {
673 		memmove(&(debug_bp_m68k[index]),
674 		    &(debug_bp_m68k[index+1]),
675 		    sizeof(struct dgen_bp) * (MAX_BREAKPOINTS - index - 1));
676 		// disable last slot
677 		debug_bp_m68k[MAX_BREAKPOINTS - 1].addr = 0;
678 		debug_bp_m68k[MAX_BREAKPOINTS - 1].flags = 0;
679 	}
680 }
681 
682 /**
683  * Remove a Z80 breakpoint.
684  *
685  * @param index Index of breakpoint to remove.
686  */
debug_rm_bp_z80(int index)687 void md::debug_rm_bp_z80(int index)
688 {
689 	if (!(debug_bp_z80[index].flags & BP_FLAG_USED)) {
690 		printf("breakpoint not set\n");
691 		fflush(stdout);
692 		return;
693 	}
694 	if (index == (MAX_BREAKPOINTS - 1)) {
695 		debug_bp_z80[index].addr = 0;
696 		debug_bp_z80[index].flags = 0;
697 	}
698 	else {
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;
705 	}
706 }
707 
708 /**
709  * Remove a M68K watchpoint.
710  *
711  * @param index Index of watchpoint to remove.
712  */
debug_rm_wp_m68k(int index)713 void md::debug_rm_wp_m68k(int index)
714 {
715 	if (!(debug_wp_m68k[index].flags & WP_FLAG_USED)) {
716 		printf("watchpoint not set\n");
717 		fflush(stdout);
718 		return;
719 	}
720 
721 	free(debug_wp_m68k[index].bytes);
722 
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;
727 	} else {
728 		memmove(&(debug_wp_m68k[index]),
729 		    &(debug_wp_m68k[index+1]),
730 		    sizeof(struct dgen_bp) * (MAX_WATCHPOINTS - index - 1));
731 		// disable last slot
732 		debug_wp_m68k[MAX_WATCHPOINTS - 1].start_addr = 0;
733 		debug_wp_m68k[MAX_WATCHPOINTS - 1].flags = 0;
734 	}
735 }
736 
737 /**
738  * Remove a Z80 watchpoint.
739  *
740  * @param index Index of watchpoint to remove.
741  */
debug_rm_wp_z80(int index)742 void md::debug_rm_wp_z80(int index)
743 {
744 	if (!(debug_wp_z80[index].flags & WP_FLAG_USED)) {
745 		printf("watchpoint not set\n");
746 		fflush(stdout);
747 		return;
748 	}
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;
753 	}
754 	else {
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;
761 	}
762 }
763 
764 /**
765  * Pretty print M68K breakpoints.
766  */
debug_list_bps_m68k()767 void md::debug_list_bps_m68k()
768 {
769 	int			i;
770 
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
775 
776 		printf("#%0d:\t0x%08x\n", i, debug_bp_m68k[i].addr);
777 	}
778 
779 	if (i == 0)
780 		printf("\tno m68k breakpoints set\n");
781 	fflush(stdout);
782 }
783 
784 /**
785  * Pretty print Z80 breakpoints.
786  */
debug_list_bps_z80()787 void md::debug_list_bps_z80()
788 {
789 	unsigned int i;
790 
791 	printf("z80 breakpoints:\n");
792 	for (i = 0; (i < MAX_BREAKPOINTS); i++) {
793 		if (!(debug_bp_z80[i].flags & BP_FLAG_USED))
794 			break;
795 		printf("#%0d:\t0x%04x\n", i, debug_bp_z80[i].addr);
796 	}
797 	if (i == 0)
798 		printf("\tno z80 breakpoints set\n");
799 	fflush(stdout);
800 }
801 
802 /**
803  * Pretty print M68K watchpoints.
804  */
debug_list_wps_m68k()805 void md::debug_list_wps_m68k()
806 {
807 	int			i;
808 
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);
814 	}
815 
816 	if (i == 0)
817 		printf("\tno m68k watchpoints set\n");
818 	fflush(stdout);
819 }
820 
821 /**
822  * Pretty print Z80 watchpoints.
823  */
debug_list_wps_z80()824 void md::debug_list_wps_z80()
825 {
826 	unsigned int i;
827 
828 	printf("z80 watchpoints:\n");
829 	for (i = 0; (i < MAX_WATCHPOINTS); i++) {
830 		if (!(debug_wp_z80[i].flags & WP_FLAG_USED))
831 			break;
832 		debug_print_z80_wp(i);
833 	}
834 	if (i == 0)
835 		printf("\tno z80 watchpoints set\n");
836 	fflush(stdout);
837 }
838 
839 /**
840  * Add a M68K breakpoint.
841  *
842  * @param addr Address to break on.
843  * @return Always 1.
844  */
debug_set_bp_m68k(uint32_t addr)845 int md::debug_set_bp_m68k(uint32_t addr)
846 {
847 	int		slot;
848 
849 	if ((debug_find_bp_m68k(addr)) != -1) {
850 		printf("breakpoint already set at this address\n");
851 		goto out;
852 	}
853 
854 	slot = debug_next_free_bp_m68k();
855 	if (slot == -1) {
856 		printf("No space for another break point\n");
857 		goto out;
858 	}
859 
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);
863 out:
864 	fflush(stdout);
865 	return (1);
866 }
867 
868 /**
869  * Add a Z80 breakpoint.
870  *
871  * @param addr Address to break on.
872  * @return Always 1.
873  */
debug_set_bp_z80(uint16_t addr)874 int md::debug_set_bp_z80(uint16_t addr)
875 {
876 	int slot;
877 
878 	if ((debug_find_bp_z80(addr)) != -1) {
879 		printf("breakpoint already set at this address\n");
880 		goto out;
881 	}
882 	slot = debug_next_free_bp_z80();
883 	if (slot == -1) {
884 		printf("No space for another break point\n");
885 		goto out;
886 	}
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);
890 out:
891 	fflush(stdout);
892 	return 1;
893 }
894 
895 /**
896  * Convert a core name to a context ID.
897  *
898  * @param[in] arg NUL-terminated core name.
899  * @return Core context ID or -1 on error.
900  */
debug_parse_cpu(char * arg)901 static int debug_parse_cpu(char *arg)
902 {
903 	uint32_t	  num;
904 	const char	**p;
905 
906 	/* by name */
907 	for (p = z80_aliases; *p != NULL; p++) {
908 		if (strcmp(arg, *p) == 0)
909 			return (DBG_CONTEXT_Z80);
910 	}
911 
912 	for (p = m68k_aliases; *p != NULL; p++) {
913 		if (strcmp(arg, *p) == 0)
914 			return (DBG_CONTEXT_M68K);
915 	}
916 
917 	for (p = fm_aliases; *p != NULL; p++) {
918 		if (strcmp(arg, *p) == 0)
919 			return (DBG_CONTEXT_YM2612);
920 	}
921 
922 	for (p = psg_aliases; *p != NULL; p++) {
923 		if (strcmp(arg, *p) == 0)
924 			return (DBG_CONTEXT_SN76489);
925 	}
926 
927 	/* by index */
928 	if ((debug_strtou32(arg, &num)) < 0)
929 		return (-1);
930 
931 	if (num > DBG_CONTEXT_SN76489)
932 		return (-1);
933 
934 	return ((int) num);
935 }
936 
937 // ===[ C++ Methods ]=========================================================
938 
939 /**
940  * Add a M68K watchpoint to a range of addresses.
941  *
942  * @param start_addr Start address of watchpoint range.
943  * @param end_addr End address of watchpoint range.
944  */
debug_set_wp_m68k(uint32_t start_addr,uint32_t end_addr)945 void md::debug_set_wp_m68k(uint32_t start_addr, uint32_t end_addr)
946 {
947 	int		slot;
948 
949 	slot = debug_next_free_wp_m68k();
950 	if (slot == -1) {
951 		printf("No space for another watch point\n");
952 		goto out;
953 	}
954 
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) {
960 		perror("malloc");
961 		goto out;
962 	}
963 
964 	debug_update_m68k_wp_cache(&(debug_wp_m68k[slot]));
965 
966 	printf("m68k watchpoint #%d set @ 0x%08x-0x%08x (%u bytes)\n",
967 	    slot, start_addr, end_addr, end_addr - start_addr + 1);
968 out:
969 	fflush(stdout);
970 }
971 
972 /**
973  * Update the data pointer of a single M68K watchpoint.
974  *
975  * @param w Watchpoint to update.
976  */
debug_update_m68k_wp_cache(struct dgen_wp * w)977 void md::debug_update_m68k_wp_cache(struct dgen_wp *w)
978 {
979 	unsigned int		 addr;
980 	unsigned char		*p;
981 
982 	p = w->bytes;
983 	for (addr = w->start_addr; addr <= w->end_addr; addr++) {
984 		*(p++) = misc_readbyte(addr);
985 	}
986 }
987 
988 /**
989  * Resynchronise all M68K watchpoints based on actual data.
990  */
debug_update_fired_m68k_wps()991 void md::debug_update_fired_m68k_wps()
992 {
993 	int			i;
994 
995 	for (i = 0; i < MAX_WATCHPOINTS; i++) {
996 
997 		if (!(debug_wp_m68k[i].flags & WP_FLAG_USED))
998 			return;
999 
1000 		if (!(debug_wp_m68k[i].flags & WP_FLAG_FIRED))
1001 			continue;
1002 
1003 		debug_update_m68k_wp_cache(&(debug_wp_m68k[i]));
1004 		debug_wp_m68k[i].flags &= ~WP_FLAG_FIRED;
1005 	}
1006 }
1007 
1008 /**
1009  * Add a Z80 watchpoint to a range of addresses.
1010  *
1011  * @param start_addr Start address of watchpoint range.
1012  * @param end_addr End address of watchpoint range.
1013  */
debug_set_wp_z80(uint16_t start_addr,uint16_t end_addr)1014 void md::debug_set_wp_z80(uint16_t start_addr, uint16_t end_addr)
1015 {
1016 	int slot;
1017 
1018 	slot = debug_next_free_wp_z80();
1019 	if (slot == -1) {
1020 		printf("No space for another watch point\n");
1021 		goto out;
1022 	}
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) {
1029 		perror("malloc");
1030 		goto out;
1031 	}
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));
1035 out:
1036 	fflush(stdout);
1037 }
1038 
1039 /**
1040  * Update the data pointer of a single Z80 watchpoint.
1041  *
1042  * @param w Watchpoint to update.
1043  */
debug_update_z80_wp_cache(struct dgen_wp * w)1044 void md::debug_update_z80_wp_cache(struct dgen_wp *w)
1045 {
1046 	unsigned int addr;
1047 	unsigned char *p = w->bytes;
1048 
1049 	for (addr = w->start_addr; (addr <= w->end_addr); addr++)
1050 		*(p++) = z80_read(addr);
1051 }
1052 
1053 /**
1054  * Resynchronise all Z80 watchpoints based on actual data.
1055  */
debug_update_fired_z80_wps()1056 void md::debug_update_fired_z80_wps()
1057 {
1058 	int i;
1059 
1060 	for (i = 0; (i < MAX_WATCHPOINTS); i++) {
1061 		if (!(debug_wp_z80[i].flags & WP_FLAG_USED))
1062 			return;
1063 		if (!(debug_wp_z80[i].flags & WP_FLAG_FIRED))
1064 			continue;
1065 		debug_update_z80_wp_cache(&(debug_wp_z80[i]));
1066 		debug_wp_z80[i].flags &= ~WP_FLAG_FIRED;
1067 	}
1068 }
1069 
1070 /**
1071  * Watchpoints (watch) command handler.
1072  *
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
1077  *   length args[1].
1078  *
1079  * @param n_args Number of arguments.
1080  * @param args Arguments, see above.
1081  * @return Always 1.
1082  */
debug_cmd_watch(int n_args,char ** args)1083 int md::debug_cmd_watch(int n_args, char **args)
1084 {
1085 	uint32_t		start, len = 1;
1086 
1087 	if (debug_context != DBG_CONTEXT_M68K){
1088 		printf("watchpoints not supported on %s core\n",
1089 		    CURRENT_DEBUG_CONTEXT_NAME);
1090 		goto out;
1091 	}
1092 
1093 	switch (n_args) {
1094 	case 2:
1095 		if ((debug_strtou32(args[1], &len)) < 0) {
1096 			printf("length malformed: %s\n", args[1]);
1097 			goto out;
1098 		}
1099 		// fallthru
1100 	case 1:
1101 		if ((debug_strtou32(args[0], &start)) < 0) {
1102 			printf("address malformed: %s\n", args[0]);
1103 			goto out;
1104 		}
1105 		debug_set_wp_m68k(start, start+len-1); // one byte
1106 		break;
1107 	case 0:
1108 		// listing wps
1109 		debug_list_wps_m68k();
1110 		break;
1111 	};
1112 out:
1113 	fflush(stdout);
1114 	return (1);
1115 }
1116 
1117 /**
1118  * Pretty print a block of memory as a hex dump.
1119  *
1120  * @param addr Start address.
1121  * @param len Length (in bytes) to dump.
1122  */
debug_dump_mem(uint32_t addr,uint32_t len)1123 void md::debug_dump_mem(uint32_t addr, uint32_t len)
1124 {
1125 	uint32_t		 i;
1126 	unsigned char		*buf;
1127 
1128 	// we have to make a buffer to pass down
1129 	buf = (unsigned char *) malloc(len);
1130 	if (buf == NULL) {
1131 		perror("malloc");
1132 		return;
1133 	}
1134 
1135 	for (i = 0; i < len; i++) {
1136 	    buf[i] = misc_readbyte(addr + i);
1137 	}
1138 
1139 	debug_print_hex_buf(buf, len, addr);
1140 	free(buf);
1141 }
1142 
1143 /**
1144  * Memory dump (mem) command handler.
1145  *
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
1149  *   bytes to dump.
1150  *
1151  * @param n_args Number of arguments.
1152  * @param args Arguments, see above.
1153  * @return Always 1.
1154  */
debug_cmd_mem(int n_args,char ** args)1155 int md::debug_cmd_mem(int n_args, char **args)
1156 {
1157 	uint32_t		addr, len = DEBUG_DFLT_MEMDUMP_LEN;
1158 
1159 	if (debug_context != DBG_CONTEXT_M68K) {
1160 		printf("memory dumping not implemented on %s core\n",
1161 		    CURRENT_DEBUG_CONTEXT_NAME);
1162 		goto out;
1163 	}
1164 
1165 	switch (n_args) {
1166 	case 2: /* specified length */
1167 		if ((debug_strtou32(args[1], &len)) < 0) {
1168 			printf("length malformed: %s\n", args[1]);
1169 			goto out;
1170 		}
1171 		/* FALLTHRU */
1172 	case 1: /* default length */
1173 		if ((debug_strtou32(args[0], &addr)) < 0) {
1174 			printf("addr malformed: %s\n", args[0]);
1175 			goto out;
1176 		}
1177 
1178 		debug_dump_mem(addr, len);
1179 		break;
1180 	};
1181 out:
1182 	fflush(stdout);
1183 	return (1);
1184 }
1185 
1186 /**
1187  * Memory/registers write (setb/setw/setl/setr) commands handler.
1188  *
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.
1194  *
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.
1198  * @return Always 1.
1199  */
debug_cmd_setbwlr(int n_args,char ** args,unsigned int type)1200 int md::debug_cmd_setbwlr(int n_args, char **args, unsigned int type)
1201 {
1202 	uint32_t		addr = 0;
1203 	union {
1204 		uint32_t *r32;
1205 		uint16_t *r16;
1206 		uint8_t *r8;
1207 		void *ptr;
1208 	} reg_ptr = { NULL };
1209 	unsigned int		reg = -1;
1210 	uint32_t		val;
1211 
1212 	(void)n_args;
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);
1218 		goto out;
1219 	}
1220 	if (type == ~0u) {
1221 		static const struct {
1222 
1223 #define REG0(id, idx) { \
1224 	# id # idx, \
1225 	((uintptr_t)&m68k_state.id[idx] - (uintptr_t)&m68k_state), \
1226 	sizeof(m68k_state.id[idx]) \
1227 }
1228 
1229 #define REG1(id) { # id, offsetof(m68k_state_t, id), sizeof(m68k_state.id) }
1230 
1231 #define REG2(id, idx, name) { \
1232 	name, \
1233 	((uintptr_t)&z80_state.alt[idx].id - (uintptr_t)&z80_state), \
1234 	sizeof(z80_state.alt[idx].id) \
1235 }
1236 
1237 #define REG3(id) { # id, offsetof(z80_state_t, id), sizeof(z80_state.id) }
1238 
1239 			const char *name;
1240 			size_t offset;
1241 			size_t size;
1242 		} regid[2][32] = {
1243 			{
1244 				// M68K
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),
1249 				REG1(pc), REG1(sr)
1250 			},
1251 			{
1252 				// Z80
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)
1259 			}
1260 		};
1261 		unsigned int idx;
1262 		uint8_t *state;
1263 
1264 		if (debug_context == DBG_CONTEXT_M68K) {
1265 			idx = 0;
1266 			state = (uint8_t *)&m68k_state;
1267 		}
1268 		else if (debug_context == DBG_CONTEXT_Z80) {
1269 			idx = 1;
1270 			state = (uint8_t *)&z80_state;
1271 		}
1272 		else
1273 			goto out;
1274 		for (addr = 0;
1275 		     (addr != (sizeof(regid[idx]) / sizeof(regid[idx][0])));
1276 		     ++addr) {
1277 			if (regid[idx][addr].name == NULL)
1278 				break;
1279 			if (strcasecmp(regid[idx][addr].name, args[0]))
1280 				continue;
1281 			reg_ptr.ptr =
1282 				(void *)(state + regid[idx][addr].offset);
1283 			reg = regid[idx][addr].size;
1284 			break;
1285 		}
1286 		if (reg == -1u) {
1287 			printf("unknown register %s\n", args[0]);
1288 			goto out;
1289 		}
1290 	}
1291 	else if (debug_strtou32(args[0], &addr) < 0) {
1292 		printf("addr malformed: %s\n", args[0]);
1293 		goto out;
1294 	}
1295 	if (debug_strtou32(args[1], &val) < 0) {
1296 		printf("value malformed: %s\n", args[1]);
1297 		goto out;
1298 	}
1299 	switch (type) {
1300 	case 1:
1301 		/* byte */
1302 		misc_writebyte(addr, val);
1303 		break;
1304 	case 2:
1305 		/* word */
1306 		misc_writeword(addr, val);
1307 		break;
1308 	case 4:
1309 		/* long */
1310 		misc_writeword(addr, ((val >> 16) & 0xffff));
1311 		misc_writeword((addr + 2), (val & 0xffff));
1312 		break;
1313 	case ~0u:
1314 		/* register */
1315 		m68k_state_dump();
1316 		z80_state_dump();
1317 		if (reg == 2)
1318 			*reg_ptr.r16 = le2h16(val);
1319 		else if (reg == 4)
1320 			*reg_ptr.r32 = le2h32(val);
1321 		else if (reg == 1)
1322 			*reg_ptr.r8 = val;
1323 		m68k_state_restore();
1324 		z80_state_restore();
1325 		break;
1326 	default:
1327 		printf("unknown type size %u\n", type);
1328 	}
1329 out:
1330 	fflush(stdout);
1331 	return 1;
1332 }
1333 
1334 /**
1335  * Set byte (setb) command handler, see debug_cmd_setbwlr().
1336  *
1337  * @return Always 1.
1338  */
debug_cmd_setb(int n_args,char ** args)1339 int md::debug_cmd_setb(int n_args, char **args)
1340 {
1341 	return debug_cmd_setbwlr(n_args, args, 1);
1342 }
1343 
1344 /**
1345  * Set word (setw) command handler, see debug_cmd_setbwlr().
1346  *
1347  * @return Always 1.
1348  */
debug_cmd_setw(int n_args,char ** args)1349 int md::debug_cmd_setw(int n_args, char **args)
1350 {
1351 	return debug_cmd_setbwlr(n_args, args, 2);
1352 }
1353 
1354 /**
1355  * Set long word (setl) command handler, see debug_cmd_setbwlr().
1356  *
1357  * @return Always 1.
1358  */
debug_cmd_setl(int n_args,char ** args)1359 int md::debug_cmd_setl(int n_args, char **args)
1360 {
1361 	return debug_cmd_setbwlr(n_args, args, 4);
1362 }
1363 
1364 /**
1365  * Set register (setr) command handler, see debug_cmd_setbwlr().
1366  *
1367  * @return Always 1.
1368  */
debug_cmd_setr(int n_args,char ** args)1369 int md::debug_cmd_setr(int n_args, char **args)
1370 {
1371 	return debug_cmd_setbwlr(n_args, args, ~0u);
1372 }
1373 
1374 /**
1375  * Disassemble (dis) command handler.
1376  *
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]
1381  *   instructions.
1382  *
1383  * @param n_args Number of arguments.
1384  * @param[in] args Arguments list.
1385  * @return Always 1.
1386  */
debug_cmd_dis(int n_args,char ** args)1387 int md::debug_cmd_dis(int n_args, char **args)
1388 {
1389 	uint32_t		addr;
1390 	uint32_t		length = DEBUG_DFLT_DASM_LEN;
1391 
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();
1396 	else {
1397 		printf("disassembly is not implemented on %s core\n",
1398 		    CURRENT_DEBUG_CONTEXT_NAME);
1399 		goto out;
1400 	}
1401 
1402 	switch (n_args) {
1403 		case 0:
1404 			// nothing :)
1405 			break;
1406 		case 2:
1407 			if ((debug_strtou32(args[1], &length)) < 0) {
1408 				printf("length malformed: %s\n", args[1]);
1409 				goto out;
1410 			}
1411 			// fallthru
1412 		case 1:
1413 			if ((debug_strtou32(args[0], &addr)) < 0) {
1414 				printf("address malformed: %s\n", args[0]);
1415 				goto out;
1416 			}
1417 			break;
1418 	};
1419 
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);
1424 out:
1425 	fflush(stdout);
1426 	return (1);
1427 }
1428 
1429 /**
1430  * Continue (cont) command handler. This command drops out of debug mode.
1431  *
1432  * @param n_args Number of arguments (ignored).
1433  * @param args Arguments (ignored).
1434  * @return Always 0 (debugger should exit).
1435  */
debug_cmd_cont(int n_args,char ** args)1436 int md::debug_cmd_cont(int n_args, char **args)
1437 {
1438 	(void) n_args;
1439 	(void) args;
1440 
1441 	debug_trap = false;
1442 	return (0); // causes debugger to exit
1443 }
1444 
1445 /**
1446  * Pretty print the M68K registers using m68k_state from class md.
1447  */
debug_show_m68k_regs()1448 void md::debug_show_m68k_regs()
1449 {
1450 	int			i;
1451 	uint16_t		sr;
1452 
1453 	m68k_state_dump();
1454 	sr = le2h16(m68k_state.sr);
1455 
1456 	if (debug_instr_count_enabled)
1457 		printf("m68k (%lu instructions):\n", debug_m68k_instr_count);
1458 	else
1459 		printf("m68k:\n");
1460 
1461 	printf("\tpc:\t0x%08x\n\tsr:\t0x%08x\n", le2h32(m68k_state.pc), sr);
1462 
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);
1470 
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);
1480 
1481 	// d*
1482 	for (i =  0; i < 8; i++)
1483 		printf("\td%d:\t0x%08x\n", i, le2h32(m68k_state.d[i]));
1484 	// a*
1485 	for (i =  0; i < 8; i++)
1486 		printf("\ta%d:\t0x%08x\n", i, le2h32(m68k_state.a[i]));
1487 	fflush(stdout);
1488 }
1489 
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);
1498 /**
1499  * Pretty print Z80 registers using z80_state from class md.
1500  */
debug_show_z80_regs()1501 void md::debug_show_z80_regs()
1502 {
1503 	int			i;
1504 
1505 	z80_state_dump();
1506 	printf("z80:\n");
1507 
1508 	for (i = 0; i < 2; i++) {
1509 		const char *alt = (i ? "'" : "");
1510 
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));
1520 	}
1521 
1522 	printf("\t ix:\t0x%04x\n"
1523 	    "\t iy:\t0x%04x\n"
1524 	    "\t sp:\t0x%04x\n"
1525 	    "\t pc:\t0x%04x\n"
1526 	    "\t  r:\t0x%02x\n"
1527 	    "\t  i:\t0x%02x\n"
1528 	    "\tiff:\t0x%02x\n"
1529 	    "\t im:\t0x%02x\n",
1530 	    le2h16(z80_state.ix),
1531 	    le2h16(z80_state.iy),
1532 	    le2h16(z80_state.sp),
1533 	    le2h16(z80_state.pc),
1534 	    z80_state.r,
1535 	    z80_state.i,
1536 	    z80_state.iff,
1537 	    z80_state.im);
1538 	fflush(stdout);
1539 }
1540 
1541 /**
1542  * Help (help) command handler.
1543  *
1544  * @param n_args Number of arguments (ignored).
1545  * @param args List of arguments (ignored).
1546  * @return Always 1.
1547  */
debug_cmd_help(int n_args,char ** args)1548 int md::debug_cmd_help(int n_args, char **args)
1549 {
1550 	(void) n_args;
1551 	(void) args;
1552 
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);
1585 	fflush(stdout);
1586 	return (1);
1587 }
1588 
1589 /**
1590  * Dump registers (reg) command handler.
1591  * This command pretty prints registers for the current context.
1592  *
1593  * @param n_args Number of arguments (ignored).
1594  * @param[in] args List of arguments (ignored).
1595  * @return Always 1.
1596  */
debug_cmd_reg(int n_args,char ** args)1597 int md::debug_cmd_reg(int n_args, char **args)
1598 {
1599 	(void) n_args;
1600 	(void) args;
1601 
1602 	switch (debug_context) {
1603 	case DBG_CONTEXT_M68K:
1604 		debug_show_m68k_regs();
1605 		break;
1606 	case DBG_CONTEXT_Z80:
1607 		debug_show_z80_regs();
1608 		break;
1609 	case DBG_CONTEXT_YM2612:
1610 		debug_show_ym2612_regs();
1611 		break;
1612 	default:
1613 		printf("register dump not implemented on %s core\n",
1614 		    CURRENT_DEBUG_CONTEXT_NAME);
1615 		break;
1616 	};
1617 	fflush(stdout);
1618 	return (1);
1619 }
1620 
1621 /**
1622  * Instructions counters toggle (count) command handler.
1623  *
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.
1627  *
1628  * @param n_args Number of arguments.
1629  * @param args Arguments.
1630  * @return Always 1.
1631  */
debug_cmd_count(int n_args,char ** args)1632 int md::debug_cmd_count(int n_args, char **args)
1633 {
1634 	static const struct {
1635 		const char *param;
1636 		bool value;
1637 	} opt[] = {
1638 		{ "true", true }, { "false", false },
1639 		{ "yes", true }, { "no", false },
1640 		{ "on", true }, { "off", false },
1641 		{ "enable", true }, { "disable", false }
1642 	};
1643 
1644 	if (n_args == 1) {
1645 		uint32_t i;
1646 
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;
1650 				break;
1651 			}
1652 		if (i == (sizeof(opt) / sizeof(opt[0]))) {
1653 			if (debug_strtou32(args[0], &i) == -1) {
1654 				printf("invalid argument: %s\n", args[0]);
1655 				goto out;
1656 			}
1657 			debug_instr_count_enabled = !!i;
1658 		}
1659 	}
1660 	else
1661 		debug_instr_count_enabled = !debug_instr_count_enabled;
1662 	printf("instructions counters ");
1663 	if (!debug_instr_count_enabled)
1664 		printf("disabled.\n");
1665 	else {
1666 		debug_m68k_instr_count = 0;
1667 		debug_z80_instr_count = 0;
1668 		printf("enabled.\n");
1669 	}
1670 out:
1671 	fflush(stdout);
1672 	return 1;
1673 }
1674 
1675 /**
1676  * Breakpoint (break) command handler.
1677  *
1678  * - If n_args == 0, list breakpoints.
1679  * - If n_args == 1, set a breakpoint at address args[0].
1680  *
1681  * @param n_args Number of arguments.
1682  * @param[in] args List of arguments.
1683  * @return Always 1.
1684  */
debug_cmd_break(int n_args,char ** args)1685 int md::debug_cmd_break(int n_args, char **args)
1686 {
1687 	uint32_t		num;
1688 
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);
1693 		goto out;
1694 	}
1695 
1696 	switch (n_args) {
1697 	case 1:
1698 		// setting a bp
1699 		if ((debug_strtou32(args[0], &num)) < 0) {
1700 			printf("address malformed: %s\n", args[0]);
1701 			goto out;
1702 		}
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);
1707 		break;
1708 	case 0:
1709 		// listing bps
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();
1714 	};
1715 
1716 out:
1717 	fflush(stdout);
1718 	return (1);
1719 }
1720 
1721 /**
1722  * Quit (quit) command handler.
1723  * This command makes DGen/SDL quit.
1724  *
1725  * @param n_args Number of arguments (ignored).
1726  * @param args List of arguments (ignored).
1727  * @return Always -1.
1728  */
debug_cmd_quit(int n_args,char ** args)1729 int md::debug_cmd_quit(int n_args, char **args)
1730 {
1731 	(void) n_args;
1732 	(void) args;
1733 	debug_leave();
1734 	return -1;
1735 }
1736 
1737 /**
1738  * Core/CPU selection (cpu) command.
1739  * Switch to the core/CPU given in args[0].
1740  *
1741  * @param n_args Number of arguments (should always be 1).
1742  * @param args List of arguments.
1743  * @return Always 1.
1744  */
debug_cmd_cpu(int n_args,char ** args)1745 int md::debug_cmd_cpu(int n_args, char **args)
1746 {
1747 	(void) n_args;
1748 
1749 	int			ctx;
1750 
1751 	ctx = debug_parse_cpu(args[0]);
1752 	if (ctx < 0) {
1753 		printf("unknown cpu: %s\n", args[0]);
1754 		goto out;
1755 	}
1756 
1757 	debug_context = ctx;
1758 out:
1759 	fflush(stdout);
1760 	return (1);
1761 }
1762 
1763 /**
1764  * Step (step) command handler for the current core.
1765  *
1766  * - If n_args == 0, step one instruction.
1767  * - If n_args == 1, step args[0] instructions.
1768  *
1769  * @param n_args Number of arguments.
1770  * @param args List of arguments.
1771  * @return 0 if execution should continue, 1 otherwise.
1772  */
debug_cmd_step(int n_args,char ** args)1773 int md::debug_cmd_step(int n_args, char **args)
1774 {
1775 	uint32_t		num = 1;
1776 
1777 	if ((n_args >= 1) && (debug_strtou32(args[0], &num) < 0)) {
1778 		printf("malformed number: %s\n", args[0]);
1779 		goto out;
1780 	}
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);
1785 	else {
1786 		printf("stepping not supported on %s\n",
1787 		       CURRENT_DEBUG_CONTEXT_NAME);
1788 		goto out;
1789 	}
1790 	fflush(stdout);
1791 	debug_trap = false;
1792 	return (0); // continue executing
1793 out:
1794 	fflush(stdout);
1795 	return (1);
1796 }
1797 
1798 /**
1799  * Trace toggle (trace) command handler.
1800  *
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.
1806  *
1807  * @param n_args Number of arguments.
1808  * @param args Arguments.
1809  * @return Always 1.
1810  */
debug_cmd_trace(int n_args,char ** args)1811 int md::debug_cmd_trace(int n_args, char **args)
1812 {
1813 	static const struct {
1814 		const char *param;
1815 		unsigned int value;
1816 	} opt[] = {
1817 		{ "true", ~0u }, { "false", 0 },
1818 		{ "yes", ~0u }, { "no", 0 },
1819 		{ "on", ~0u }, { "off", 0 },
1820 		{ "enable", ~0u }, { "disable", 0 }
1821 	};
1822 	unsigned int *which;
1823 
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);
1828 		goto out;
1829 	}
1830 	if (n_args == 1) {
1831 		uint32_t i;
1832 
1833 		for (i = 0; (i != (sizeof(opt) / sizeof(opt[0]))); ++i)
1834 			if (!strcasecmp(args[0], opt[i].param)) {
1835 				*which = opt[i].value;
1836 				break;
1837 			}
1838 		if (i == (sizeof(opt) / sizeof(opt[0]))) {
1839 			if (debug_strtou32(args[0], &i) == -1) {
1840 				printf("invalid argument: %s\n", args[0]);
1841 				goto out;
1842 			}
1843 			*which = i;
1844 		}
1845 	}
1846 	else
1847 		*which = (!*which * ~0u);
1848 	printf("instructions tracing ");
1849 	switch (*which) {
1850 	case 0:
1851 		printf("disabled.\n");
1852 		break;
1853 	case ~0u:
1854 		printf("enabled permanently.\n");
1855 		break;
1856 	default:
1857 		printf("enabled for the next %u instruction(s).\n", *which);
1858 		break;
1859 	}
1860 out:
1861 	fflush(stdout);
1862 	return 1;
1863 }
1864 
1865 /**
1866  * Watchpoint removal (-watch) command handler.
1867  *
1868  * If args[0] starts with a #, remove a watchpoint by ID. Otherwise, remove
1869  * it by address.
1870  *
1871  * @param n_args Number of arguments (always 1).
1872  * @param[in] args List of arguments.
1873  * @return Always 1.
1874  */
debug_cmd_minus_watch(int n_args,char ** args)1875 int md::debug_cmd_minus_watch(int n_args, char **args)
1876 {
1877 	int			index = -1;
1878 	uint32_t		num;
1879 
1880 	(void) n_args;
1881 
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);
1886 		goto out;
1887 	}
1888 
1889 	if (args[0][0] == '#') { // remove by index
1890 
1891 		if (strlen(args[0]) < 2) {
1892 			printf("parse error\n");
1893 			goto out;
1894 		}
1895 
1896 		if ((debug_strtou32(args[0]+1, &num)) < 0) {
1897 			printf("address malformed: %s\n", args[0]);
1898 			goto out;
1899 		}
1900 		index = num;
1901 
1902 		if ((index < 0) || (index >= MAX_BREAKPOINTS)) {
1903 			printf("breakpoint out of range\n");
1904 			goto out;
1905 		}
1906 	} else { // remove by address
1907 		if ((debug_strtou32(args[0], &num)) < 0) {
1908 			printf("address malformed: %s\n", args[0]);
1909 			goto out;
1910 		}
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);
1915 	}
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);
1920 out:
1921 	fflush(stdout);
1922 	return (1);
1923 }
1924 
1925 
1926 /**
1927  * Breakpoint removal (-break) command handler.
1928  *
1929  * If args[0] starts with a #, remove a breakpoint by ID. Otherwise, remove
1930  * it by address.
1931  *
1932  * @param n_args Number of arguments (always 1).
1933  * @param args List of arguments.
1934  * @return Always 1.
1935  */
debug_cmd_minus_break(int n_args,char ** args)1936 int md::debug_cmd_minus_break(int n_args, char **args)
1937 {
1938 	int			index = -1;
1939 	uint32_t		num;
1940 
1941 	(void) n_args;
1942 
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);
1947 		goto out;
1948 	}
1949 
1950 	if (args[0][0] == '#') { // remove by index
1951 
1952 		if (strlen(args[0]) < 2) {
1953 		    printf("parse error\n");
1954 		    goto out;
1955 		}
1956 
1957 		if ((debug_strtou32(args[0]+1, &num)) < 0) {
1958 			printf("address malformed: %s\n", args[0]);
1959 			goto out;
1960 		}
1961 		index = num;
1962 
1963 		if ((index < 0) || (index >= MAX_BREAKPOINTS)) {
1964 			printf("breakpoint out of range\n");
1965 			goto out;
1966 		}
1967 
1968 	} else { // remove by address
1969 		if ((debug_strtou32(args[0], &num)) < 0) {
1970 			printf("address malformed: %s\n", args[0]);
1971 			goto out;
1972 		}
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);
1977 		if (index < 0) {
1978 			printf("no breakpoint here: %s\n", args[0]);
1979 			goto out;
1980 		}
1981 	}
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);
1987 out:
1988 	fflush(stdout);
1989 	return (1);
1990 }
1991 
1992 /**
1993  * Dispatch a command to the relevant handler method.
1994  *
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.
1998  */
debug_despatch_cmd(int n_toks,char ** toks)1999 int md::debug_despatch_cmd(int n_toks, char **toks)
2000 {
2001 
2002 	struct md::dgen_debugger_cmd	 *d = (struct md::dgen_debugger_cmd *)
2003 	    md::debug_cmd_list, *found = NULL;
2004 
2005 	if (n_toks == 0)
2006 		return 1;
2007 	while (d->cmd != NULL) {
2008 		if ((strcmp(toks[0], d->cmd) == 0) && (n_toks-1 == d->n_args)) {
2009 			found = d;
2010 			break;
2011 		}
2012 		d++;
2013 	}
2014 
2015 	if (found == NULL) {
2016 		printf("unknown command/wrong argument count (type '?' for help)\n");
2017 		fflush(stdout);
2018 		return (1);
2019 	}
2020 
2021 	// all is well, call
2022 	return ((this->*found->handler)(n_toks-1, &toks[1]));
2023 }
2024 
2025 #define MAX_DISASM		128
2026 /**
2027  * Pretty print a M68K disassembly.
2028  *
2029  * @param from Address to start disassembling from.
2030  * @param len Number of instructions to disassemble.
2031  */
debug_print_m68k_disassemble(uint32_t from,int len)2032 void md::debug_print_m68k_disassemble(uint32_t from, int len)
2033 {
2034 #ifdef WITH_MUSA
2035 	int			i;
2036 	char			disasm[MAX_DISASM];
2037 
2038 	md_set_musa(1);	// assign static in md:: so C can get at it (HACK)
2039 	for (i = 0; i < len; i++) {
2040 		unsigned int sz;
2041 
2042 		sz = m68k_disassemble(disasm, from, M68K_CPU_TYPE_68040);
2043 		printf("   0x%06x: %s\n", from, disasm);
2044 		from += sz;
2045 	}
2046 	md_set_musa(0);
2047 #else
2048 	(void)len;
2049 	printf("   0x%06x: %02x %02x [...]\n", from,
2050 	       misc_readbyte(from), misc_readbyte(from + 1));
2051 #endif
2052 	fflush(stdout);
2053 }
2054 
2055 /**
2056  * Pretty print a Z80 disassembly.
2057  *
2058  * @param from Address to start disassembling from.
2059  * @param num Number of instructions to disassemble.
2060  */
debug_print_z80_disassemble(uint16_t from,unsigned int num)2061 void md::debug_print_z80_disassemble(uint16_t from, unsigned int num)
2062 {
2063 #ifdef WITH_DZ80
2064 	unsigned int i;
2065 
2066 	for (i = 0; (i < num); ++i) {
2067 		int err;
2068 
2069 		disz80.start = from;
2070 		disz80.end = from;
2071 		err = dZ80_Disassemble(&disz80);
2072 		if (err != DERR_NONE)
2073 			printf("   0x%04x: ??? error: %s\n",
2074 			       from, dZ80_GetErrorText(err));
2075 		else
2076 			printf("   0x%04x: %8s %s\n",
2077 			       from, disz80.hexDisBuf, disz80.disBuf);
2078 		from += disz80.bytesProcessed;
2079 	}
2080 #else
2081 	(void)num;
2082 	printf("   0x%04x: %02x [...]\n", from, z80_read(from));
2083 #endif
2084 	fflush(stdout);
2085 }
2086 
2087 /**
2088  * Leave debugger.
2089  */
debug_leave()2090 void md::debug_leave()
2091 {
2092 	if (debug_trap == false)
2093 		return;
2094 	linenoise_nb_clean();
2095 	debug_trap = false;
2096 }
2097 
2098 /**
2099  * Enter debugger and show command prompt.
2100  */
debug_enter()2101 int md::debug_enter()
2102 {
2103 	char				*cmd, prompt[32];
2104 	char				*p, *next;
2105 	char				*toks[MAX_DEBUG_TOKS];
2106 	int				 n_toks = 0;
2107 	uint32_t			 m68k_pc = m68k_get_pc();
2108 	uint16_t			 z80_pc = z80_get_pc();
2109 	int				 ret;
2110 
2111 	if (debug_trap == false) {
2112 		pd_message("Debug trap.");
2113 		debug_trap = true;
2114 
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);
2119 	}
2120 
2121 	switch (debug_context) {
2122 	case DBG_CONTEXT_M68K:
2123 		snprintf(prompt, sizeof(prompt), "m68k:0x%08x> ", m68k_pc);
2124 		break;
2125 	case DBG_CONTEXT_Z80:
2126 		snprintf(prompt, sizeof(prompt), "z80:0x%04x> ", z80_pc);
2127 		break;
2128 	case DBG_CONTEXT_YM2612:
2129 		snprintf(prompt, sizeof(prompt), "ym2612> ");
2130 		break;
2131 	case DBG_CONTEXT_SN76489:
2132 		snprintf(prompt, sizeof(prompt), "sn76489> ");
2133 		break;
2134 	default:
2135 		printf("unknown cpu. should not happen\n");
2136 		fflush(stdout);
2137 		return 0;
2138 	};
2139 
2140 	if ((cmd = linenoise_nb(prompt)) == NULL) {
2141 		if (!linenoise_nb_eol())
2142 			return 0;
2143 		linenoise_nb_clean();
2144 		return 0;
2145 	}
2146 
2147 	linenoiseHistoryAdd((const char *)cmd);
2148 
2149 	// tokenise
2150 	next = p = cmd;
2151 	n_toks = 0;
2152 	while ((n_toks < MAX_DEBUG_TOKS) &&
2153 	       ((p = strtok(next, " \t")) != NULL)) {
2154 		toks[n_toks++] = p;
2155 		next = NULL;
2156 	}
2157 
2158 	ret = debug_despatch_cmd(n_toks,  toks);
2159 	free(cmd);
2160 	return ret;
2161 }
2162 
2163 
2164 /**
2165  * List of commands.
2166  */
2167 const struct md::dgen_debugger_cmd md::debug_cmd_list[] = {
2168 		// breakpoints
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},
2181 		// disassemble
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},
2188 		// help
2189 		{(char *) "help",	0,	&md::debug_cmd_help},
2190 		{(char *) "h",		0,	&md::debug_cmd_help},
2191 		{(char *) "?",		0,	&md::debug_cmd_help},
2192 		// memory
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},
2202 		// quit
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},
2207 		// dump registers
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},
2212 		// step
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},
2221 		// watch points
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},
2230 		// sentinal
2231 		{NULL,                  0,      NULL}
2232 	};
2233