comparison dis.c @ 2206:4c265d2f6c88

Minor refactor of 68K disassembler
author Michael Pavone <pavone@retrodev.com>
date Sat, 27 Aug 2022 17:07:57 -0700
parents 0c0d4233d826
children 53411df7fc71
comparison
equal deleted inserted replaced
2205:90297f1fb3fe 2206:4c265d2f6c88
10 #include <stdarg.h> 10 #include <stdarg.h>
11 #include <ctype.h> 11 #include <ctype.h>
12 #include "vos_program_module.h" 12 #include "vos_program_module.h"
13 #include "tern.h" 13 #include "tern.h"
14 #include "util.h" 14 #include "util.h"
15 15 #include "disasm.h"
16 uint8_t visited[(16*1024*1024)/16]; 16
17 uint16_t label[(16*1024*1024)/8]; 17 int headless;
18 18 void render_errorbox(char *title, char *message) {}
19 void fatal_error(char *format, ...) 19 void render_warnbox(char *title, char *message) {}
20 { 20 void render_infobox(char *title, char *message) {}
21 va_list args; 21
22 va_start(args, format); 22 void check_reference(disasm_context *context, m68kinst * inst, m68k_op_info * op)
23 vfprintf(stderr, format, args);
24 va_end(args);
25 exit(1);
26 }
27
28
29 void visit(uint32_t address)
30 {
31 address &= 0xFFFFFF;
32 visited[address/16] |= 1 << ((address / 2) % 8);
33 }
34
35 void reference(uint32_t address)
36 {
37 address &= 0xFFFFFF;
38 //printf("referenced: %X\n", address);
39 label[address/16] |= 1 << (address % 16);
40 }
41
42 uint8_t is_visited(uint32_t address)
43 {
44 address &= 0xFFFFFF;
45 return visited[address/16] & (1 << ((address / 2) % 8));
46 }
47
48 uint16_t is_label(uint32_t address)
49 {
50 address &= 0xFFFFFF;
51 return label[address/16] & (1 << (address % 16));
52 }
53
54 typedef struct {
55 uint32_t num_labels;
56 uint32_t storage;
57 uint32_t full_address;
58 char *labels[];
59 } label_names;
60
61 tern_node * weak_label(tern_node * head, const char *name, uint32_t address)
62 {
63 char key[MAX_INT_KEY_SIZE];
64 tern_int_key(address & 0xFFFFFF, key);
65 label_names * names = tern_find_ptr(head, key);
66 if (names)
67 {
68 if (names->num_labels == names->storage)
69 {
70 names->storage = names->storage + (names->storage >> 1);
71 names = realloc(names, sizeof(label_names) + names->storage * sizeof(char *));
72 }
73 } else {
74 names = malloc(sizeof(label_names) + 4 * sizeof(char *));
75 names->num_labels = 0;
76 names->storage = 4;
77 head = tern_insert_ptr(head, key, names);
78 }
79 names->labels[names->num_labels++] = strdup(name);
80 names->full_address = address;
81 return head;
82 }
83 tern_node *add_label(tern_node * head, const char *name, uint32_t address)
84 {
85 reference(address);
86 return weak_label(head, name, address);
87 }
88
89 typedef struct deferred {
90 uint32_t address;
91 struct deferred *next;
92 } deferred;
93
94 deferred * defer(uint32_t address, deferred * next)
95 {
96 if (is_visited(address) || address & 1) {
97 return next;
98 }
99 //printf("deferring %X\n", address);
100 deferred * d = malloc(sizeof(deferred));
101 d->address = address;
102 d->next = next;
103 return d;
104 }
105
106 void check_reference(m68kinst * inst, m68k_op_info * op)
107 { 23 {
108 switch(op->addr_mode) 24 switch(op->addr_mode)
109 { 25 {
110 case MODE_PC_DISPLACE: 26 case MODE_PC_DISPLACE:
111 reference(inst->address + 2 + op->params.regs.displacement); 27 reference(context, inst->address + 2 + op->params.regs.displacement);
112 break; 28 break;
113 case MODE_ABSOLUTE: 29 case MODE_ABSOLUTE:
114 case MODE_ABSOLUTE_SHORT: 30 case MODE_ABSOLUTE_SHORT:
115 reference(op->params.immed); 31 reference(context, op->params.immed);
116 break; 32 break;
117 } 33 }
118 } 34 }
119 35
120 int label_fun(char *dst, uint32_t address, void * data) 36 int label_fun(char *dst, uint32_t address, void * data)
121 { 37 {
122 tern_node * labels = data; 38 disasm_context *context = data;
123 char key[MAX_INT_KEY_SIZE]; 39 label_def *def = find_label(context, address);
124 label_names * names = tern_find_ptr(labels, tern_int_key(address & 0xFFFFFF, key)); 40 if (def && def->num_labels) {
125 if (names) 41 return sprintf(dst, "%s", def->labels[0]);
126 { 42 }
127 return sprintf(dst, "%s", names->labels[0]); 43 return m68k_default_label_fun(dst, address, NULL);
128 } else {
129 return m68k_default_label_fun(dst, address, NULL);
130 }
131 }
132
133 char * strip_ws(char * text)
134 {
135 while (*text && (!isprint(*text) || isblank(*text)))
136 {
137 text++;
138 }
139 char * ret = text;
140 text = ret + strlen(ret) - 1;
141 while (text > ret && (!isprint(*text) || isblank(*text)))
142 {
143 *text = 0;
144 text--;
145 }
146 return ret;
147 } 44 }
148 45
149 typedef struct { 46 typedef struct {
150 uint32_t address_off; 47 uint32_t address_off;
151 uint32_t address_end; 48 uint32_t address_end;
157 rom_def *rom = data; 54 rom_def *rom = data;
158 if (address >= rom->address_off && address < rom->address_end) { 55 if (address >= rom->address_off && address < rom->address_end) {
159 return rom->buffer[((address & 0xFFFFFF) - rom->address_off) >> 1]; 56 return rom->buffer[((address & 0xFFFFFF) - rom->address_off) >> 1];
160 } 57 }
161 return 0; 58 return 0;
59 }
60
61 void print_label_def(char *key, tern_val val, uint8_t valtype, void *data)
62 {
63 rom_def *rom = data;
64 label_def *label = val.ptrval;
65 uint32_t address = label->full_address & 0xFFFFFFF;
66 if (address >= rom->address_off && address < rom->address_end) {
67 return;
68 }
69 if (!label->referenced) {
70 return;
71 }
72 if (label->num_labels) {
73 for (int i = 0; i < label->num_labels; i++)
74 {
75 printf("%s equ $%X\n", label->labels[i], label->full_address);
76 }
77 } else {
78 printf("ADR_%X equ $%X\n", label->full_address, label->full_address);
79 }
162 } 80 }
163 81
164 int main(int argc, char ** argv) 82 int main(int argc, char ** argv)
165 { 83 {
166 long filesize; 84 long filesize;
167 unsigned short *filebuf = NULL; 85 unsigned short *filebuf = NULL;
168 char disbuf[1024]; 86 char disbuf[1024];
169 m68kinst instbuf; 87 m68kinst instbuf;
170 unsigned short * cur; 88 unsigned short * cur;
171 deferred *def = NULL, *tmpd;
172 89
173 uint8_t labels = 0, addr = 0, only = 0, vos = 0, reset = 0; 90 uint8_t labels = 0, addr = 0, only = 0, vos = 0, reset = 0;
174 tern_node * named_labels = NULL; 91 disasm_context *context = create_68000_disasm();
92
175 93
176 uint32_t address_off = 0, address_end; 94 uint32_t address_off = 0, address_end;
177 uint8_t do_cd_labels = 0, main_cpu = 0; 95 uint8_t do_cd_labels = 0, main_cpu = 0;
178 for(uint8_t opt = 2; opt < argc; ++opt) { 96 for(uint8_t opt = 2; opt < argc; ++opt) {
179 if (argv[opt][0] == '-') { 97 if (argv[opt][0] == '-') {
223 while (fgets(disbuf, sizeof(disbuf), address_log)) { 141 while (fgets(disbuf, sizeof(disbuf), address_log)) {
224 if (disbuf[0]) { 142 if (disbuf[0]) {
225 char *end; 143 char *end;
226 uint32_t address = strtol(disbuf, &end, 16); 144 uint32_t address = strtol(disbuf, &end, 16);
227 if (address) { 145 if (address) {
228 def = defer(address, def); 146 defer_disasm(context, address);
229 reference(address);
230 if (*end == '=') { 147 if (*end == '=') {
231 named_labels = add_label(named_labels, strip_ws(end+1), address); 148 add_label(context, strip_ws(end+1), address);
149 } else {
150 reference(context, address);
232 } 151 }
233 } 152 }
234 } 153 }
235 } 154 }
236 fclose(address_log); 155 fclose(address_log);
237 } 156 }
238 } else { 157 } else {
239 char *end; 158 char *end;
240 uint32_t address = strtol(argv[opt], &end, 16); 159 uint32_t address = strtol(argv[opt], &end, 16);
241 def = defer(address, def); 160 defer_disasm(context, address);
242 reference(address);
243 if (*end == '=') { 161 if (*end == '=') {
244 named_labels = add_label(named_labels, end+1, address); 162 add_label(context, end+1, address);
163 } else {
164 reference(context, address);
245 } 165 }
246 } 166 }
247 } 167 }
248 FILE * f = fopen(argv[1], "rb"); 168 FILE * f = fopen(argv[1], "rb");
249 fseek(f, 0, SEEK_END); 169 fseek(f, 0, SEEK_END);
250 filesize = ftell(f); 170 filesize = ftell(f);
251 fseek(f, 0, SEEK_SET); 171 fseek(f, 0, SEEK_SET);
252 172
253 char int_key[MAX_INT_KEY_SIZE]; 173 char int_key[MAX_INT_KEY_SIZE];
254 uint8_t is_scd_iso = 0; 174 uint8_t is_scd_iso = 0;
255 uint8_t has_manual_defs = !!def; 175 uint8_t has_manual_defs = !!context->deferred;
256 if (vos) 176 if (vos)
257 { 177 {
258 vos_program_module header; 178 vos_program_module header;
259 vos_read_header(f, &header); 179 vos_read_header(f, &header);
260 vos_read_alloc_module_map(f, &header); 180 vos_read_alloc_module_map(f, &header);
261 address_off = header.user_boundary; 181 address_off = header.user_boundary;
262 address_end = address_off + filesize - 0x1000; 182 address_end = address_off + filesize - 0x1000;
263 def = defer(header.main_entry_link.code_address, def); 183 defer_disasm(context, header.main_entry_link.code_address);
264 named_labels = add_label(named_labels, "main_entry_link", header.main_entry_link.code_address); 184 add_label(context, "main_entry_link", header.main_entry_link.code_address);
265 for (int i = 0; i < header.n_modules; i++) 185 for (int i = 0; i < header.n_modules; i++)
266 { 186 {
267 if (!reset || header.module_map_entries[i].code_address != header.user_boundary) 187 if (!reset || header.module_map_entries[i].code_address != header.user_boundary)
268 { 188 {
269 def = defer(header.module_map_entries[i].code_address, def); 189 defer_disasm(context, header.module_map_entries[i].code_address);
270 } 190 }
271 named_labels = add_label(named_labels, header.module_map_entries[i].name.str, header.module_map_entries[i].code_address); 191 add_label(context, header.module_map_entries[i].name.str, header.module_map_entries[i].code_address);
272 } 192 }
273 fseek(f, 0x1000, SEEK_SET); 193 fseek(f, 0x1000, SEEK_SET);
274 filebuf = malloc(filesize - 0x1000); 194 filebuf = malloc(filesize - 0x1000);
275 if (fread(filebuf, 2, (filesize - 0x1000)/2, f) != (filesize - 0x1000)/2) 195 if (fread(filebuf, 2, (filesize - 0x1000)/2, f) != (filesize - 0x1000)/2)
276 { 196 {
281 { 201 {
282 *cur = (*cur >> 8) | (*cur << 8); 202 *cur = (*cur >> 8) | (*cur << 8);
283 } 203 }
284 if (reset) 204 if (reset)
285 { 205 {
286 def = defer(filebuf[2] << 16 | filebuf[3], def); 206 defer_disasm(context, filebuf[2] << 16 | filebuf[3]);
287 named_labels = add_label(named_labels, "reset", filebuf[2] << 16 | filebuf[3]); 207 add_label(context, "reset", filebuf[2] << 16 | filebuf[3]);
288 } 208 }
289 } else if (filesize > 0x1000) { 209 } else if (filesize > 0x1000) {
290 long boot_size = filesize > (32*1024) ? 32*1024 : filesize; 210 long boot_size = filesize > (32*1024) ? 32*1024 : filesize;
291 filebuf = malloc(boot_size); 211 filebuf = malloc(boot_size);
292 if (fread(filebuf, 1, boot_size, f) != boot_size) { 212 if (fread(filebuf, 1, boot_size, f) != boot_size) {
320 main_end = boot_size; 240 main_end = boot_size;
321 } 241 }
322 address_off = 0xFF0000; 242 address_off = 0xFF0000;
323 address_end = address_off + main_end-main_start; 243 address_end = address_off + main_end-main_start;
324 filebuf += main_start / 2; 244 filebuf += main_start / 2;
325 named_labels = add_label(named_labels, "start", 0xFF0000); 245 add_label(context, "start", 0xFF0000);
326 if (!has_manual_defs || !only) { 246 if (!has_manual_defs || !only) {
327 def = defer(0xFF0000, def); 247 defer_disasm(context, 0xFF0000);
328 } 248 }
329 uint32_t user_start; 249 uint32_t user_start;
330 if (filebuf[0xA/2] == 0x57A) { 250 if (filebuf[0xA/2] == 0x57A) {
331 //US 251 //US
332 user_start = 0xFF0584; 252 user_start = 0xFF0584;
335 user_start = 0xFF056E; 255 user_start = 0xFF056E;
336 } else { 256 } else {
337 //JP 257 //JP
338 user_start = 0xFF0156; 258 user_start = 0xFF0156;
339 } 259 }
340 named_labels = add_label(named_labels, "user_start", user_start); 260 add_label(context, "user_start", user_start);
341 do_cd_labels = 1; 261 do_cd_labels = 1;
342 } else { 262 } else {
343 uint32_t sub_start =filebuf[0x40/2] << 16 | filebuf[0x42/2]; 263 uint32_t sub_start =filebuf[0x40/2] << 16 | filebuf[0x42/2];
344 uint32_t sub_end = sub_start + (filebuf[0x44/2] << 16 | filebuf[0x46/2]); 264 uint32_t sub_end = sub_start + (filebuf[0x44/2] << 16 | filebuf[0x46/2]);
345 if (sub_start > (boot_size - 0x20)) { 265 if (sub_start > (boot_size - 0x20)) {
368 } else { 288 } else {
369 name = namebuf; 289 name = namebuf;
370 sprintf(namebuf, "usercall%u", index); 290 sprintf(namebuf, "usercall%u", index);
371 } 291 }
372 uint32_t address = 0x6000 + offset - sub_start; 292 uint32_t address = 0x6000 + offset - sub_start;
373 named_labels = add_label(named_labels, name, address); 293 add_label(context, name, address);
374 if (!has_manual_defs || !only) { 294 if (!has_manual_defs || !only) {
375 def = defer(address, def); 295 defer_disasm(context, address);
376 } 296 }
377 } 297 }
378 298
379 do_cd_labels = 1; 299 do_cd_labels = 1;
380 filebuf += sub_start / 2; 300 filebuf += sub_start / 2;
406 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur) 326 for(cur = filebuf; cur - filebuf < (filesize/2); ++cur)
407 { 327 {
408 *cur = (*cur >> 8) | (*cur << 8); 328 *cur = (*cur >> 8) | (*cur << 8);
409 } 329 }
410 if (!address_off) { 330 if (!address_off) {
411 uint32_t start = filebuf[2] << 16 | filebuf[3]; 331 process_m68k_vectors(context, filebuf, context->deferred && only);
412 uint32_t int_2 = filebuf[0x68/2] << 16 | filebuf[0x6A/2];
413 uint32_t int_4 = filebuf[0x70/2] << 16 | filebuf[0x72/2];
414 uint32_t int_6 = filebuf[0x78/2] << 16 | filebuf[0x7A/2];
415 named_labels = add_label(named_labels, "start", start);
416 named_labels = add_label(named_labels, "int_2", int_2);
417 named_labels = add_label(named_labels, "int_4", int_4);
418 named_labels = add_label(named_labels, "int_6", int_6);
419 if (!def || !only) {
420 def = defer(start, def);
421 def = defer(int_2, def);
422 def = defer(int_4, def);
423 def = defer(int_6, def);
424 }
425 named_labels = weak_label(named_labels, "illegal_inst", filebuf[0x10/2] << 16 | filebuf[0x12/2]);
426 named_labels = weak_label(named_labels, "div_zero", filebuf[0x14/2] << 16 | filebuf[0x16/2]);
427 named_labels = weak_label(named_labels, "chk_exception", filebuf[0x18/2] << 16 | filebuf[0x1A/2]);
428 named_labels = weak_label(named_labels, "trapv", filebuf[0x1C/2] << 16 | filebuf[0x1E/2]);
429 named_labels = weak_label(named_labels, "line_a_trap", filebuf[0x28/2] << 16 | filebuf[0x2A/2]);
430 named_labels = weak_label(named_labels, "line_f_trap", filebuf[0x2C/2] << 16 | filebuf[0x2E/2]);
431 } 332 }
432 } 333 }
433 if (do_cd_labels) { 334 if (do_cd_labels) {
434 if (main_cpu) { 335 if (main_cpu) {
435 named_labels = weak_label(named_labels, "_bios_reset", 0x280); 336 add_segacd_maincpu_labels(context);
436 named_labels = weak_label(named_labels, "_bios_entry", 0x284);
437 named_labels = weak_label(named_labels, "_bios_init", 0x288);
438 named_labels = weak_label(named_labels, "_bios_init_sp", 0x28C);
439 named_labels = weak_label(named_labels, "_bios_vint", 0x290);
440 named_labels = weak_label(named_labels, "_bios_set_hint", 0x294);
441 named_labels = weak_label(named_labels, "_bios_poll_io", 0x298);
442 named_labels = weak_label(named_labels, "_bios_detect_io", 0x29C);
443 named_labels = weak_label(named_labels, "_bios_clear_vram", 0x2A0);
444 named_labels = weak_label(named_labels, "_bios_clear_nmtbl", 0x2A4);
445 named_labels = weak_label(named_labels, "_bios_clear_vsram", 0x2A8);
446 named_labels = weak_label(named_labels, "_bios_init_vdp", 0x2AC);
447 named_labels = weak_label(named_labels, "_bios_vdp_loadregs", 0x2B0);
448 named_labels = weak_label(named_labels, "_bios_vdp_fill", 0x2B4);
449 named_labels = weak_label(named_labels, "_bios_clear_vram_range", 0x2B8);
450 named_labels = weak_label(named_labels, "_bios_clear_vram_range_dma", 0x2BC);
451 named_labels = weak_label(named_labels, "_bios_vram_dma_fill", 0x2C0);
452 named_labels = weak_label(named_labels, "_bios_update_nmtbl", 0x2C4);
453 named_labels = weak_label(named_labels, "_bios_update_nmtbl_template", 0x2C8);
454 named_labels = weak_label(named_labels, "_bios_fill_nmtbl", 0x2CC);
455 named_labels = weak_label(named_labels, "_bios_vdp_dma", 0x2D0);
456 named_labels = weak_label(named_labels, "_bios_vdp_dma_wordram", 0x2D4);
457 named_labels = weak_label(named_labels, "_bios_vdp_display_enable", 0x2D8);
458 named_labels = weak_label(named_labels, "_bios_vdp_display_disable", 0x2DC);
459 named_labels = weak_label(named_labels, "_bios_pal_buffer", 0x2E0);
460 named_labels = weak_label(named_labels, "_bios_pal_buffer_update", 0x2E4);
461 named_labels = weak_label(named_labels, "_bios_pal_dma", 0x2E8);
462 named_labels = weak_label(named_labels, "_bios_gfx_decomp", 0x2EC);
463 named_labels = weak_label(named_labels, "_bios_gfx_decomp_ram", 0x2F0);
464 named_labels = weak_label(named_labels, "_bios_update_sprites", 0x2F4);
465 named_labels = weak_label(named_labels, "_bios_clear_ram", 0x2F8);
466 named_labels = weak_label(named_labels, "_bios_display_sprite", 0x300);
467 named_labels = weak_label(named_labels, "_bios_wait_vint", 0x304);
468 named_labels = weak_label(named_labels, "_bios_wait_vint_flags", 0x308);
469 named_labels = weak_label(named_labels, "_bios_dma_sat", 0x30C);
470 named_labels = weak_label(named_labels, "_bios_set_hint_direct", 0x314);
471 named_labels = weak_label(named_labels, "_bios_disable_hint", 0x318);
472 named_labels = weak_label(named_labels, "_bios_print", 0x31C);
473 named_labels = weak_label(named_labels, "_bios_load_user_font", 0x320);
474 named_labels = weak_label(named_labels, "_bios_load_bios_font", 0x324);
475 named_labels = weak_label(named_labels, "_bios_load_bios_font_default", 0x328);
476 //TODO: more functions in the middle here
477 named_labels = weak_label(named_labels, "_bios_prng_mod", 0x338);
478 named_labels = weak_label(named_labels, "_bios_prng", 0x33C);
479 named_labels = weak_label(named_labels, "_bios_clear_comm", 0x340);
480 named_labels = weak_label(named_labels, "_bios_comm_update", 0x344);
481 //TODO: more functions in the middle here
482 named_labels = weak_label(named_labels, "_bios_sega_logo", 0x364);
483 named_labels = weak_label(named_labels, "_bios_set_vint", 0x368);
484 //TODO: more functions at the end here
485
486 named_labels = weak_label(named_labels, "WORD_RAM", 0x200000);
487 named_labels = weak_label(named_labels, "CD_RESET_IFL2", 0xA12000);
488 named_labels = weak_label(named_labels, "CD_RESET_IFL2_BYTE", 0xA12001);
489 named_labels = weak_label(named_labels, "CD_WRITE_PROTECT", 0xA12002);
490 named_labels = weak_label(named_labels, "CD_MEM_MODE", 0xA12003);
491 named_labels = weak_label(named_labels, "CDC_CTRL", 0xA12004);
492 named_labels = weak_label(named_labels, "HINT_VECTOR", 0xA12006);
493 named_labels = weak_label(named_labels, "CDC_HOST_DATA", 0xA12008);
494 named_labels = weak_label(named_labels, "STOP_WATCH", 0xA1200C);
495 named_labels = weak_label(named_labels, "COMM_MAIN_FLAG", 0xA1200E);
496 named_labels = weak_label(named_labels, "COMM_SUB_FLAG", 0xA1200F);
497 named_labels = weak_label(named_labels, "COMM_CMD0", 0xA12010);
498 named_labels = weak_label(named_labels, "COMM_CMD1", 0xA12012);
499 named_labels = weak_label(named_labels, "COMM_CMD2", 0xA12014);
500 named_labels = weak_label(named_labels, "COMM_CMD3", 0xA12016);
501 named_labels = weak_label(named_labels, "COMM_CMD4", 0xA12018);
502 named_labels = weak_label(named_labels, "COMM_CMD5", 0xA1201A);
503 named_labels = weak_label(named_labels, "COMM_CMD6", 0xA1201C);
504 named_labels = weak_label(named_labels, "COMM_CMD7", 0xA1201E);
505 named_labels = weak_label(named_labels, "COMM_STATUS0", 0xA12020);
506 named_labels = weak_label(named_labels, "COMM_STATUS1", 0xA12022);
507 named_labels = weak_label(named_labels, "COMM_STATUS2", 0xA12024);
508 named_labels = weak_label(named_labels, "COMM_STATUS3", 0xA12026);
509 named_labels = weak_label(named_labels, "COMM_STATUS4", 0xA12028);
510 named_labels = weak_label(named_labels, "COMM_STATUS5", 0xA1202A);
511 named_labels = weak_label(named_labels, "COMM_STATUS6", 0xA1202C);
512 named_labels = weak_label(named_labels, "COMM_STATUS7", 0xA1202E);
513 } else { 337 } else {
514 named_labels = weak_label(named_labels, "bios_common_work", 0x5E80); 338 add_segacd_subcpu_labels(context);
515 named_labels = weak_label(named_labels, "_setjmptbl", 0x5F0A);
516 named_labels = weak_label(named_labels, "_waitvsync", 0x5F10);
517 named_labels = weak_label(named_labels, "_buram", 0x5F16);
518 named_labels = weak_label(named_labels, "_cdboot", 0x5F1C);
519 named_labels = weak_label(named_labels, "_cdbios", 0x5F22);
520 named_labels = weak_label(named_labels, "_usercall0", 0x5F28);
521 named_labels = weak_label(named_labels, "_usercall1", 0x5F2E);
522 named_labels = weak_label(named_labels, "_usercall2", 0x5F34);
523 named_labels = weak_label(named_labels, "_usercall2Address", 0x5F36);
524 named_labels = weak_label(named_labels, "_usercall3", 0x5F3A);
525 named_labels = weak_label(named_labels, "_adrerr", 0x5F40);
526 named_labels = weak_label(named_labels, "_adrerrAddress", 0x5F42);
527 named_labels = weak_label(named_labels, "_coderr", 0x5F46);
528 named_labels = weak_label(named_labels, "_coderrAddress", 0x5F48);
529 named_labels = weak_label(named_labels, "_diverr", 0x5F4C);
530 named_labels = weak_label(named_labels, "_diverrAddress", 0x5F4E);
531 named_labels = weak_label(named_labels, "_chkerr", 0x5F52);
532 named_labels = weak_label(named_labels, "_chkerrAddress", 0x5F54);
533 named_labels = weak_label(named_labels, "_trperr", 0x5F58);
534 named_labels = weak_label(named_labels, "_trperrAddress", 0x5F5A);
535 named_labels = weak_label(named_labels, "_spverr", 0x5F5E);
536 named_labels = weak_label(named_labels, "_spverrAddress", 0x5F60);
537 named_labels = weak_label(named_labels, "_trace", 0x5F64);
538 named_labels = weak_label(named_labels, "_traceAddress", 0x5F66);
539 named_labels = weak_label(named_labels, "_nocod0", 0x5F6A);
540 named_labels = weak_label(named_labels, "_nocod0Address", 0x5F6C);
541 named_labels = weak_label(named_labels, "_nocod0", 0x5F70);
542 named_labels = weak_label(named_labels, "_nocod0Address", 0x5F72);
543 named_labels = weak_label(named_labels, "_slevel1", 0x5F76);
544 named_labels = weak_label(named_labels, "_slevel1Address", 0x5F78);
545 named_labels = weak_label(named_labels, "_slevel2", 0x5F7C);
546 named_labels = weak_label(named_labels, "_slevel2Address", 0x5F7E);
547 named_labels = weak_label(named_labels, "_slevel3", 0x5F82);
548 named_labels = weak_label(named_labels, "_slevel3Address", 0x5F84);
549 named_labels = weak_label(named_labels, "WORD_RAM_2M", 0x80000);
550 named_labels = weak_label(named_labels, "WORD_RAM_1M", 0xC0000);
551 named_labels = weak_label(named_labels, "LED_CONTROL", 0xFFFF8000);
552 named_labels = weak_label(named_labels, "VERSION_RESET", 0xFFFF8001);
553 named_labels = weak_label(named_labels, "MEM_MODE_WORD", 0xFFFF8002);
554 named_labels = weak_label(named_labels, "MEM_MODE_BYTE", 0xFFFF8003);
555 named_labels = weak_label(named_labels, "CDC_CTRL", 0xFFFF8004);
556 named_labels = weak_label(named_labels, "CDC_AR", 0xFFFF8005);
557 named_labels = weak_label(named_labels, "CDC_REG_DATA_WORD", 0xFFFF8006);
558 named_labels = weak_label(named_labels, "CDC_REG_DATA", 0xFFFF8007);
559 named_labels = weak_label(named_labels, "CDC_HOST_DATA", 0xFFFF8008);
560 named_labels = weak_label(named_labels, "CDC_DMA_ADDR", 0xFFFF800A);
561 named_labels = weak_label(named_labels, "STOP_WATCH", 0xFFFF800C);
562 named_labels = weak_label(named_labels, "COMM_MAIN_FLAG", 0xFFFF800E);
563 named_labels = weak_label(named_labels, "COMM_SUB_FLAG", 0xFFFF800F);
564 named_labels = weak_label(named_labels, "COMM_CMD0", 0xFFFF8010);
565 named_labels = weak_label(named_labels, "COMM_CMD1", 0xFFFF8012);
566 named_labels = weak_label(named_labels, "COMM_CMD2", 0xFFFF8014);
567 named_labels = weak_label(named_labels, "COMM_CMD3", 0xFFFF8016);
568 named_labels = weak_label(named_labels, "COMM_CMD4", 0xFFFF8018);
569 named_labels = weak_label(named_labels, "COMM_CMD5", 0xFFFF801A);
570 named_labels = weak_label(named_labels, "COMM_CMD6", 0xFFFF801C);
571 named_labels = weak_label(named_labels, "COMM_CMD7", 0xFFFF801E);
572 named_labels = weak_label(named_labels, "COMM_STATUS0", 0xFFFF8020);
573 named_labels = weak_label(named_labels, "COMM_STATUS1", 0xFFFF8022);
574 named_labels = weak_label(named_labels, "COMM_STATUS2", 0xFFFF8024);
575 named_labels = weak_label(named_labels, "COMM_STATUS3", 0xFFFF8026);
576 named_labels = weak_label(named_labels, "COMM_STATUS4", 0xFFFF8028);
577 named_labels = weak_label(named_labels, "COMM_STATUS5", 0xFFFF802A);
578 named_labels = weak_label(named_labels, "COMM_STATUS6", 0xFFFF802C);
579 named_labels = weak_label(named_labels, "COMM_STATUS7", 0xFFFF802E);
580 named_labels = weak_label(named_labels, "TIMER_WORD", 0xFFFF8030);
581 named_labels = weak_label(named_labels, "TIMER", 0xFFFF8031);
582 named_labels = weak_label(named_labels, "INT_MASK_WORD", 0xFFFF8032);
583 named_labels = weak_label(named_labels, "INT_MASK", 0xFFFF8033);
584 named_labels = weak_label(named_labels, "CDD_FADER", 0xFFFF8034);
585 named_labels = weak_label(named_labels, "CDD_CTRL_WORD", 0xFFFF8036);
586 named_labels = weak_label(named_labels, "CDD_CTRL_BYTE", 0xFFFF8037);
587 } 339 }
588 } 340 }
589 uint32_t size, tmp_addr; 341 uint32_t size, tmp_addr;
590 uint32_t address; 342 uint32_t address;
591 rom_def rom = { 343 rom_def rom = {
592 .address_off = address_off, 344 .address_off = address_off,
593 .address_end = address_end, 345 .address_end = address_end,
594 .buffer = filebuf 346 .buffer = filebuf
595 }; 347 };
596 uint8_t valid_address; 348 uint8_t valid_address;
597 while(def) { 349 while(context->deferred) {
598 do { 350 do {
599 valid_address = 0; 351 valid_address = 0;
600 address = def->address; 352 address = context->deferred->address;
601 if (!is_visited(address)) { 353 if (!is_visited(context, address)) {
602 address &= 0xFFFFFF; 354 address &= context->address_mask;
603 if (address < address_end && address >= address_off) { 355 if (address < address_end && address >= address_off) {
604 valid_address = 1; 356 valid_address = 1;
605 } 357 address = context->deferred->address;
606 } 358 }
607 tmpd = def; 359 }
608 def = def->next; 360 deferred_addr *tmpd = context->deferred;
361 context->deferred = context->deferred->next;
609 free(tmpd); 362 free(tmpd);
610 } while(def && !valid_address); 363 } while(context->deferred && !valid_address);
611 if (!valid_address) { 364 if (!valid_address) {
612 break; 365 break;
613 } 366 }
614 for(;;) { 367 for(;;) {
615 if ((address & 0xFFFFFF) > address_end || address < address_off) { 368 if ((address & context->address_mask) > address_end || address < address_off) {
616 break; 369 break;
617 } 370 }
618 visit(address); 371 visit(context, address);
619 address = m68k_decode(fetch, &rom, &instbuf, address); 372 address = m68k_decode(fetch, &rom, &instbuf, address);
620 //m68k_disasm(&instbuf, disbuf); 373 //m68k_disasm(&instbuf, disbuf);
621 //printf("%X: %s\n", instbuf.address, disbuf); 374 //printf("%X: %s\n", instbuf.address, disbuf);
622 check_reference(&instbuf, &(instbuf.src)); 375 check_reference(context, &instbuf, &(instbuf.src));
623 check_reference(&instbuf, &(instbuf.dst)); 376 check_reference(context, &instbuf, &(instbuf.dst));
624 if (instbuf.op == M68K_ILLEGAL || instbuf.op == M68K_RTS || instbuf.op == M68K_RTE || instbuf.op == M68K_INVALID) { 377 if (instbuf.op == M68K_ILLEGAL || instbuf.op == M68K_RTS || instbuf.op == M68K_RTE || instbuf.op == M68K_INVALID) {
625 break; 378 break;
626 } 379 }
627 if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) { 380 if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) {
381 tmp_addr = instbuf.address + 2 + instbuf.src.params.immed;
382 reference(context, tmp_addr);
628 if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) { 383 if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) {
629 address = instbuf.address + 2 + instbuf.src.params.immed; 384 address = tmp_addr;
630 reference(address); 385 if (is_visited(context, address)) {
631 if (is_visited(address)) {
632 break; 386 break;
633 } 387 }
634 } else { 388 } else {
635 tmp_addr = instbuf.address + 2 + instbuf.src.params.immed; 389 defer_disasm(context, tmp_addr);
636 reference(tmp_addr);
637 def = defer(tmp_addr, def);
638 } 390 }
639 } else if(instbuf.op == M68K_JMP) { 391 } else if(instbuf.op == M68K_JMP) {
640 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) { 392 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) {
641 address = instbuf.src.params.immed; 393 address = instbuf.src.params.immed;
642 if (is_visited(address)) { 394 if (is_visited(context, address)) {
643 break; 395 break;
644 } 396 }
645 } else if (instbuf.src.addr_mode == MODE_PC_DISPLACE) { 397 } else if (instbuf.src.addr_mode == MODE_PC_DISPLACE) {
646 address = instbuf.src.params.regs.displacement + instbuf.address + 2; 398 address = instbuf.src.params.regs.displacement + instbuf.address + 2;
647 if (is_visited(address)) { 399 if (is_visited(context, address)) {
648 break; 400 break;
649 } 401 }
650 } else { 402 } else {
651 break; 403 break;
652 } 404 }
653 } else if(instbuf.op == M68K_JSR) { 405 } else if(instbuf.op == M68K_JSR) {
654 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) { 406 if (instbuf.src.addr_mode == MODE_ABSOLUTE || instbuf.src.addr_mode == MODE_ABSOLUTE_SHORT) {
655 def = defer(instbuf.src.params.immed, def); 407 defer_disasm(context, instbuf.src.params.immed);
656 } else if (instbuf.src.addr_mode == MODE_PC_DISPLACE) { 408 } else if (instbuf.src.addr_mode == MODE_PC_DISPLACE) {
657 def = defer(instbuf.src.params.regs.displacement + instbuf.address + 2, def); 409 defer_disasm(context, instbuf.src.params.regs.displacement + instbuf.address + 2);
658 } 410 }
659 } 411 }
660 } 412 }
661 } 413 }
662 if (labels) { 414 if (labels) {
663 for (address = 0; address < address_off; address++) { 415 tern_foreach(context->labels, print_label_def, &rom);
664 if (is_label(address)) {
665 char key[MAX_INT_KEY_SIZE];
666 tern_int_key(address, key);
667 label_names *names = tern_find_ptr(named_labels, key);
668 if (names) {
669 for (int i = 0; i < names->num_labels; i++)
670 {
671 printf("%s equ $%X\n", names->labels[i], address);
672 }
673 } else {
674 printf("ADR_%X equ $%X\n", address, address);
675 }
676 }
677 }
678 for (address = address_end; address < (16*1024*1024); address++) {
679 if (is_label(address)) {
680 char key[MAX_INT_KEY_SIZE];
681 tern_int_key(address, key);
682 label_names *names = tern_find_ptr(named_labels, key);
683 if (names) {
684 for (int i = 0; i < names->num_labels; i++)
685 {
686 printf("%s equ $%X\n", names->labels[i], names->full_address);
687 }
688 } else {
689 printf("ADR_%X equ $%X\n", address, address);
690 }
691 }
692 }
693 puts(""); 416 puts("");
694 } 417 }
695 for (address = address_off; address < address_end; address+=2) { 418 for (address = address_off; address < address_end; address+=2) {
696 if (is_visited(address)) { 419 if (is_visited(context, address)) {
697 m68k_decode(fetch, &rom, &instbuf, address); 420 m68k_decode(fetch, &rom, &instbuf, address);
698 if (labels) { 421 if (labels) {
699 m68k_disasm_labels(&instbuf, disbuf, label_fun, named_labels); 422 m68k_disasm_labels(&instbuf, disbuf, label_fun, context);
700 char keybuf[MAX_INT_KEY_SIZE]; 423 label_def *label = find_label(context, address);
701 label_names * names = tern_find_ptr(named_labels, tern_int_key(address, keybuf)); 424 if (label) {
702 if (names) 425 if (label->num_labels) {
703 { 426 for (int i = 0; i < label->num_labels; i++)
704 for (int i = 0; i < names->num_labels; i++) 427 {
705 { 428 printf("%s:\n", label->labels[i]);
706 printf("%s:\n", names->labels[i]); 429 }
707 } 430 } else {
708 } else if (is_label(instbuf.address)) { 431 printf("ADR_%X:\n", label->full_address);
709 printf("ADR_%X:\n", instbuf.address); 432 }
710 } 433 }
711 if (addr) { 434 if (addr) {
712 printf("\t%s\t;%X\n", disbuf, instbuf.address); 435 printf("\t%s\t;%X\n", disbuf, instbuf.address);
713 } else { 436 } else {
714 printf("\t%s\n", disbuf); 437 printf("\t%s\n", disbuf);