changeset 2216:4e27c36f947c

Add disassemble command to debugger
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Aug 2022 18:42:45 -0700
parents a8af8d898a7c
children 8483c685cf03
files debug.c disasm.c disasm.h m68k_core.h m68k_internal.h
diffstat 5 files changed, 83 insertions(+), 2 deletions(-) [+]
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;
 }
--- a/disasm.c	Tue Aug 30 00:13:55 2022 -0700
+++ b/disasm.c	Tue Aug 30 18:42:45 2022 -0700
@@ -304,3 +304,11 @@
 	return context;
 }
 
+disasm_context *create_z80_disasm(void)
+{
+	disasm_context *context = calloc(1, sizeof(disasm_context));
+	context->address_mask = 0xFFFF;
+	context->invalid_inst_addr_mask = 0;
+	context->visit_preshift = 0;
+	return context;
+}
--- a/disasm.h	Tue Aug 30 00:13:55 2022 -0700
+++ b/disasm.h	Tue Aug 30 18:42:45 2022 -0700
@@ -36,5 +36,6 @@
 void add_segacd_maincpu_labels(disasm_context *context);
 void add_segacd_subcpu_labels(disasm_context *context);
 disasm_context *create_68000_disasm(void);
+disasm_context *create_z80_disasm(void);
 
 #endif //DISASM_H_
--- a/m68k_core.h	Tue Aug 30 00:13:55 2022 -0700
+++ b/m68k_core.h	Tue Aug 30 18:42:45 2022 -0700
@@ -10,7 +10,7 @@
 #include "backend.h"
 #include "serialize.h"
 //#include "68kinst.h"
-struct m68kinst;
+typedef struct m68kinst m68kinst;
 
 #define NUM_MEM_AREAS 10
 #define NATIVE_MAP_CHUNKS (64*1024)
@@ -122,6 +122,7 @@
 void m68k_serialize(m68k_context *context, uint32_t pc, serialize_buffer *buf);
 void m68k_deserialize(deserialize_buffer *buf, void *vcontext);
 uint16_t m68k_instruction_fetch(uint32_t address, void *vcontext);
+uint8_t m68k_is_terminal(m68kinst * inst);
 
 #endif //M68K_CORE_H_
 
--- a/m68k_internal.h	Tue Aug 30 00:13:55 2022 -0700
+++ b/m68k_internal.h	Tue Aug 30 18:42:45 2022 -0700
@@ -50,7 +50,6 @@
 void jump_m68k_abs(m68k_options * opts, uint32_t address);
 void swap_ssp_usp(m68k_options * opts);
 code_ptr get_native_address(m68k_options *opts, uint32_t address);
-uint8_t m68k_is_terminal(m68kinst * inst);
 code_ptr get_native_address_trans(m68k_context * context, uint32_t address);
 void * m68k_retranslate_inst(uint32_t address, m68k_context * context);
 m68k_context *m68k_bp_dispatcher(m68k_context *context, uint32_t address);