diff debug.c @ 2216:4e27c36f947c

Add disassemble command to debugger
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Aug 2022 18:42:45 -0700
parents 7591c67b8d1e
children 6a07b13894f7
line wrap: on
line diff
--- a/debug.c	Tue Aug 30 00:13:55 2022 -0700
+++ b/debug.c	Tue Aug 30 18:42:45 2022 -0700
@@ -1884,6 +1884,31 @@
 	return 1;
 }
 
+static uint8_t cmd_disassemble_m68k(debug_root *root, parsed_command *cmd)
+{
+	m68k_context *context = root->cpu_context;
+	uint32_t address = root->address;
+	if (cmd->num_args) {
+		address = cmd->args[0].value;
+	}
+	char disasm_buf[1024];
+	m68kinst inst;
+	do {
+		label_def *def = find_label(root->disasm, address);
+		if (def) {
+			for (uint32_t i = 0; i < def->num_labels; i++)
+			{
+				printf("%s:\n", def->labels[i]);
+			}
+		}
+		
+		address = m68k_decode(m68k_instruction_fetch, context, &inst, address);
+		m68k_disasm_labels(&inst, disasm_buf, root->disasm);
+		printf("\t%s\n", disasm_buf);
+	} while(!m68k_is_terminal(&inst));
+	return 1;
+}
+
 static uint8_t cmd_vdp_sprites(debug_root *root, parsed_command *cmd)
 {
 	m68k_context *context = root->cpu_context;
@@ -2265,6 +2290,16 @@
 		.impl = cmd_delete_m68k,
 		.min_args = 1,
 		.max_args = 1
+	},
+	{
+		.names = (const char *[]){
+			"disassemble", "disasm", NULL
+		},
+		.usage = "disassemble [ADDRESS]",
+		.desc = "Disassemble code starting at ADDRESS if provided or the current address if not",
+		.impl = cmd_disassemble_m68k,
+		.min_args = 0,
+		.max_args = 1
 	}
 };
 
@@ -2505,6 +2540,32 @@
 	return 1;
 }
 
+static uint8_t cmd_disassemble_z80(debug_root *root, parsed_command *cmd)
+{
+	z80_context *context = root->cpu_context;
+	uint32_t address = root->address;
+	if (cmd->num_args) {
+		address = cmd->args[0].value;
+	}
+	char disasm_buf[1024];
+	z80inst inst;
+	do {
+		label_def *def = find_label(root->disasm, address);
+		if (def) {
+			for (uint32_t i = 0; i < def->num_labels; i++)
+			{
+				printf("%s:\n", def->labels[i]);
+			}
+		}
+		uint8_t *pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
+		uint8_t *after = z80_decode(pc, &inst);
+		z80_disasm(&inst, disasm_buf, address);
+		address += after - pc;
+		printf("\t%s\n", disasm_buf);
+	} while(!z80_is_terminal(&inst));
+	return 1;
+}
+
 static uint8_t cmd_gen_m68k(debug_root *root, parsed_command *cmd)
 {
 	char *param = cmd->raw;
@@ -2619,6 +2680,16 @@
 		.impl = cmd_delete_z80,
 		.min_args = 1,
 		.max_args = 1
+	},
+	{
+		.names = (const char *[]){
+			"disassemble", "disasm", NULL
+		},
+		.usage = "disassemble [ADDRESS]",
+		.desc = "Disassemble code starting at ADDRESS if provided or the current address if not",
+		.impl = cmd_disassemble_z80,
+		.min_args = 0,
+		.max_args = 1
 	}
 };
 
@@ -3238,6 +3309,7 @@
 		root->read_mem = read_z80;
 		root->write_mem = write_z80;
 		root->set = set_z80;
+		root->disasm = create_z80_disasm();
 	}
 	return root;
 }