summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--68kinst.c72
-rw-r--r--68kinst.h1
-rw-r--r--dis.c82
3 files changed, 123 insertions, 32 deletions
diff --git a/68kinst.c b/68kinst.c
index 4c1a0fa..7a7c239 100644
--- a/68kinst.c
+++ b/68kinst.c
@@ -1156,7 +1156,7 @@ char * cond_mnem[] = {
"le"
};
-int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma)
+int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma, uint8_t labels, uint32_t address)
{
char * c = need_comma ? "," : "";
switch(decoded->addr_mode)
@@ -1179,11 +1179,23 @@ int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma)
case MODE_IMMEDIATE_WORD:
return sprintf(dst, (decoded->params.immed <= 128 ? "%s #%d" : "%s #$%X"), c, decoded->params.immed);
case MODE_ABSOLUTE_SHORT:
- return sprintf(dst, "%s $%X.w", c, decoded->params.immed);
+ if (labels) {
+ return sprintf(dst, "%s ADDR_%X.w", c, decoded->params.immed);
+ } else {
+ return sprintf(dst, "%s $%X.w", c, decoded->params.immed);
+ }
case MODE_ABSOLUTE:
- return sprintf(dst, "%s $%X", c, decoded->params.immed);
+ if (labels) {
+ return sprintf(dst, "%s ADDR_%X.l", c, decoded->params.immed);
+ } else {
+ return sprintf(dst, "%s $%X", c, decoded->params.immed);
+ }
case MODE_PC_DISPLACE:
- return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement);
+ if (labels) {
+ return sprintf(dst, "%s ADDR_%X(pc)", c, address + 2 + decoded->params.regs.displacement);
+ } else {
+ return sprintf(dst, "%s (%d, pc)", c, decoded->params.regs.displacement);
+ }
case MODE_PC_INDEX_DISP8:
return sprintf(dst, "%s (%d, pc, %c%d.%c)", c, decoded->params.regs.displacement, (decoded->params.regs.sec & 0x10) ? 'a': 'd', (decoded->params.regs.sec >> 1) & 0x7, (decoded->params.regs.sec & 1) ? 'l': 'w');
default:
@@ -1191,7 +1203,7 @@ int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma)
}
}
-int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma)
+int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma, uint8_t labels, uint32_t address)
{
int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1;
char *rtype, *last_rtype;
@@ -1245,11 +1257,11 @@ int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst,
}
return oplen;
} else {
- return m68k_disasm_op(decoded, dst, need_comma);
+ return m68k_disasm_op(decoded, dst, need_comma, labels, address);
}
}
-int m68k_disasm(m68kinst * decoded, char * dst)
+int m68k_disasm_ex(m68kinst * decoded, char * dst, uint8_t labels)
{
int ret,op1len;
uint8_t size;
@@ -1265,21 +1277,34 @@ int m68k_disasm(m68kinst * decoded, char * dst)
strcpy(dst+ret, cond_mnem[decoded->extra.cond]);
ret = strlen(dst);
if (decoded->op != M68K_SCC) {
- if (decoded->op == M68K_DBCC) {
- ret += sprintf(dst+ret, " d%d, #%d <%X>", decoded->dst.params.regs.pri, decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
+ if (labels) {
+ if (decoded->op == M68K_DBCC) {
+ ret += sprintf(dst+ret, " d%d, ADDR_%X", decoded->dst.params.regs.pri, decoded->address + 2 + decoded->src.params.immed);
+ } else {
+ ret += sprintf(dst+ret, " ADDR_%X", decoded->address + 2 + decoded->src.params.immed);
+ }
} else {
- ret += sprintf(dst+ret, " #%d <%X>", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
+ if (decoded->op == M68K_DBCC) {
+ ret += sprintf(dst+ret, " d%d, #%d <%X>", decoded->dst.params.regs.pri, decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
+ } else {
+ ret += sprintf(dst+ret, " #%d <%X>", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
+ }
}
return ret;
}
break;
case M68K_BSR:
- ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
+ if (labels) {
+ ret = sprintf(dst, "bsr%s ADDR_%X", decoded->variant == VAR_BYTE ? ".s" : "",
+ decoded->address + 2 + decoded->src.params.immed);
+ } else {
+ ret = sprintf(dst, "bsr%s #%d <%X>", decoded->variant == VAR_BYTE ? ".s" : "", decoded->src.params.immed, decoded->address + 2 + decoded->src.params.immed);
+ }
return ret;
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);
+ ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1, labels, decoded->address);
return ret;
case M68K_ANDI_SR:
case M68K_EORI_SR:
@@ -1291,17 +1316,17 @@ int m68k_disasm(m68kinst * decoded, char * dst)
case M68K_MOVE_CCR:
case M68K_ORI_CCR:
ret = sprintf(dst, "%s", mnemonics[decoded->op]);
- ret += m68k_disasm_op(&(decoded->src), dst + ret, 0);
+ ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
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);
+ ret += m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
ret += sprintf(dst + ret, ", USP");
} else {
ret += sprintf(dst + ret, "USP, ");
- ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0);
+ ret += m68k_disasm_op(&(decoded->dst), dst + ret, 0, labels, decoded->address);
}
return ret;
default:
@@ -1312,14 +1337,23 @@ int m68k_disasm(m68kinst * decoded, char * dst)
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);
+ op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0, labels, decoded->address);
ret += op1len;
- ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len);
+ ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len, labels, decoded->address);
} else {
- op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0);
+ op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0, labels, decoded->address);
ret += op1len;
- ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len);
+ ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len, labels, decoded->address);
}
return ret;
}
+int m68k_disasm(m68kinst * decoded, char * dst)
+{
+ return m68k_disasm_ex(decoded, dst, 0);
+}
+
+int m68k_disasm_labels(m68kinst * decoded, char * dst)
+{
+ return m68k_disasm_ex(decoded, dst, 1);
+}
diff --git a/68kinst.h b/68kinst.h
index a43a775..f1aba46 100644
--- a/68kinst.h
+++ b/68kinst.h
@@ -185,6 +185,7 @@ typedef struct {
uint16_t * m68k_decode(uint16_t * istream, m68kinst * dst, uint32_t address);
uint32_t m68k_cycles(m68kinst * inst);
int m68k_disasm(m68kinst * decoded, char * dst);
+int m68k_disasm_labels(m68kinst * decoded, char * dst);
#endif
diff --git a/dis.c b/dis.c
index e99b332..41f6a30 100644
--- a/dis.c
+++ b/dis.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
uint8_t visited[(16*1024*1024)/16];
+uint8_t label[(16*1024*1024)/16];
void visit(uint32_t address)
{
@@ -10,12 +11,25 @@ void visit(uint32_t address)
visited[address/16] |= 1 << ((address / 2) % 8);
}
+void reference(uint32_t address)
+{
+ address &= 0xFFFFFF;
+ //printf("referenced: %X\n", address);
+ label[address/16] |= 1 << ((address / 2) % 8);
+}
+
uint8_t is_visited(uint32_t address)
{
address &= 0xFFFFFF;
return visited[address/16] & (1 << ((address / 2) % 8));
}
+uint8_t is_label(uint32_t address)
+{
+ address &= 0xFFFFFF;
+ return label[address/16] & (1 << ((address / 2) % 8));
+}
+
typedef struct deferred {
uint32_t address;
struct deferred *next;
@@ -33,7 +47,22 @@ deferred * defer(uint32_t address, deferred * next)
return d;
}
-#define SIMPLE 0
+void check_reference(m68kinst * inst, m68k_op_info * op)
+{
+ switch(op->addr_mode)
+ {
+ case MODE_PC_DISPLACE:
+ reference(inst->address + 2 + op->params.regs.displacement);
+ break;
+ case MODE_ABSOLUTE:
+ case MODE_ABSOLUTE_SHORT:
+ reference(op->params.immed);
+ break;
+ }
+}
+
+uint8_t labels = 0;
+uint8_t addr = 0;
int main(int argc, char ** argv)
{
@@ -49,12 +78,24 @@ int main(int argc, char ** argv)
filebuf = malloc(filesize);
fread(filebuf, 2, filesize/2, f);
fclose(f);
+ for(uint8_t opt = 2; opt < argc; ++opt) {
+ if (argv[opt][0] == '-') {
+ switch (argv[opt][1])
+ {
+ case 'l':
+ labels = 1;
+ break;
+ case 'a':
+ addr = 1;
+ break;
+ }
+ }
+ }
for(cur = filebuf; cur - filebuf < (filesize/2); ++cur)
{
*cur = (*cur >> 8) | (*cur << 8);
}
uint32_t address = filebuf[2] << 16 | filebuf[3], tmp_addr;
- #if !SIMPLE
uint16_t *encoded, *next;
uint32_t size;
deferred *def = NULL, *tmpd;
@@ -86,17 +127,21 @@ int main(int argc, char ** argv)
encoded = next;
//m68k_disasm(&instbuf, disbuf);
//printf("%X: %s\n", instbuf.address, disbuf);
+ check_reference(&instbuf, &(instbuf.src));
+ check_reference(&instbuf, &(instbuf.dst));
if (instbuf.op == M68K_ILLEGAL || instbuf.op == M68K_RTS || instbuf.op == M68K_RTE) {
break;
} else if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) {
if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) {
address = instbuf.address + 2 + instbuf.src.params.immed;
encoded = filebuf + address/2;
+ reference(address);
if (is_visited(address)) {
break;
}
} else {
tmp_addr = instbuf.address + 2 + instbuf.src.params.immed;
+ reference(tmp_addr);
def = defer(tmp_addr, def);
}
} else if(instbuf.op == M68K_JMP) {
@@ -124,22 +169,33 @@ int main(int argc, char ** argv)
}
}
}
+ if (labels) {
+ for (address = filesize; address < (16*1024*1024); address++) {
+ if (is_label(address)) {
+ printf("ADR_%X equ $%X\n", address, address);
+ }
+ }
+ puts("");
+ }
for (address = 0; address < filesize; address+=2) {
if (is_visited(address)) {
encoded = filebuf + address/2;
m68k_decode(encoded, &instbuf, address);
- m68k_disasm(&instbuf, disbuf);
- printf("%X: %s\n", instbuf.address, disbuf);
+ if (labels) {
+ m68k_disasm_labels(&instbuf, disbuf);
+ if (is_label(instbuf.address)) {
+ printf("ADR_%X:\n", instbuf.address);
+ }
+ if (addr) {
+ printf("\t%s\t;%X\n", disbuf, instbuf.address);
+ } else {
+ printf("\t%s\n", disbuf);
+ }
+ } else {
+ m68k_disasm(&instbuf, disbuf);
+ printf("%X: %s\n", instbuf.address, disbuf);
+ }
}
}
- #else
- for(cur = filebuf + 0x100; (cur - filebuf) < (filesize/2); )
- {
- unsigned short * start = cur;
- cur = m68k_decode(cur, &instbuf, (start - filebuf)*2);
- m68k_disasm(&instbuf, disbuf);
- printf("%X: %s\n", instbuf.address, disbuf);
- }
- #endif
return 0;
}