comparison dis.c @ 652:f822d9216968

Merge
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Dec 2014 19:11:34 -0800
parents 316facea756d c806b96b86eb
children 1a14f5f6c6a1
comparison
equal deleted inserted replaced
620:9d6fed6501ba 652:f822d9216968
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */ 5 */
6 #include "68kinst.h" 6 #include "68kinst.h"
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <string.h>
10 #include "vos_program_module.h"
11 #include "tern.h"
9 12
10 uint8_t visited[(16*1024*1024)/16]; 13 uint8_t visited[(16*1024*1024)/16];
11 uint8_t label[(16*1024*1024)/8]; 14 uint16_t label[(16*1024*1024)/8];
12 15
13 void visit(uint32_t address) 16 void visit(uint32_t address)
14 { 17 {
15 address &= 0xFFFFFF; 18 address &= 0xFFFFFF;
16 visited[address/16] |= 1 << ((address / 2) % 8); 19 visited[address/16] |= 1 << ((address / 2) % 8);
18 21
19 void reference(uint32_t address) 22 void reference(uint32_t address)
20 { 23 {
21 address &= 0xFFFFFF; 24 address &= 0xFFFFFF;
22 //printf("referenced: %X\n", address); 25 //printf("referenced: %X\n", address);
23 label[address/16] |= 1 << (address % 8); 26 label[address/16] |= 1 << (address % 16);
24 } 27 }
25 28
26 uint8_t is_visited(uint32_t address) 29 uint8_t is_visited(uint32_t address)
27 { 30 {
28 address &= 0xFFFFFF; 31 address &= 0xFFFFFF;
29 return visited[address/16] & (1 << ((address / 2) % 8)); 32 return visited[address/16] & (1 << ((address / 2) % 8));
30 } 33 }
31 34
32 uint8_t is_label(uint32_t address) 35 uint16_t is_label(uint32_t address)
33 { 36 {
34 address &= 0xFFFFFF; 37 address &= 0xFFFFFF;
35 return label[address/16] & (1 << (address % 8)); 38 return label[address/16] & (1 << (address % 16));
39 }
40
41 typedef struct {
42 uint32_t num_labels;
43 uint32_t storage;
44 char *labels[];
45 } label_names;
46
47 tern_node * add_label(tern_node * head, char * name, uint32_t address)
48 {
49 char key[MAX_INT_KEY_SIZE];
50 address &= 0xFFFFFF;
51 reference(address);
52 tern_int_key(address, key);
53 label_names * names = tern_find_ptr(head, key);
54 if (names)
55 {
56 if (names->num_labels == names->storage)
57 {
58 names->storage = names->storage + (names->storage >> 1);
59 names = realloc(names, sizeof(label_names) + names->storage * sizeof(char *));
60 }
61 } else {
62 names = malloc(sizeof(label_names) + 4 * sizeof(char *));
63 names->num_labels = 0;
64 names->storage = 4;
65 head = tern_insert_ptr(head, key, names);
66 }
67 names->labels[names->num_labels++] = strdup(name);
68 return head;
36 } 69 }
37 70
38 typedef struct deferred { 71 typedef struct deferred {
39 uint32_t address; 72 uint32_t address;
40 struct deferred *next; 73 struct deferred *next;
41 } deferred; 74 } deferred;
42 75
43 deferred * defer(uint32_t address, deferred * next) 76 deferred * defer(uint32_t address, deferred * next)
44 { 77 {
45 if (is_visited(address)) { 78 if (is_visited(address) || address & 1) {
46 return next; 79 return next;
47 } 80 }
48 //printf("deferring %X\n", address); 81 //printf("deferring %X\n", address);
49 deferred * d = malloc(sizeof(deferred)); 82 deferred * d = malloc(sizeof(deferred));
50 d->address = address; 83 d->address = address;
64 reference(op->params.immed); 97 reference(op->params.immed);
65 break; 98 break;
66 } 99 }
67 } 100 }
68 101
69 uint8_t labels = 0; 102 int label_fun(char *dst, uint32_t address, void * data)
70 uint8_t addr = 0; 103 {
71 uint8_t only = 0; 104 tern_node * labels = data;
105 char key[MAX_INT_KEY_SIZE];
106 label_names * names = tern_find_ptr(labels, tern_int_key(address & 0xFFFFFF, key));
107 if (names)
108 {
109 return sprintf(dst, "%s", names->labels[0]);
110 } else {
111 return m68k_default_label_fun(dst, address, NULL);
112 }
113 }
72 114
73 int main(int argc, char ** argv) 115 int main(int argc, char ** argv)
74 { 116 {
75 long filesize; 117 long filesize;
76 unsigned short *filebuf; 118 unsigned short *filebuf;
77 char disbuf[1024]; 119 char disbuf[1024];
78 m68kinst instbuf; 120 m68kinst instbuf;
79 unsigned short * cur; 121 unsigned short * cur;
80 FILE * f = fopen(argv[1], "rb");
81 fseek(f, 0, SEEK_END);
82 filesize = ftell(f);
83 fseek(f, 0, SEEK_SET);
84 filebuf = malloc(filesize);
85 fread(filebuf, 2, filesize/2, f);
86 fclose(f);
87 deferred *def = NULL, *tmpd; 122 deferred *def = NULL, *tmpd;
123
124 uint8_t labels = 0, addr = 0, only = 0, vos = 0, reset = 0;
125
88 for(uint8_t opt = 2; opt < argc; ++opt) { 126 for(uint8_t opt = 2; opt < argc; ++opt) {
89 if (argv[opt][0] == '-') { 127 if (argv[opt][0] == '-') {
90 FILE * address_log; 128 FILE * address_log;
91 switch (argv[opt][1]) 129 switch (argv[opt][1])
92 { 130 {
97 addr = 1; 135 addr = 1;
98 break; 136 break;
99 case 'o': 137 case 'o':
100 only = 1; 138 only = 1;
101 break; 139 break;
140 case 'v':
141 vos = 1;
142 break;
143 case 'r':
144 reset = 1;
145 break;
102 case 'f': 146 case 'f':
103 opt++; 147 opt++;
104 if (opt >= argc) { 148 if (opt >= argc) {
105 fputs("-f must be followed by a filename\n", stderr); 149 fputs("-f must be followed by a filename\n", stderr);
106 exit(1); 150 exit(1);
124 uint32_t address = strtol(argv[opt], NULL, 16); 168 uint32_t address = strtol(argv[opt], NULL, 16);
125 def = defer(address, def); 169 def = defer(address, def);
126 reference(address); 170 reference(address);
127 } 171 }
128 } 172 }
129 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur) 173
174 FILE * f = fopen(argv[1], "rb");
175 fseek(f, 0, SEEK_END);
176 filesize = ftell(f);
177 fseek(f, 0, SEEK_SET);
178
179 tern_node * named_labels = NULL;
180 char int_key[MAX_INT_KEY_SIZE];
181 uint32_t address_off, address_end;
182 if (vos)
130 { 183 {
131 *cur = (*cur >> 8) | (*cur << 8); 184 vos_program_module header;
132 } 185 vos_read_header(f, &header);
133 uint32_t start = filebuf[2] << 16 | filebuf[3], tmp_addr; 186 vos_read_alloc_module_map(f, &header);
134 uint32_t int_2 = filebuf[0x68/2] << 16 | filebuf[0x6A/2]; 187 address_off = header.user_boundary;
135 uint32_t int_4 = filebuf[0x70/2] << 16 | filebuf[0x72/2]; 188 address_end = address_off + filesize - 0x1000;
136 uint32_t int_6 = filebuf[0x78/2] << 16 | filebuf[0x7A/2]; 189 def = defer(header.main_entry_link.code_address, def);
190 named_labels = add_label(named_labels, "main_entry_link", header.main_entry_link.code_address);
191 for (int i = 0; i < header.n_modules; i++)
192 {
193 if (!reset || header.module_map_entries[i].code_address != header.user_boundary)
194 {
195 def = defer(header.module_map_entries[i].code_address, def);
196 }
197 named_labels = add_label(named_labels, header.module_map_entries[i].name.str, header.module_map_entries[i].code_address);
198 }
199 fseek(f, 0x1000, SEEK_SET);
200 filebuf = malloc(filesize - 0x1000);
201 if (fread(filebuf, 2, (filesize - 0x1000)/2, f) != (filesize - 0x1000)/2)
202 {
203 fprintf(stderr, "Failure while reading file %s\n", argv[1]);
204 }
205 fclose(f);
206 for(cur = filebuf; cur - filebuf < ((filesize - 0x1000)/2); ++cur)
207 {
208 *cur = (*cur >> 8) | (*cur << 8);
209 }
210 if (reset)
211 {
212 def = defer(filebuf[2] << 16 | filebuf[3], def);
213 named_labels = add_label(named_labels, "reset", filebuf[2] << 16 | filebuf[3]);
214 }
215 } else {
216 address_off = 0;
217 address_end = filesize;
218 filebuf = malloc(filesize);
219 if (fread(filebuf, 2, filesize/2, f) != filesize/2)
220 {
221 fprintf(stderr, "Failure while reading file %s\n", argv[1]);
222 }
223 fclose(f);
224 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur)
225 {
226 *cur = (*cur >> 8) | (*cur << 8);
227 }
228 uint32_t start = filebuf[2] << 16 | filebuf[3];
229 uint32_t int_2 = filebuf[0x68/2] << 16 | filebuf[0x6A/2];
230 uint32_t int_4 = filebuf[0x70/2] << 16 | filebuf[0x72/2];
231 uint32_t int_6 = filebuf[0x78/2] << 16 | filebuf[0x7A/2];
232 named_labels = add_label(named_labels, "start", start);
233 named_labels = add_label(named_labels, "int_2", int_2);
234 named_labels = add_label(named_labels, "int_4", int_4);
235 named_labels = add_label(named_labels, "int_6", int_6);
236 if (!def || !only) {
237 def = defer(start, def);
238 def = defer(int_2, def);
239 def = defer(int_4, def);
240 def = defer(int_6, def);
241 }
242 }
137 uint16_t *encoded, *next; 243 uint16_t *encoded, *next;
138 uint32_t size; 244 uint32_t size, tmp_addr;
139 if (!def || !only) {
140 def = defer(start, def);
141 def = defer(int_2, def);
142 def = defer(int_4, def);
143 def = defer(int_6, def);
144 }
145 uint32_t address; 245 uint32_t address;
146 while(def) { 246 while(def) {
147 do { 247 do {
148 encoded = NULL; 248 encoded = NULL;
149 address = def->address; 249 address = def->address;
150 if (!is_visited(address)) { 250 if (!is_visited(address)) {
151 encoded = filebuf + address/2; 251 encoded = filebuf + (address - address_off)/2;
152 } 252 }
153 tmpd = def; 253 tmpd = def;
154 def = def->next; 254 def = def->next;
155 free(tmpd); 255 free(tmpd);
156 } while(def && encoded == NULL); 256 } while(def && encoded == NULL);
157 if (!encoded) { 257 if (!encoded) {
158 break; 258 break;
159 } 259 }
160 for(;;) { 260 for(;;) {
161 if (address > filesize) { 261 if (address > address_end || address < address_off) {
162 break; 262 break;
163 } 263 }
164 visit(address); 264 visit(address);
165 next = m68k_decode(encoded, &instbuf, address); 265 next = m68k_decode(encoded, &instbuf, address);
166 address += (next-encoded)*2; 266 address += (next-encoded)*2;
173 break; 273 break;
174 } 274 }
175 if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) { 275 if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) {
176 if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) { 276 if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) {
177 address = instbuf.address + 2 + instbuf.src.params.immed; 277 address = instbuf.address + 2 + instbuf.src.params.immed;
178 encoded = filebuf + address/2; 278 encoded = filebuf + (address - address_off)/2;
179 reference(address); 279 reference(address);
180 if (is_visited(address)) { 280 if (is_visited(address)) {
181 break; 281 break;
182 } 282 }
183 } else { 283 } else {
186 def = defer(tmp_addr, def); 286 def = defer(tmp_addr, def);
187 } 287 }
188 } else if(instbuf.op == M68K_JMP) { 288 } else if(instbuf.op == M68K_JMP) {
189 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) { 289 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) {
190 address = instbuf.src.params.immed; 290 address = instbuf.src.params.immed;
191 encoded = filebuf + address/2; 291 encoded = filebuf + (address - address_off)/2;
192 if (is_visited(address)) { 292 if (is_visited(address)) {
193 break; 293 break;
194 } 294 }
195 } else if (instbuf.src.addr_mode == MODE_PC_DISPLACE) { 295 } else if (instbuf.src.addr_mode == MODE_PC_DISPLACE) {
196 address = instbuf.src.params.regs.displacement + instbuf.address + 2; 296 address = instbuf.src.params.regs.displacement + instbuf.address + 2;
197 encoded = filebuf + address/2; 297 encoded = filebuf + (address - address_off)/2;
198 if (is_visited(address)) { 298 if (is_visited(address)) {
199 break; 299 break;
200 } 300 }
201 } else { 301 } else {
202 break; 302 break;
209 } 309 }
210 } 310 }
211 } 311 }
212 } 312 }
213 if (labels) { 313 if (labels) {
314 for (address = 0; address < address_off; address++) {
315 if (is_label(address)) {
316 printf("ADR_%X equ $%X\n", address, address);
317 }
318 }
214 for (address = filesize; address < (16*1024*1024); address++) { 319 for (address = filesize; address < (16*1024*1024); address++) {
215 if (is_label(address)) { 320 if (is_label(address)) {
216 printf("ADR_%X equ $%X\n", address, address); 321 printf("ADR_%X equ $%X\n", address, address);
217 } 322 }
218 } 323 }
219 puts(""); 324 puts("");
220 } 325 }
221 for (address = 0; address < filesize; address+=2) { 326 for (address = address_off; address < address_end; address+=2) {
222 if (is_visited(address)) { 327 if (is_visited(address)) {
223 encoded = filebuf + address/2; 328 encoded = filebuf + (address-address_off)/2;
224 m68k_decode(encoded, &instbuf, address); 329 m68k_decode(encoded, &instbuf, address);
225 if (labels) { 330 if (labels) {
226 m68k_disasm_labels(&instbuf, disbuf); 331 m68k_disasm_labels(&instbuf, disbuf, label_fun, named_labels);
227 if (address == start) { 332 char keybuf[MAX_INT_KEY_SIZE];
228 puts("start:"); 333 label_names * names = tern_find_ptr(named_labels, tern_int_key(address, keybuf));
229 } 334 if (names)
230 if(address == int_2) { 335 {
231 puts("int_2:"); 336 for (int i = 0; i < names->num_labels; i++)
232 } 337 {
233 if(address == int_4) { 338 printf("%s:\n", names->labels[i]);
234 puts("int_4:"); 339 }
235 } 340 } else if (is_label(instbuf.address)) {
236 if(address == int_6) {
237 puts("int_6:");
238 }
239 if (is_label(instbuf.address)) {
240 printf("ADR_%X:\n", instbuf.address); 341 printf("ADR_%X:\n", instbuf.address);
241 } 342 }
242 if (addr) { 343 if (addr) {
243 printf("\t%s\t;%X\n", disbuf, instbuf.address); 344 printf("\t%s\t;%X\n", disbuf, instbuf.address);
244 } else { 345 } else {