|
|
1.1 root 1:
2: #include <stdio.h>
3: #include <stdlib.h>
4: #include <string.h>
5: #include <stdarg.h>
6:
7: #include <SDL_types.h>
8:
9: #include "main.h"
10: #include "dialog.h"
11: #include "file.h"
1.1.1.2 ! root 12: #include "../m68000.h"
1.1 root 13: #include "memAlloc.h"
14:
15: static int buf_pos = 0;
16:
17: static void output (const char *format, ...)
18: {
19: va_list argptr;
20:
21: va_start (argptr, format);
22: vprintf (format, argptr);
23: va_end (argptr);
24: }
25:
26: static void output_lab (int addr)
27: {
28: printf ("$%x", addr);
29: }
30:
1.1.1.2 ! root 31: unsigned char _rd_byte(void)
1.1 root 32: {
33: int val = STMemory_ReadByte (buf_pos);
34: buf_pos++;
35: return val;
36: }
37:
1.1.1.2 ! root 38: short _rd_short(void)
1.1 root 39: {
40: short val = STMemory_ReadWord (buf_pos);
41: buf_pos+=2;
42: return val;
43: }
44:
1.1.1.2 ! root 45: int _rd_int(void)
1.1 root 46: {
47: int val = STMemory_ReadLong (buf_pos);
48: buf_pos+=4;
49: return val;
50: }
51:
52: const char *size_str[4] = { ".b", ".w", ".l", ".?" };
53: /* to convert weird move sizes to standard sizes */
54: const int move_size[4] = { 3, 0, 2, 1 };
55: const char *Bcc_str[16] = {
56: NULL,NULL,"hi","ls","cc","cs","ne","eq",
57: "vc","vs","pl","mi","ge","lt","gt","le"
58: };
59:
60: const char *DBcc_str[16] = {
61: "t","ra","hi","ls","cc","cs","ne","eq",
62: "vc","vs","pl","mi","ge","lt","gt","le"
63: };
64:
65: typedef union Opcode {
66: unsigned short code;
67: struct move {
68: uint src_reg : 3;
69: uint src_mode : 3;
70: uint dest_mode : 3;
71: uint dest_reg : 3;
72: uint size : 2;
73: uint op : 2;
74: } move;
75: struct adr_index {
76: int displacement : 8;
77: uint zeros : 3;
78: uint ind_size : 1;
79: uint reg : 3;
80: uint reg_type : 1;
81: } adr_index;
82: struct addq {
83: uint dest_reg : 3;
84: uint dest_mode : 3;
85: uint size : 2;
86: uint issub : 1;
87: uint data : 3;
88: uint op : 4;
89: } addq;
90: struct jmp {
91: uint dest_reg : 3;
92: uint dest_mode : 3;
93: uint op : 10;
94: } jmp;
95: struct addi {
96: uint dest_reg : 3;
97: uint dest_mode : 3;
98: uint size : 2;
99: uint OP6 : 8;
100: } addi;
101: /* size and effective address */
102: struct type1 {
103: uint ea_reg : 3;
104: uint ea_mode : 3;
105: uint size : 2;
106: uint op : 8;
107: } type1;
108: /* reg, opmode, ea */
109: struct type2 {
110: uint ea_reg : 3;
111: uint ea_mode : 3;
112: uint op_mode : 3;
113: uint reg : 3;
114: uint op : 4;
115: } type2;
116: struct MemShift {
117: uint ea_reg : 3;
118: uint ea_mode : 3;
119: uint OP3 : 2;
120: uint dr : 1;
121: uint type : 2;
122: uint OP0x1c : 5;
123: } MemShift;
124: struct ASx {
125: uint reg : 3;
126: uint OP0 : 2;
127: uint ir : 1;
128: uint size : 2;
129: uint dr : 1;
130: uint count_reg : 3;
131: uint OP0xe : 4;
132: } ASx;
133: struct abcd {
134: uint src_reg : 3;
135: uint rm : 1;
136: uint OP16 : 5;
137: uint dest_reg : 3;
138: uint OP12 : 4;
139: } abcd;
140: struct addx {
141: uint src_reg : 3;
142: uint rm : 1;
143: uint OP0 : 2;
144: uint size : 2;
145: uint OP1 : 1;
146: uint dest_reg : 3;
147: uint op : 4;
148: } addx;
149: struct cmpm {
150: uint src_reg : 3;
151: uint OP1_1 : 3;
152: uint size : 2;
153: uint OP2_1 : 1;
154: uint dest_reg : 3;
155: uint OP0xb : 4;
156: } cmpm;
157: /* branches */
158: struct DBcc {
159: uint reg : 3;
160: uint OP25 : 5;
161: uint cond : 4;
162: uint OP5 : 4;
163: } DBcc;
164: struct Bcc {
165: int displacement : 8;
166: uint cond : 4;
167: uint op : 4;
168: } Bcc;
169: struct bra {
170: int displacement : 8;
171: uint op : 8;
172: } bra;
173: struct movem {
174: uint dest_reg : 3;
175: uint dest_mode : 3;
176: uint sz : 1;
177: uint ONE : 3;
178: uint dr : 1;
179: uint NINE : 5;
180: } movem;
181: struct lea {
182: uint dest_reg : 3;
183: uint dest_mode : 3;
184: uint SEVEN : 3;
185: uint reg : 3;
186: uint FOUR : 4;
187: } lea;
188: struct moveq {
189: int data : 8;
190: uint ZERO : 1;
191: uint reg : 3;
192: uint SEVEN : 4;
193: } moveq;
194: struct exg {
195: uint dest_reg : 3;
196: uint op_mode : 5;
197: uint OP1 : 1;
198: uint src_reg : 3;
199: uint OP0xc : 4;
200: } exg;
201: } Opcode;
202:
203: /*
204: * Skip size is used when there is immediate data, for addressing
205: * modes $addr(Ax,Dy.s), and the PC flavoured version of that.
206: * The immediate data comes first and must be skipped
207: */
208: int is_adrmod (int mode, int reg, int op_size, int skip_size)
209: {
210: Opcode ext;
211: switch (skip_size) {
212: case -1: skip_size = 0; break;
213: case 0: case 1: skip_size = 2; break;
214: default: skip_size = 4; break;
215: }
216: switch (mode) {
217: case 0: case 1: case 2: case 3: case 4:
218: return 1;
219: case 5: return 1;
220: case 6: buf_pos += skip_size;
1.1.1.2 ! root 221: ext.code = _rd_short ();
1.1 root 222: buf_pos -= 2 + skip_size;
223: if (ext.adr_index.zeros != 0) return 0;
224: else return 1;
225: case 7:
226: switch (reg) {
227: case 0: return 1;
228: case 1: return 1;
229: case 4:
230: return 1;
231: case 2:
232: return 1;
233: case 3: buf_pos += skip_size;
1.1.1.2 ! root 234: ext.code = _rd_short ();
1.1 root 235: buf_pos -= 2 + skip_size;
236: if (ext.adr_index.zeros != 0) return 0;
237: else return 1;
238: default:
239: return 0;
240: }
241: break;
242: default:
243: return 0;
244: }
245:
246: }
247:
248: /* returns abs address if possible or 0xdeadbeef if not */
249: uint put_adrmod (int mode, int reg, int op_size)
250: {
251: uint temp;
252: Opcode ext;
253: switch (mode) {
254: case 0: output ("d%d", reg); break;
255: case 1: output ("a%d", reg); break;
256: case 2: output ("(a%d)", reg); break;
257: case 3: output ("(a%d)+", reg); break;
258: case 4: output ("-(a%d)", reg); break;
1.1.1.2 ! root 259: case 5: output ("%hd(a%d)", _rd_short(), reg); break;
! 260: case 6: ext.code = _rd_short ();
1.1 root 261: if (ext.adr_index.zeros != 0) output ("???");
262: output ("%hd(a%d,", ext.adr_index.displacement, reg);
263: if (ext.adr_index.reg_type) {
264: output ("a%d", ext.adr_index.reg);
265: } else {
266: output ("d%d", ext.adr_index.reg);
267: }
268: if (ext.adr_index.ind_size) {
269: output (".l)");
270: } else {
271: output (".w)");
272: }
273: break;
274: case 7:
275: switch (reg) {
1.1.1.2 ! root 276: case 0: output ("$%hx.w", _rd_short()); break;
! 277: case 1: temp = _rd_int ();
1.1 root 278: output ("$%x.l", temp);
279: return temp;
280: case 4:
281: if (op_size == 0) {
1.1.1.2 ! root 282: if (_rd_byte () != 0) output ("???");
! 283: output ("#$%x", _rd_byte ());
1.1 root 284: } else if (op_size == 2) {
285: output ("#");
1.1.1.2 ! root 286: output ("$%x", _rd_int ());
1.1 root 287: } else if (op_size == 1) {
1.1.1.2 ! root 288: output ("#$%hx", _rd_short ());
1.1 root 289: } else {
290: output ("#???");
291: }
292: break;
293: case 2:
294: temp = buf_pos;
1.1.1.2 ! root 295: temp += _rd_short ();
1.1 root 296: output ("$%x(pc)", temp);
297: return temp;
298: case 3: temp = buf_pos;
1.1.1.2 ! root 299: ext.code = _rd_short ();
1.1 root 300: if (ext.adr_index.zeros != 0) output ("???");
301: output ("$%x", temp + ext.adr_index.displacement);
302: if (ext.adr_index.reg_type) {
303: output ("(pc,a%d", ext.adr_index.reg);
304: } else {
305: output ("(pc,d%d", ext.adr_index.reg);
306: }
307: if (ext.adr_index.ind_size) {
308: output (".l)");
309: } else {
310: output (".w)");
311: }
312: break;
313: default:
314: output ("???"); break;
315: }
316: break;
317: default:
318: output ("???"); break;
319: }
320: return 0xdeadbeef;
321: }
322:
323: void aux_put_movem_regs (int mode, int low, int high)
324: {
325: if (!mode) {
326: /* (Ax)+ and control modes */
327: if (low < 8) {
328: if (low == high) {
329: output ("d%d", low);
330: return;
331: }
332: if (high >7) {
333: if (low == 7) output ("d7/");
334: else output ("d%d-7/", low);
335: } else {
336: output ("d%d-%d", low, high);
337: return;
338: }
339: }
340: if (high > 7) {
341: if (low == high) {
342: output ("a%d", low-8);
343: return;
344: }
345: if (low > 7) {
346: output ("a%d-%d", low-8, high-8);
347: } else {
348: if (high == 8) output ("a0");
349: else output ("a0-%d", high-8);
350: }
351: }
352: } else {
353: /* -(Ax) mode */
354: if (high > 7) {
355: if (low == high) {
356: output ("d%d", 15-low);
357: return;
358: }
359: if (low > 7) {
360: output ("d%d-%d", 15-high, 15-low);
361: return;
362: } else {
363: if (high == 8) output ("d7/");
364: else output ("d%d-7/", 15-high);
365: }
366: }
367: if (low < 8) {
368: if (low == high) {
369: output ("a%d", 7-low);
370: return;
371: }
372: if (high >7) {
373: if (low == 7) output ("a0");
374: else output ("a0-%d", 7-low);
375: } else {
376: output ("a%d-%d", 7-high, 7-low);
377: }
378: }
379: }
380: }
381:
382: void put_movem_regs (int mask, int mode)
383: {
384: int start;
385: int pos;
386: int pixie = 0;
387:
388: start = -1;
389: for (pos=0; pos < 16; pos++) {
390: if ((mask & (1<<pos)) && (start == -1)) start = pos;
391: else if ((!(mask & (1<<pos))) && (start != -1)) {
392: if (pixie) output ("/");
393: else pixie = 1;
394: aux_put_movem_regs (mode, start, pos-1);
395: start = -1;
396: }
397: }
398: if (mask & (1<<15)) {
399: if (pixie) output ("/");
400: else pixie = 1;
401: aux_put_movem_regs (mode, start, pos-1);
402: start = -1;
403: }
404: }
405:
406: void put_imm (int size)
407: {
408: if (size == 0) {
1.1.1.2 ! root 409: _rd_byte ();
! 410: output ("#$%x", (int)_rd_byte ());
1.1 root 411: } else if (size == 1) {
1.1.1.2 ! root 412: output ("#$%hx", (int)_rd_short ());
1.1 root 413: } else {
1.1.1.2 ! root 414: output ("#$%x", (int)_rd_int ());
1.1 root 415: }
416: }
417:
418: /*
419: * Disassemble _count bytes from _start.
420: */
421: void dump_code (int _start, int _count)
422: {
423: Opcode op;
424: int size;
425: int temp;
426: const char *str;
427: int last_ip;
428: buf_pos = _start;
429:
430: while (buf_pos < _start+_count) {
431: output ("\r\n$%x\t", buf_pos);
432: last_ip = buf_pos;
1.1.1.2 ! root 433: op.code = _rd_short ();
1.1 root 434: output ("($%hx)\t", op.code);
435: /* ABCD/SBCD */
436: while (op.abcd.OP16 == 16) {
437: if (op.abcd.OP12 == 12) output ("abcd\t");
438: else if (op.abcd.OP12 == 8) output ("sbcd\t");
439: else break;
440: if (op.abcd.rm) {
441: output ("-(a%d),-(a%d)", op.abcd.src_reg, op.abcd.dest_reg);
442: } else {
443: output ("d%d,d%d", op.abcd.src_reg, op.abcd.dest_reg);
444: }
445: goto done;
446: }
447: /* ADD/SUB */
448: while ((op.type2.op == 0xd) || (op.type2.op == 0x9)) {
449: if (op.type2.op == 0xd) str = "add";
450: else str = "sub";
451: if (op.type2.op_mode == 3) {
452: /* ADDA.W */
453: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
454: output ("%sa.w\t", str);
455: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
456: output (",a%d", op.type2.reg);
457: }
458: else if (op.type2.op_mode == 7) {
459: /* ADDA.L */
460: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2, -1)) break;
461: output ("%sa.l\t", str);
462: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2);
463: output (",a%d", op.type2.reg);
464: }
465: else if (op.type2.op_mode < 3) {
466: /* dest is reg */
467: /* no .b size Ax sources */
468: if ((op.type2.op_mode == 0) && (op.type2.ea_mode == 0x1)) break;
469: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode, -1)) break;
470: output ("%s%s\t", str, size_str[op.type2.op_mode]);
471: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode);
472: output (",d%d", op.type2.reg);
473: } else {
474: /* dest is ea */
475: if (op.type2.ea_mode == 0x0) break;
476: if (op.type2.ea_mode == 0x1) break;
477: if (op.type2.ea_mode == 0x7) {
478: if ((op.type2.ea_reg == 2) ||
479: (op.type2.ea_reg == 3) ||
480: (op.type2.ea_reg == 4)) break;
481: }
482: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4, -1)) break;
483: output ("%s%s\t", str, size_str[op.type2.op_mode-4]);
484: output ("d%d,", op.type2.reg);
485: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4);
486: }
487: goto done;
488: }
489: /* ADDI/SUBI */
490: while ((op.addi.OP6 == 6) || (op.addi.OP6 == 4)) {
491: if (op.addi.size == 3) break;
492: if (op.addi.dest_mode == 0x1) break;
493: if (op.addi.dest_mode == 0x7) {
494: if ((op.addi.dest_reg == 2) ||
495: (op.addi.dest_reg == 3) ||
496: (op.addi.dest_reg == 4)) break;
497: }
498: if (!is_adrmod (op.addi.dest_mode, op.addi.dest_reg, op.addi.size, op.addi.size)) break;
499: if (op.addi.OP6 == 6) output ("addi%s\t", size_str[op.addi.size]);
500: else output ("subi%s\t", size_str[op.addi.size]);
501: put_imm (op.addi.size);
502: output (",");
503: put_adrmod (op.addi.dest_mode, op.addi.dest_reg, op.addi.size);
504: goto done;
505: }
506: /* ADDQ/SUBQ */
507: while (op.addq.op == 0x5) {
508: if (op.addq.size == 3) break;
509: /* no immediate or pc relative dest */
510: if (op.addq.dest_mode == 0x7) {
511: if (op.addq.dest_reg > 0x1) break;
512: }
513: /* no addq.b to address registers */
514: if ((op.addq.size == 0) && (op.addq.dest_mode == 1)) break;
515: if (!is_adrmod (op.addq.dest_mode, op.addq.dest_reg, op.addq.size, -1)) break;
516: if (op.addq.issub) output ("subq%s\t", size_str[op.addq.size]);
517: else output ("addq%s\t", size_str[op.addq.size]);
518: output ("#%d,", (op.addq.data == 0 ? 8 : op.addq.data));
519: put_adrmod (op.addq.dest_mode, op.addq.dest_reg, op.addq.size);
520: goto done;
521: }
522: /* ADDX/SUBX */
523: while (((op.addx.op == 0xd) || (op.addx.op == 0x9)) && (op.addx.OP1 == 1) && (op.addx.OP0 == 0)) {
524: if (op.addx.size == 3) break;
525: if (op.addx.op == 0xd) output ("addx%s\t", size_str[op.addx.size]);
526: else output ("subx%s\t", size_str[op.addx.size]);
527: if (op.addx.rm) {
528: /* memory to memory */
529: output ("-(a%d),-(a%d)", op.addx.src_reg, op.addx.dest_reg);
530: } else {
531: output ("d%d,d%d", op.addx.src_reg, op.addx.dest_reg);
532: }
533:
534: goto done;
535: }
536: /* AND/OR */
537: while ((op.type2.op == 0xc) || (op.type2.op == 0x8)) {
538: if (op.type2.op_mode == 3) break;
539: if (op.type2.op_mode == 7) break;
540: if (op.type2.op == 0xc) str = "and";
541: else str = "or";
542: if (op.type2.op_mode < 3) {
543: /* dest is reg */
544: if (op.type2.ea_mode == 0x1) break;
545: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode, -1)) break;
546: output ("%s%s\t", str, size_str[op.type2.op_mode]);
547: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode);
548: output (",d%d", op.type2.reg);
549: } else {
550: /* dest is ea */
551: if (op.type2.ea_mode == 0x0) break;
552: if (op.type2.ea_mode == 0x1) break;
553: if (op.type2.ea_mode == 0x7) {
554: if (op.type2.ea_reg > 1) break;
555: }
556: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4, -1)) break;
557: output ("%s%s\t", str, size_str[op.type2.op_mode-4]);
558: output ("d%d,", op.type2.reg);
559: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode-4);
560: }
561: goto done;
562: }
563: /* ANDI/EORI/ORI */
564: while ((op.type1.op == 0x02) || (op.type1.op == 0xa) || (op.type1.op == 0x0)) {
565: if (op.type1.size == 3) break;
566: /* no address reg direct */
567: if (op.type1.ea_mode == 0x1) break;
568: /* no immediate or pc relative dest */
569: if (op.type1.ea_mode == 0x7) {
570: if (op.type1.ea_reg > 0x1) break;
571: }
572: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, op.type1.size)) break;
573: if (op.type1.op == 0x2) output ("andi%s\t", size_str[op.type1.size]);
574: else if (op.type1.op == 0xa) output ("eori%s\t", size_str[op.type1.size]);
575: else output ("ori%s\t", size_str[op.type1.size]);
576: put_imm (op.addi.size);
577: output (",");
578: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
579: goto done;
580: }
581: /* ANDI to CCR */
582: while (op.code == 0x023c) {
1.1.1.2 ! root 583: _rd_byte ();
! 584: output ("andi\t#$%x,ccr", _rd_byte ());
1.1 root 585: goto done;
586: }
587: /* ANDI to SR */
588: while (op.code == 0x027c) {
1.1.1.2 ! root 589: output ("andi\t#$%hx,sr", _rd_short ());
1.1 root 590: goto done;
591: }
592: /* ASx/LSx reg/imm */
593: while (op.ASx.OP0xe == 0xe) {
594: if (op.ASx.size == 3) break;
595: switch (op.ASx.OP0) {
596: case 0: str = "as"; break;
597: case 1: str = "ls"; break;
598: case 2: str = "rox"; break;
599: default: case 3: str = "ro"; break;
600: }
601: if (op.ASx.ir) {
602: /* data register shift */
603: output ("%s%c%s\td%d,d%d", str,
604: (op.ASx.dr ? 'l' : 'r'),
605: size_str[op.ASx.size],
606: op.ASx.count_reg, op.ASx.reg);
607: } else {
608: /* count shift thingy */
609: output ("%s%c%s\t#%d,d%d", str,
610: (op.ASx.dr ? 'l' : 'r'),
611: size_str[op.ASx.size],
612: (op.ASx.count_reg == 0 ? 8 : op.ASx.count_reg),
613: op.ASx.reg);
614: }
615: goto done;
616: }
617: /* ASx/LSx memory shift */
618: while ((op.MemShift.OP3 == 3) && (op.MemShift.OP0x1c == 0x1c)) {
619: if (op.type1.ea_mode < 0x2) break;
620: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
621: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
622: switch (op.MemShift.type) {
623: case 0: str = "as"; break;
624: case 1: str = "ls"; break;
625: case 2: str = "rox"; break;
626: default: case 3: str = "ro"; break;
627: }
628: output ("%s%c.w\t", str, (op.ASx.dr ? 'l' : 'r'));
629: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
630: goto done;
631: }
632: /* Bcc */
633: while (op.Bcc.op == 0x6) {
634: if (Bcc_str [op.Bcc.cond] == NULL) break;
635: if (op.bra.displacement) {
636: temp = buf_pos + op.Bcc.displacement;
637: output ("b%s.s\t", Bcc_str[op.Bcc.cond]);
638: output_lab (temp);
639: } else {
640: temp = buf_pos;
1.1.1.2 ! root 641: temp += _rd_short ();
1.1 root 642: output ("b%s.w\t", Bcc_str[op.Bcc.cond]);
643: output_lab (temp);
644: }
645: goto done;
646: }
647: /* BRA */
648: while (op.bra.op == 0x60) {
649: if (op.bra.displacement) {
650: temp = buf_pos + op.bra.displacement;
651: output ("bra.s\t");
652: output_lab (temp);
653: } else {
654: temp = buf_pos;
1.1.1.2 ! root 655: temp += _rd_short ();
1.1 root 656: output ("bra.w\t");
657: output_lab (temp);
658: }
659: goto done;
660: }
661: /* BSR */
662: while ((op.code & 0xff00) == 0x6100) {
663: if (op.bra.displacement) {
664: temp = buf_pos + op.bra.displacement;
665: output ("bsr.s\t");
666: output_lab (temp);
667: } else {
668: temp = buf_pos;
1.1.1.2 ! root 669: temp += _rd_short ();
1.1 root 670: output ("bsr.w\t");
671: output_lab (temp);
672: }
673: goto done;
674: }
675: /* BCHG/BCLR/BSET/BTST (Dn,ea) */
676: while ((op.type2.op == 0) && ((op.type2.op_mode == 0x4) || (op.type2.op_mode == 0x5) || (op.type2.op_mode == 0x6) || (op.type2.op_mode == 0x7))) {
677: if (op.type2.ea_mode == 0x1) break;
678: if ((op.type2.op_mode != 0x4) && (op.type2.ea_mode == 0x7)) {
679: if (op.type2.ea_reg > 1) break;
680: }
681: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2, -1)) break;
682:
683: if (op.type2.op_mode == 0x4) output ("btst\t");
684: else if (op.type2.op_mode == 0x5) output ("bchg\t");
685: else if (op.type2.op_mode == 0x6) output ("bclr\t");
686: else output ("bset\t");
687: output ("d%d,", op.type2.reg);
688: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2);
689: goto done;
690: }
691: /* BCHG/BCLR/BSET (#<data>,ea) */
692: while ((op.type2.op == 0) && (op.type2.reg == 4) &&
693: ((op.type2.op_mode == 0) || (op.type2.op_mode == 1) || (op.type2.op_mode == 2) || (op.type2.op_mode == 3))) {
694: if (op.type2.ea_mode == 0x1) break;
695: if ((op.type2.ea_mode == 0x7) && (op.type2.ea_reg > 1)) break;
696: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2, 1)) break;
1.1.1.2 ! root 697: temp = _rd_byte ();
1.1 root 698: if (temp != 0) {
699: buf_pos--;
700: break;
701: }
702: if (op.type2.op_mode == 0) {
703: output ("btst\t");
704: } else if (op.type2.op_mode == 1) {
705: output ("bchg\t");
706: } else if (op.type2.op_mode == 2) {
707: output ("bclr\t");
708: } else {
709: output ("bset\t");
710: }
1.1.1.2 ! root 711: output ("#$%x,", (int)_rd_byte ());
1.1 root 712: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 2);
713: goto done;
714: }
715: /* BKPT */
716: /*while ((op.code & 0xfff8) == 0x4848) {
717: output ("bkpt\t#%d", op.code & 0x7);
718: goto done;
719: }*/
720: /* CHK */
721: while ((op.type2.op == 0x4) && (op.type2.op_mode == 0x6)) {
722: /* no address reg direct */
723: if (op.type2.ea_mode == 0x1) break;
724: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
725:
726: output ("chk\t");
727: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
728: output (",d%d", op.type2.reg);
729:
730: goto done;
731: }
732: /* CLR */
733: while (op.type1.op == 0x42) {
734: if (op.type1.size == 3) break;
735: /* no address reg direct */
736: if (op.type1.ea_mode == 0x1) break;
737: /* no immediate or pc relative dest */
738: if (op.type1.ea_mode == 0x7) {
739: if (op.type1.ea_reg > 0x1) break;
740: }
741: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
742: output ("clr%s\t", size_str[op.type1.size]);
743: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
744: goto done;
745: }
746: /* CMP */
747: while (op.type2.op == 11) {
748: if (op.type2.op_mode > 2) break;
749: /* no .b size for adr reg direct */
750: if ((op.type2.op_mode == 0) && (op.type2.ea_mode == 0x1)) break;
751: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode, -1)) break;
752: output ("cmp%s\t", size_str[op.type2.op_mode]);
753: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, op.type2.op_mode);
754: output (",d%d", op.type2.reg);
755: goto done;
756: }
757: /* CMPA */
758: while (op.type2.op == 11) {
759: if ((op.type2.op_mode != 0x3) && (op.type2.op_mode != 0x7)) break;
760: if (op.type2.op_mode == 0x3) size = 1;
761: else size = 2;
762: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, size, -1)) break;
763: output ("cmpa%s\t", size_str [size]);
764: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, size);
765: output (",a%d", op.type2.reg);
766: goto done;
767: }
768: /* CMPI */
769: while ((op.type1.op == 0x0c) && (op.type1.size != 0x3)) {
770: if (op.type1.ea_mode == 0x1) break;
771: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
772: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, op.type1.size)) break;
773: output ("cmpi%s\t", size_str [op.type1.size]);
774: put_imm (op.type1.size);
775: output (",");
776: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
777: goto done;
778: }
779: /* CMPM */
780: while ((op.cmpm.OP0xb == 0xb) && (op.cmpm.OP2_1 == 0x1) && (op.cmpm.OP1_1 == 0x1)) {
781: if (op.cmpm.size == 3) break;
782: output ("cmpm%s\t(a%d)+,(a%d)+", size_str [op.cmpm.size], op.cmpm.src_reg, op.cmpm.dest_reg);
783: goto done;
784: }
785: /* DBcc */
786: while ((op.DBcc.OP5 == 5) && (op.DBcc.OP25 == 25)) {
787: if (DBcc_str [op.DBcc.cond] == NULL) break;
788: temp = buf_pos;
1.1.1.2 ! root 789: temp += _rd_short ();
1.1 root 790: output ("db%s\td%d,", DBcc_str[op.DBcc.cond],
791: op.DBcc.reg);
792: output_lab (temp);
793: goto done;
794: }
795: /* DIVS/DIVU */
796: while ((op.type2.op == 0x8) && ((op.type2.op_mode == 0x7) || (op.type2.op_mode == 0x3))) {
797: if (op.type2.ea_mode == 0x1) break;
798: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
799: if (op.type2.op_mode == 0x7) output ("divs\t");
800: else output ("divu\t");
801: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
802: output (",d%d", op.type2.reg);
803: goto done;
804: }
805: /* EOR */
806: while (op.type2.op == 0xb) {
807: if ((op.type2.op_mode < 4) || (op.type2.op_mode > 6)) break;
808: if (op.type2.ea_mode == 0x1) break;
809: if ((op.type2.ea_mode == 0x7) && (op.type2.ea_reg > 0x1)) break;
810: size = op.type2.op_mode - 4;
811: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, size, -1)) break;
812: output ("eor%s\t", size_str [size]);
813: output ("d%d,", op.type2.reg);
814: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, size);
815: goto done;
816: }
817: /* EORI to CCR */
818: while (op.code == 0x0a3c) {
1.1.1.2 ! root 819: _rd_byte ();
! 820: output ("eori\t#$%x,ccr", _rd_byte ());
1.1 root 821: goto done;
822: }
823: /* EORI to SR */
824: while (op.code == 0x0a7c) {
1.1.1.2 ! root 825: output ("eori\t#$%hx,sr", _rd_short ());
1.1 root 826: goto done;
827: }
828: /* EXG */
829: while ((op.exg.OP0xc == 0xc) && (op.exg.OP1 == 1)) {
830: if (op.exg.op_mode == 0x8) {
831: /* data reg swap */
832: output ("exg\td%d,d%d", op.exg.src_reg, op.exg.dest_reg);
833: } else if (op.exg.op_mode == 0x9) {
834: /* address reg swap */
835: output ("exg\ta%d,a%d", op.exg.src_reg, op.exg.dest_reg);
836: } else if (op.exg.op_mode == 0x11) {
837: /* data & adr reg swap */
838: output ("exg\td%d,a%d", op.exg.src_reg, op.exg.dest_reg);
839: } else {
840: break;
841: }
842: goto done;
843: }
844: /* EXT */
845: while ((op.code & 0xfe38) == 0x4800) {
846: if (op.type2.op_mode == 0x2) {
847: output ("ext.w\td%d", op.type2.ea_reg);
848: } else if (op.type2.op_mode == 0x3) {
849: output ("ext.l\td%d", op.type2.ea_reg);
850: } else {
851: break;
852: }
853: goto done;
854: }
855: /* ILLEGAL */
856: while (op.code == 0x4afc) {
857: output ("illegal");
858: goto done;
859: }
860: /* JMP */
861: while ((op.code & 0xffc0) == 0x4ec0) {
862: if (op.jmp.dest_mode == 0) break;
863: if (op.jmp.dest_mode == 1) break;
864: if (op.jmp.dest_mode == 3) break;
865: if (op.jmp.dest_mode == 4) break;
866: if ((op.jmp.dest_mode == 7) &&
867: (op.jmp.dest_reg == 4)) break;
868: if (!is_adrmod (op.jmp.dest_mode, op.jmp.dest_reg, 2, -1)) break;
869: output ("jmp\t");
870: temp = put_adrmod (op.jmp.dest_mode, op.jmp.dest_reg, 2);
871: goto done;
872: }
873: /* JSR */
874: while ((op.code & 0xffc0) == 0x4e80) {
875: if (op.type1.ea_mode == 0) break;
876: if (op.type1.ea_mode == 1) break;
877: if (op.type1.ea_mode == 3) break;
878: if (op.type1.ea_mode == 4) break;
879: /* no immediate dest */
880: if ((op.type1.ea_mode == 7) && (op.type1.ea_reg == 4)) break;
881: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 2, -1)) break;
882: output ("jsr\t");
883: temp = put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 2);
884: goto done;
885: }
886: /* LEA */
887: while ((op.lea.SEVEN == 7) && (op.lea.FOUR == 4)) {
888: if (op.lea.dest_mode == 0) break;
889: if (op.lea.dest_mode == 1) break;
890: if (op.lea.dest_mode == 3) break;
891: if (op.lea.dest_mode == 4) break;
892: /* no immediate dest */
893: if ((op.lea.dest_mode == 7) && (op.lea.dest_reg == 4)) break;
894: if (!is_adrmod (op.lea.dest_mode, op.lea.dest_reg, 2, -1)) break;
895: output ("lea\t");
896: put_adrmod (op.lea.dest_mode, op.lea.dest_reg, 2);
897: output (",a%d", op.lea.reg);
898: goto done;
899: }
900: /* LINK */
901: while ((op.code & 0xfff8) == 0x4e50) {
902: output ("link\ta%d,", op.type1.ea_reg);
903: put_imm (1);
904: goto done;
905: }
906: /* MOVE/MOVEA */
907: while (op.move.op == 0) {
908: if (op.move.size == 0) break;
909: /* byte size and address reg direct is not allowed */
910: if ((op.move.size == 1) && (op.move.src_mode == 0x1)) break;
911: if ((op.move.size == 1) && (op.move.dest_mode == 0x1)) break;
912: if (op.move.dest_mode == 0x7) {
913: if (op.move.dest_reg > 1) break;
914: }
915: size = move_size [op.move.size];
916: if (!is_adrmod (op.move.src_mode, op.move.src_reg, size, -1)) break;
917: if ((op.move.src_mode == 0x7) && (op.move.src_reg == 0x4)) {
918: /* immediate crap in the source so we must skip it */
919: if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, size)) break;
920: } else if ((op.move.src_mode == 0x7) && (op.move.src_reg > 0x1)) {
921: if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 1)) break;
922: } else if ((op.move.src_mode == 0x7) && (op.move.src_reg == 0x1)) {
923: if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 2)) break;
924: } else if ((op.move.src_mode == 0x7) && (op.move.src_reg == 0x0)) {
925: if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 1)) break;
926: } else if ((op.move.src_mode == 0x6) || (op.move.src_mode == 0x5)) {
927: /* PC with disp + Dx, (Ax) with disp + Dx */
928: if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, 1)) break;
929: } else {
930: if (!is_adrmod (op.move.dest_mode, op.move.dest_reg, size, -1)) break;
931: }
932: if (op.move.dest_mode == 0x1) {
933: output ("movea%s\t", size_str[size]);
934: } else {
935: output ("move%s\t", size_str[size]);
936: }
937:
938: put_adrmod (op.move.src_mode, op.move.src_reg, size);
939: output (",");
940: put_adrmod (op.move.dest_mode, op.move.dest_reg, size);
941: goto done;
942: }
943: /* MOVE to CCR */
944: while ((op.code & 0xffc0) == 0x44c0) {
945: if (op.type1.ea_mode == 0x1) break;
946: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
947: output ("move.w\t");
948: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
949: output (",ccr");
950: goto done;
951: }
952: /* MOVE from SR */
953: while ((op.code & 0xffc0) == 0x40c0) {
954: if (op.type1.ea_mode == 0x1) break;
955: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
956: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
957: output ("move.w\tsr,");
958: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
959: goto done;
960: }
961: /* MOVE to SR */
962: while ((op.code & 0xffc0) == 0x46c0) {
963: if (op.type1.ea_mode == 0x1) break;
964: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1, -1)) break;
965: output ("move.w\t");
966: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 1);
967: output (",sr");
968: goto done;
969: }
970: /* MOVE USP */
971: while ((op.code & 0xfff0) == 0x4e60) {
972: if (op.addx.rm) {
973: /* USP to Ax */
974: output ("move.l\tusp,a%d", op.addx.src_reg);
975: } else {
976: output ("move.l\ta%d,usp", op.addx.src_reg);
977: }
978: goto done;
979: }
980: /* TODO MOVEC */
981: /* TODO MOVEP */
982: /* MOVEM */
983: while ((op.movem.NINE == 9) && (op.movem.ONE == 1)) {
984: if (op.movem.dr) {
985: /* memory to register */
986: if (op.movem.dest_mode < 2) break;
987: if (op.movem.dest_mode == 4) break;
988: if ((op.movem.dest_mode == 7) && (op.movem.dest_reg == 4)) break;
989: if (!is_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1, 1)) break;
1.1.1.2 ! root 990: temp = _rd_short ();
1.1 root 991: output ("movem%s\t", size_str [op.movem.sz+1]);
992: put_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1);
993: output (",");
994: put_movem_regs (temp, 0);
995: } else {
996: /* register to memory */
997: if (op.movem.dest_mode < 2) break;
998: if (op.movem.dest_mode == 3) break;
999: if ((op.movem.dest_mode == 7) && (op.movem.dest_reg > 1)) break;
1000: if (!is_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1, 1)) break;
1001: output ("movem%s\t", size_str [op.movem.sz+1]);
1.1.1.2 ! root 1002: put_movem_regs (_rd_short (), (op.movem.dest_mode == 4));
1.1 root 1003: output (",");
1004: put_adrmod (op.movem.dest_mode, op.movem.dest_reg, op.movem.sz+1);
1005: }
1006: goto done;
1007: }
1008: /* MOVEQ */
1009: while ((op.moveq.SEVEN == 7) && (op.moveq.ZERO == 0)) {
1010: output ("moveq\t#%d,d%d", op.moveq.data, op.moveq.reg);
1011: goto done;
1012: }
1013: /* MULS/MULU */
1014: while ((op.type2.op == 0xc) && ((op.type2.op_mode == 0x7) || (op.type2.op_mode == 0x3))) {
1015: if (op.type2.ea_mode == 0x1) break;
1016: if (!is_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1, -1)) break;
1017: if (op.type2.op_mode == 0x7) output ("muls\t");
1018: else output ("mulu\t");
1019: put_adrmod (op.type2.ea_mode, op.type2.ea_reg, 1);
1020: output (",d%d", op.type2.reg);
1021: goto done;
1022: }
1023: /* NBCD */
1024: while ((op.code & 0xffc0) == 0x4800) {
1025: if (op.type1.ea_mode == 0x1) break;
1026: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 1)) break;
1027: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0, -1)) break;
1028: output ("nbcd\t");
1029: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0);
1030: goto done;
1031: }
1032: /* NEG/NEGX/NOT */
1033: while ((op.type1.op == 0x44) || (op.type1.op == 0x40) || (op.type1.op == 0x46)) {
1034: if (op.type1.size == 3) break;
1035: if (op.type1.ea_mode == 0x1) break;
1036: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 1)) break;
1037: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
1038: if (op.type1.op == 0x44) output ("neg%s\t", size_str [op.type1.size]);
1039: else if (op.type1.op == 0x40) output ("negx%s\t", size_str [op.type1.size]);
1040: else output ("not%s\t", size_str [op.type1.size]);
1041: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
1042: goto done;
1043: }
1044: /* NOP */
1045: while (op.code == 0x4e71) {
1046: output ("nop");
1047: goto done;
1048: }
1049: /* ORI to CCR */
1050: while (op.code == 0x003c) {
1.1.1.2 ! root 1051: _rd_byte ();
! 1052: output ("ori\t#$%x,ccr", _rd_byte ());
1.1 root 1053: goto done;
1054: }
1055: /* ORI to SR */
1056: while (op.code == 0x007c) {
1.1.1.2 ! root 1057: output ("ori\t#$%hx,sr", _rd_short ());
1.1 root 1058: goto done;
1059: }
1060: /* PEA */
1061: while ((op.code & 0xffc0) == 0x4840) {
1062: if (op.type1.ea_mode < 2) break;
1063: if (op.type1.ea_mode == 3) break;
1064: if (op.type1.ea_mode == 4) break;
1065: if ((op.type1.ea_mode == 7) && (op.type1.ea_reg == 4)) break;
1066: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
1067: output ("pea\t");
1068: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 2);
1069: goto done;
1070: }
1071: /* RESET */
1072: while (op.code == 0x4e70) {
1073: output ("reset");
1074: goto done;
1075: }
1076: /* RTE */
1077: while (op.code == 0x4e73) {
1078: output ("rte");
1079: goto done;
1080: }
1081: /* RTR */
1082: while (op.code == 0x4e77) {
1083: output ("rtr");
1084: goto done;
1085: }
1086: /* RTS */
1087: while (op.code == 0x4e75) {
1088: output ("rts");
1089: goto done;
1090: }
1091: /* Scc */
1092: while ((op.code & 0xf0c0) == 0x50c0) {
1093: if (op.type1.ea_mode == 1) break;
1094: if ((op.type1.ea_mode == 7) && (op.type1.ea_reg > 1)) break;
1095: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0, -1)) break;
1096: output ("s%s\t", DBcc_str[op.DBcc.cond]);
1097: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0);
1098: goto done;
1099: }
1100: /* STOP */
1101: while (op.code == 0x4e72) {
1102: output ("stop\t");
1103: put_imm (1);
1104: goto done;
1105: }
1106: /* SWAP */
1107: while ((op.code & 0xfff8) == 0x4840) {
1108: output ("swap\td%d", op.code & 0x7);
1109: goto done;
1110: }
1111: /* TAS */
1112: while ((op.code & 0xffc0) == 0x4ac0) {
1113: if (op.type1.ea_mode == 0x1) break;
1114: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
1115: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0, -1)) break;
1116: output ("tas\t");
1117: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, 0);
1118: goto done;
1119: }
1120: /* TRAP */
1121: while ((op.code & 0xfff0) == 0x4e40) {
1122: output ("trap\t#%d", op.code & 0xf);
1123: goto done;
1124: }
1125: /* TRAPV */
1126: while (op.code == 0x4e76) {
1127: output ("trapv");
1128: goto done;
1129: }
1130: /* TST */
1131: while (op.type1.op == 0x4a) {
1132: if (op.type1.size == 3) break;
1133: /* no address reg direct */
1134: if (op.type1.ea_mode == 0x1) break;
1135: /* no immediate or pc relative dest */
1136: if ((op.type1.ea_mode == 0x7) && (op.type1.ea_reg > 0x1)) break;
1137: if (!is_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size, -1)) break;
1138: output ("tst%s\t", size_str[op.type1.size]);
1139: put_adrmod (op.type1.ea_mode, op.type1.ea_reg, op.type1.size);
1140: goto done;
1141: }
1142: /* UNLK */
1143: while ((op.code & 0xfff8) == 0x4e58) {
1144: output ("unlk\ta%d", op.code & 0x7);
1145: goto done;
1146: }
1147: /* fuck knows */
1148: output ("dc.w\t$%hx", op.code);
1149: done:
1150: continue;
1151: }
1152: output ("\r\n");
1153: }
1154:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.