comparison dis.c @ 134:ab50421b1b7a

Improve disassembler
author Mike Pavone <pavone@retrodev.com>
date Sun, 30 Dec 2012 09:55:18 -0800
parents e821b6fde0e4
children cce22fb4c450
comparison
equal deleted inserted replaced
133:c4d10c2aaee2 134:ab50421b1b7a
1 #include "68kinst.h" 1 #include "68kinst.h"
2 #include <stdio.h> 2 #include <stdio.h>
3 #include <stdlib.h> 3 #include <stdlib.h>
4 4
5 uint8_t visited[(16*1024*1024)/16]; 5 uint8_t visited[(16*1024*1024)/16];
6 uint8_t label[(16*1024*1024)/16];
6 7
7 void visit(uint32_t address) 8 void visit(uint32_t address)
8 { 9 {
9 address &= 0xFFFFFF; 10 address &= 0xFFFFFF;
10 visited[address/16] |= 1 << ((address / 2) % 8); 11 visited[address/16] |= 1 << ((address / 2) % 8);
11 } 12 }
12 13
14 void reference(uint32_t address)
15 {
16 address &= 0xFFFFFF;
17 //printf("referenced: %X\n", address);
18 label[address/16] |= 1 << ((address / 2) % 8);
19 }
20
13 uint8_t is_visited(uint32_t address) 21 uint8_t is_visited(uint32_t address)
14 { 22 {
15 address &= 0xFFFFFF; 23 address &= 0xFFFFFF;
16 return visited[address/16] & (1 << ((address / 2) % 8)); 24 return visited[address/16] & (1 << ((address / 2) % 8));
25 }
26
27 uint8_t is_label(uint32_t address)
28 {
29 address &= 0xFFFFFF;
30 return label[address/16] & (1 << ((address / 2) % 8));
17 } 31 }
18 32
19 typedef struct deferred { 33 typedef struct deferred {
20 uint32_t address; 34 uint32_t address;
21 struct deferred *next; 35 struct deferred *next;
31 d->address = address; 45 d->address = address;
32 d->next = next; 46 d->next = next;
33 return d; 47 return d;
34 } 48 }
35 49
36 #define SIMPLE 0 50 void check_reference(m68kinst * inst, m68k_op_info * op)
51 {
52 switch(op->addr_mode)
53 {
54 case MODE_PC_DISPLACE:
55 reference(inst->address + 2 + op->params.regs.displacement);
56 break;
57 case MODE_ABSOLUTE:
58 case MODE_ABSOLUTE_SHORT:
59 reference(op->params.immed);
60 break;
61 }
62 }
63
64 uint8_t labels = 0;
65 uint8_t addr = 0;
37 66
38 int main(int argc, char ** argv) 67 int main(int argc, char ** argv)
39 { 68 {
40 long filesize; 69 long filesize;
41 unsigned short *filebuf; 70 unsigned short *filebuf;
47 filesize = ftell(f); 76 filesize = ftell(f);
48 fseek(f, 0, SEEK_SET); 77 fseek(f, 0, SEEK_SET);
49 filebuf = malloc(filesize); 78 filebuf = malloc(filesize);
50 fread(filebuf, 2, filesize/2, f); 79 fread(filebuf, 2, filesize/2, f);
51 fclose(f); 80 fclose(f);
81 for(uint8_t opt = 2; opt < argc; ++opt) {
82 if (argv[opt][0] == '-') {
83 switch (argv[opt][1])
84 {
85 case 'l':
86 labels = 1;
87 break;
88 case 'a':
89 addr = 1;
90 break;
91 }
92 }
93 }
52 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur) 94 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur)
53 { 95 {
54 *cur = (*cur >> 8) | (*cur << 8); 96 *cur = (*cur >> 8) | (*cur << 8);
55 } 97 }
56 uint32_t address = filebuf[2] << 16 | filebuf[3], tmp_addr; 98 uint32_t address = filebuf[2] << 16 | filebuf[3], tmp_addr;
57 #if !SIMPLE
58 uint16_t *encoded, *next; 99 uint16_t *encoded, *next;
59 uint32_t size; 100 uint32_t size;
60 deferred *def = NULL, *tmpd; 101 deferred *def = NULL, *tmpd;
61 def = defer(address, def); 102 def = defer(address, def);
62 def = defer(filebuf[0x68/2] << 16 | filebuf[0x6A/2], def); 103 def = defer(filebuf[0x68/2] << 16 | filebuf[0x6A/2], def);
84 next = m68k_decode(encoded, &instbuf, address); 125 next = m68k_decode(encoded, &instbuf, address);
85 address += (next-encoded)*2; 126 address += (next-encoded)*2;
86 encoded = next; 127 encoded = next;
87 //m68k_disasm(&instbuf, disbuf); 128 //m68k_disasm(&instbuf, disbuf);
88 //printf("%X: %s\n", instbuf.address, disbuf); 129 //printf("%X: %s\n", instbuf.address, disbuf);
130 check_reference(&instbuf, &(instbuf.src));
131 check_reference(&instbuf, &(instbuf.dst));
89 if (instbuf.op == M68K_ILLEGAL || instbuf.op == M68K_RTS || instbuf.op == M68K_RTE) { 132 if (instbuf.op == M68K_ILLEGAL || instbuf.op == M68K_RTS || instbuf.op == M68K_RTE) {
90 break; 133 break;
91 } else if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) { 134 } else if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) {
92 if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) { 135 if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) {
93 address = instbuf.address + 2 + instbuf.src.params.immed; 136 address = instbuf.address + 2 + instbuf.src.params.immed;
94 encoded = filebuf + address/2; 137 encoded = filebuf + address/2;
138 reference(address);
95 if (is_visited(address)) { 139 if (is_visited(address)) {
96 break; 140 break;
97 } 141 }
98 } else { 142 } else {
99 tmp_addr = instbuf.address + 2 + instbuf.src.params.immed; 143 tmp_addr = instbuf.address + 2 + instbuf.src.params.immed;
144 reference(tmp_addr);
100 def = defer(tmp_addr, def); 145 def = defer(tmp_addr, def);
101 } 146 }
102 } else if(instbuf.op == M68K_JMP) { 147 } else if(instbuf.op == M68K_JMP) {
103 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) { 148 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) {
104 address = instbuf.src.params.immed; 149 address = instbuf.src.params.immed;
122 def = defer(instbuf.src.params.regs.displacement + instbuf.address + 2, def); 167 def = defer(instbuf.src.params.regs.displacement + instbuf.address + 2, def);
123 } 168 }
124 } 169 }
125 } 170 }
126 } 171 }
172 if (labels) {
173 for (address = filesize; address < (16*1024*1024); address++) {
174 if (is_label(address)) {
175 printf("ADR_%X equ $%X\n", address, address);
176 }
177 }
178 puts("");
179 }
127 for (address = 0; address < filesize; address+=2) { 180 for (address = 0; address < filesize; address+=2) {
128 if (is_visited(address)) { 181 if (is_visited(address)) {
129 encoded = filebuf + address/2; 182 encoded = filebuf + address/2;
130 m68k_decode(encoded, &instbuf, address); 183 m68k_decode(encoded, &instbuf, address);
131 m68k_disasm(&instbuf, disbuf); 184 if (labels) {
132 printf("%X: %s\n", instbuf.address, disbuf); 185 m68k_disasm_labels(&instbuf, disbuf);
133 } 186 if (is_label(instbuf.address)) {
134 } 187 printf("ADR_%X:\n", instbuf.address);
135 #else 188 }
136 for(cur = filebuf + 0x100; (cur - filebuf) < (filesize/2); ) 189 if (addr) {
137 { 190 printf("\t%s\t;%X\n", disbuf, instbuf.address);
138 unsigned short * start = cur; 191 } else {
139 cur = m68k_decode(cur, &instbuf, (start - filebuf)*2); 192 printf("\t%s\n", disbuf);
140 m68k_disasm(&instbuf, disbuf); 193 }
141 printf("%X: %s\n", instbuf.address, disbuf); 194 } else {
142 } 195 m68k_disasm(&instbuf, disbuf);
143 #endif 196 printf("%X: %s\n", instbuf.address, disbuf);
197 }
198 }
199 }
144 return 0; 200 return 0;
145 } 201 }