# HG changeset patch # User Michael Pavone # Date 1413091129 25200 # Node ID 4a6ec64acd79874b31779f15dfd99f4cf600c9b9 # Parent a759f4e3848834d1b077d548376f010a07cbf97f Better support for labels sourced from VOS program module header diff -r a759f4e38488 -r 4a6ec64acd79 68kinst.c --- 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); } diff -r a759f4e38488 -r 4a6ec64acd79 68kinst.h --- 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 diff -r a759f4e38488 -r 4a6ec64acd79 dis.c --- 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)