Mercurial > repos > blastem
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 } |