changeset 634:4a6ec64acd79

Better support for labels sourced from VOS program module header
author Michael Pavone <pavone@retrodev.com>
date Sat, 11 Oct 2014 22:18:49 -0700
parents a759f4e38488
children 6992a1b07714
files 68kinst.c 68kinst.h dis.c
diffstat 3 files changed, 63 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/68kinst.c	Sat Oct 11 21:42:33 2014 -0700
+++ b/68kinst.c	Sat Oct 11 22:18:49 2014 -0700
@@ -1533,7 +1533,7 @@
 };
 #endif
 
-int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address)
+int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data)
 {
 	char * c = need_comma ? "," : "";
 	switch(decoded->addr_mode)
@@ -1556,20 +1556,29 @@
 	case MODE_IMMEDIATE_WORD:
 		return sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed);
 	case MODE_ABSOLUTE_SHORT:
-		if (labels) {
-			return sprintf(dst, "%s ADR_%X.w", c, decoded->params.immed);
+		if (labels) {	
+			int ret = sprintf(dst, "%s ", c);
+			ret += label_fun(dst+ret, decoded->params.immed, data);
+			strcat(dst+ret, ".w");
+			return ret + 2;
 		} else {
 			return sprintf(dst, "%s $%X.w", c, decoded->params.immed);
 		}
 	case MODE_ABSOLUTE:
 		if (labels) {
-			return sprintf(dst, "%s ADR_%X.l", c, decoded->params.immed);
+			int ret = sprintf(dst, "%s ", c);
+			ret += label_fun(dst+ret, decoded->params.immed, data);
+			strcat(dst+ret, ".l");
+			return ret + 2;
 		} else {
 			return sprintf(dst, "%s $%X", c, decoded->params.immed);
 		}
 	case MODE_PC_DISPLACE:
 		if (labels) {
-			return sprintf(dst, "%s ADR_%X(pc)", c, address + 2 + decoded->params.regs.displacement);
+			int ret = sprintf(dst, "%s ", c);
+			ret += label_fun(dst+ret, address + 2 + decoded->params.regs.displacement, data);
+			strcat(dst+ret, "(pc)");
+			return ret + 4;
 		} else {
 			return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement);
 		}
@@ -1580,7 +1589,7 @@
 	}
 }
 
-int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address)
+int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address, format_label_fun label_fun, void * data)
 {
 	int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1;
 	char *rtype, *last_rtype;
@@ -1634,11 +1643,16 @@
 		}
 		return oplen;
 	} else {
-		return m68k_disasm_op(decoded, dst, need_comma, labels, address);
+		return m68k_disasm_op(decoded, dst, need_comma, labels, address, label_fun, data);
 	}
 }
 
-int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels)
+int m68k_default_label_fun(char * dst, uint32_t address, void * data)
+{
+	return sprintf(dst, "ADR_%X", address);
+}
+
+int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels, format_label_fun label_fun, void * data)
 {
 	int ret,op1len;
 	uint8_t size;
@@ -1656,9 +1670,11 @@
 		if (decoded->op != M68K_SCC) {
 			if (labels) {
 				if (decoded->op == M68K_DBCC) {
-					ret += sprintf(dst+ret, " d%d, ADR_%X", decoded->dst.params.regs.pri, decoded->address + 2 + decoded->src.params.immed);
+					ret += sprintf(dst+ret, " d%d, ", decoded->dst.params.regs.pri);
+					ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data);
 				} else {
-					ret += sprintf(dst+ret, " ADR_%X", decoded->address + 2 + decoded->src.params.immed);
+					dst[ret++] = ' ';
+					ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data);
 				}
 			} else {
 				if (decoded->op == M68K_DBCC) {
@@ -1672,8 +1688,8 @@
 		break;
 	case M68K_BSR:
 		if (labels) {
-			ret = sprintf(dst, "bsr%s ADR_%X", decoded->variant == VAR_BYTE ? ".s" : "",
-			decoded->address + 2 + decoded->src.params.immed);
+			ret = sprintf(dst, "bsr%s ", decoded->variant == VAR_BYTE ? ".s" : "");
+			ret += label_fun(dst+ret, decoded->address + 2 + decoded->src.params.immed, data);
 		} else {
 			ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
 		}
@@ -1681,7 +1697,7 @@
 	case M68K_MOVE_FROM_SR:
 		ret = sprintf(dst, "%s", mnemonics[decoded->op]);
 		ret += sprintf(dst + ret, " SR");
-		ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address);
+		ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address, label_fun, data);
 		return ret;
 	case M68K_ANDI_SR:
 	case M68K_EORI_SR:
@@ -1693,17 +1709,17 @@
 	case M68K_MOVE_CCR:
 	case M68K_ORI_CCR:
 		ret = sprintf(dst, "%s", mnemonics[decoded->op]);
-		ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
+		ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data);
 		ret += sprintf(dst + ret, ", %s", special_op);
 		return ret;
 	case M68K_MOVE_USP:
 		ret = sprintf(dst, "%s", mnemonics[decoded->op]);
 		if (decoded->src.addr_mode != MODE_UNUSED) {
-			ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
+			ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data);
 			ret += sprintf(dst + ret, ", USP");
 		} else {
 			ret += sprintf(dst + ret, "USP, ");
-			ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address);
+			ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data);
 		}
 		return ret;
 	case M68K_INVALID:
@@ -1714,9 +1730,9 @@
 		ret = sprintf(dst, "%s ", mnemonics[decoded->op]);
 		if (decoded->src.addr_mode == MODE_UNUSED) {
 			ret += sprintf(dst + ret, "%s, ", cr_mnem[decoded->src.params.immed]);
-			ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address);
+			ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data);
 		} else {
-			ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
+			ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data);
 			ret += sprintf(dst + ret, ", %s", cr_mnem[decoded->dst.params.immed]);
 		}
 		return ret;
@@ -1729,23 +1745,27 @@
 				size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : "")));
 	}
 	if (decoded->op == M68K_MOVEM) {
-		op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address);
+		op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address, label_fun, data);
 		ret += op1len;
-		ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address);
+		ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address, label_fun, data);
 	} else {
-		op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
+		op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address, label_fun, data);
 		ret += op1len;
-		ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address);
+		ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address, label_fun, data);
 	}
 	return ret;
 }
 
 int m68k_disasm(m68kinst * decoded, char * dst)
 {
-	return m68k_disasm_ex(decoded, dst, 0);
+	return m68k_disasm_ex(decoded, dst, 0, NULL, NULL);
 }
 
-int m68k_disasm_labels(m68kinst * decoded, char * dst)
+int m68k_disasm_labels(m68kinst * decoded, char * dst, format_label_fun label_fun, void * data)
 {
-	return m68k_disasm_ex(decoded, dst, 1);
+	if (!label_fun)
+	{
+		label_fun = m68k_default_label_fun;
+	}
+	return m68k_disasm_ex(decoded, dst, 1, label_fun, data);
 }
--- a/68kinst.h	Sat Oct 11 21:42:33 2014 -0700
+++ b/68kinst.h	Sat Oct 11 22:18:49 2014 -0700
@@ -298,12 +298,15 @@
 	VECTOR_TRAP_15
 } m68k_vector;
 
+typedef int (*format_label_fun)(char * dst, uint32_t address, void * data);
+
 uint16_t * m68k_decode(uint16_t * istream, m68kinst * dst, uint32_t address);
 uint32_t m68k_branch_target(m68kinst * inst, uint32_t *dregs, uint32_t *aregs);
 uint8_t m68k_is_branch(m68kinst * inst);
 uint8_t m68k_is_noncall_branch(m68kinst * inst);
 int m68k_disasm(m68kinst * decoded, char * dst);
-int m68k_disasm_labels(m68kinst * decoded, char * dst);
+int m68k_disasm_labels(m68kinst * decoded, char * dst, format_label_fun label_fun, void * data);
+int m68k_default_label_fun(char * dst, uint32_t address, void * data);
 
 #endif
 
--- a/dis.c	Sat Oct 11 21:42:33 2014 -0700
+++ b/dis.c	Sat Oct 11 22:18:49 2014 -0700
@@ -99,6 +99,19 @@
 	}
 }
 
+int label_fun(char *dst, uint32_t address, void * data)
+{
+	tern_node * labels = data;
+	char key[MAX_INT_KEY_SIZE];
+	label_names * names = tern_find_ptr(labels, tern_int_key(address & 0xFFFFFF, key));
+	if (names)
+	{
+		return sprintf(dst, "%s", names->labels[0]);
+	} else {
+		return m68k_default_label_fun(dst, address, NULL);
+	}
+}
+
 int main(int argc, char ** argv)
 {
 	long filesize;
@@ -310,7 +323,7 @@
 			encoded = filebuf + (address-address_off)/2;
 			m68k_decode(encoded, &instbuf, address);
 			if (labels) {
-				m68k_disasm_labels(&instbuf, disbuf);
+				m68k_disasm_labels(&instbuf, disbuf, label_fun, named_labels);
 				char keybuf[MAX_INT_KEY_SIZE];
 				label_names * names = tern_find_ptr(named_labels, tern_int_key(address, keybuf));
 				if (names)