|
|
1.1 root 1: /*
2: * disassemble 68020 opcodes
3: */
4:
5: #include "defs.h"
6: #include "optab.h"
7: #include "space.h"
8:
9: #define SZ_MASK 00300
10: #define SZ_SHIFT 6 /* bits (7-6) */
11:
12: extern long A6base;
13: static int dorand();
14: static int ea();
15: static int doindex();
16: static int dcr();
17: static char *fcr();
18:
19: static struct opmask {
20: long mask;
21: int shift;
22: } opmask[] = {
23: 0, 0, /* DIG 0 ignore this address */
24: 0x0000003f, 0, /* DEA 1 E.A. to low order 6 bits */
25: 0x00000007, 0, /* DRG 2 register to low order 3 bits */
26: 0x00000e00, 9, /* DRGL 3 register to bits 11-9 */
27: 0x000000ff, 0, /* DBR 4 branch offset (short) */
28: 0x000000ff, 0, /* DMQ 5 move-quick 8-bit value */
29: 0x00000e00, 9, /* DAQ 6 add-quick 3-bit value in 11-9 */
30: 0, 0, /* DIM 7 Immediate value, according to size */
31: 0x00000fc0, 6, /* DEAM 8 E.A. to bits 11-6 as in move */
32: 0, 0, /* DBCC 9 branch address as in "dbcc" */
33: 0x0000000f, 0, /* DTRAP 10 immediate in low 4 bits */
34: 0x00070000, 16, /* D2L 11 register to bits 0-2 of next word */
35: 0x70000000, 16+12, /* D2H 12 register to bits 12-14 of next word */
36: 0x001f0000, 16, /* DBL 13 qty in bits 0-5 of next word */
37: 0x07c00000, 16+6, /* DBH 14 qty in bits 6-11 of next word */
38: 0x0fff0000, 16, /* DCR 15 control reg a bit combination in 0-11 */
39: 0x00000007, 0, /* DBKPT 16 immediate in low 3 bits */
40: 0x1c000000, 16+10, /* DFSRC 17 floating source specifier */
41: 0x03800000, 16+7, /* DFDRG 18 floating destination register */
42: 0x1c000000, 16+10, /* DFSRG 19 floating source register */
43: 0x007f0000, 16, /* DFCR 20 floating constant register */
44: 0x00000040, 0, /* DFBR 21 floating branch offset */
45: 0x00ff0000, 16, /* DFMRGM 22 FMOVE register mask */
46: 0x1c000000, 16+10, /* DFMRGM 23 FMOVE register mask */
47: };
48:
49: static int dsp;
50: extern struct optab optab[];
51:
52: printins(isp)
53: int isp;
54: {
55: register struct optab *op;
56: register int i;
57: register WORD w, w1;
58: int w1f = 0;
59:
60: dsp = isp;
61: w = stow(sget(dot, isp));
62: chkerr();
63: for (op = optab; op->opname; op++) {
64: if ((w & op->mask) != op->opcode)
65: continue;
66: if ((op->flags & I2W) == 0)
67: break; /* 1-word match */
68: if (w1f == 0) {
69: w1 = stow(sget(dot+2, isp));
70: w1f++;
71: }
72: if ((w1 & op->mk2) == op->op2)
73: break; /* 2-word match */
74: }
75: if (op->opname == NULL) {
76: printf("\tnumber\t%R", w);
77: dotinc = 2;
78: return;
79: }
80: w &= 0xffff;
81: if ((op->flags & I2W) == 0)
82: dotinc = 2;
83: else {
84: w |= w1 << 16;
85: dotinc = 4;
86: }
87: printf("\t%s", op->opname);
88: for (i = 0; i < op->nrand; i++) {
89: if (i == 0)
90: printf("\t");
91: else
92: printf(",");
93: dorand(w, op->rand[i], op->flags & SZ);
94: }
95: }
96:
97: #define ENSIGN(x) ((WORD)(short)(x))
98:
99: static
100: dorand(w, rand, size)
101: register WORD w;
102: register short rand;
103: int size;
104: {
105: struct opmask *om;
106: WORD lval;
107: register int val;
108:
109: om = &opmask[rand & DMASK];
110: if (om->mask)
111: val = (w & om->mask) >> om->shift;
112: switch(rand & DMASK) {
113: case DEA: /* effective address spec */
114: ea(val >> 3, val & 07, size);
115: return;
116:
117: case DRG: /* abs register */
118: case DRGL:
119: case D2H:
120: case D2L:
121: if (rand & ADEC)
122: printf("-(A%d)", val);
123: else if (rand & AINC)
124: printf("(A%d)+", val);
125: else if (rand & AAREG)
126: printf("A%d", val);
127: else if (rand & ADREG)
128: printf("R%d", val);
129: else
130: printf("DRGgok");
131: return;
132:
133: case DBR: /* branch displacement */
134: lval = val;
135: if (val == 0) {
136: lval = stow(sget(dot+dotinc, dsp));
137: if (lval & 0x8000)
138: lval |= ~0xffff;
139: dotinc += 2;
140: }
141: else if (val == 0xff) {
142: lval = ltow(lget(dot+dotinc, dsp));
143: dotinc += 4;
144: }
145: else if (val & 0x80)
146: lval |= ~0xff;
147: lval += dot + 2;
148: psymoff(lval, dsp, "");
149: return;
150:
151: case DBH: /* 6-bit strange quick */
152: case DBL: /* other 6-bit strange quick */
153: if (val & 040) {
154: printf("%%d%d", val & 07);
155: return;
156: }
157: /* fall through */
158: case DMQ: /* 8-bit quick */
159: case DTRAP: /* 4-bit quick */
160: printf("$Q");
161: psymoff((WORD)val, dsp, "");
162: return;
163:
164: case DBKPT: /* 3-bit quick */
165: printf("$Q");
166: psymoff((WORD)val, dsp, "");
167: return;
168:
169: case DAQ: /* silly 3-bit immediate */
170: if (val == 0)
171: val = 8;
172: printf("$Q");
173: psymoff((WORD)val, dsp, "");
174: return;
175:
176: case DIM: /* immediate */
177: if (rand & AONE) {
178: printf("$Q1");
179: return;
180: }
181: if (rand & AWORD)
182: size = W;
183: switch ((int)size) {
184: case B:
185: lval = stow(sget(dot+dotinc, dsp)) & 0377;
186: if (val & 0200)
187: val |= ~0377; /* sign extend */
188: dotinc += 2; /* sic */
189: break;
190:
191: case W:
192: lval = ENSIGN(stow(sget(dot+dotinc, dsp)));
193: dotinc += 2;
194: break;
195:
196: case L:
197: lval = ltow(lget(dot+dotinc, dsp));
198: dotinc += 4;
199: break;
200:
201: default:
202: lval = 0;
203: }
204: printf("$");
205: psymoff(lval, dsp, "");
206: return;
207:
208: case DEAM: /* assinine backwards ea */
209: ea(val & 07, val >> 3, size);
210: return;
211:
212: case DBCC: /* branch displacement a la dbcc */
213: lval = stow(sget(dot+dotinc, dsp));
214: dotinc += 2;
215: lval += dot + 2;
216: psymoff(lval, dsp, "");
217: return;
218:
219: case DCR:
220: dcr(val);
221: return;
222:
223: case DSREG:
224: if (rand & C)
225: printf("CCR");
226: else if (rand & SR)
227: printf("SR");
228: else if (rand & U)
229: printf("USP");
230: else
231: printf("GOKdsreg");
232: return;
233:
234: case DFSRC:
235: printf("F%d", val);
236: return;
237:
238: case DFDRG:
239: case DFSRG:
240: printf("F%d", val);
241: return;
242:
243: case DFCR:
244: printf("$%s", fcr((int)val));
245: return;
246:
247: case DFBR: /* floating branch displacement */
248: if (val == 0) {
249: lval = stow(sget(dot+dotinc, dsp));
250: if (lval & 0x8000)
251: lval |= ~0xffff;
252: dotinc += 2;
253: }
254: else {
255: lval = ltow(lget(dot+dotinc, dsp));
256: dotinc += 4;
257: }
258: lval += dot + 2;
259: psymoff(lval, dsp, "");
260: return;
261:
262: case DFMRGM:
263: case DFMCRGM:
264: printf("$%x", val);
265: return;
266: }
267: printf("GOK");
268: }
269:
270: static
271: ea(mode, reg, size)
272: int mode, reg;
273: {
274: WORD disp;
275: float sval;
276: double dval;
277: switch((int)mode){
278: case 0: /* data reg */
279: printf("R%d", reg);
280: return;
281:
282: case 1: /* addr reg */
283: printf("A%d", reg);
284: return;
285:
286: case 2: /* addr reg indir */
287: printf("(A%d)", reg);
288: return;
289:
290: case 3: /* addr reg indir incr */
291: printf("(A%d)+", reg);
292: return;
293:
294: case 4: /* addr reg indir decr */
295: printf("-(A%d)", reg);
296: return;
297:
298: case 5: /* addr reg indir with displ */
299: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
300: dotinc += 2;
301: psymoff(disp, dsp, "");
302: printf("(A%d)", reg);
303: if (reg == 6) {
304: printf(".");
305: psymoff(disp+A6base, DATASP, "");
306: }
307: return;
308:
309: case 6: /* wretched indexing */
310: doindex(reg); /* ugh */
311: return;
312:
313: case 7: /* non-register stuff: */
314: switch ((int)reg) {
315: case 0: /* absolute short */
316: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
317: dotinc += 2;
318: psymoff(disp, dsp, "");
319: printf("($0)");
320: return;
321:
322: case 1: /* absolute long */
323: disp = ltow(lget(dot+dotinc, dsp));
324: dotinc += 4;
325: psymoff(disp, dsp, "");
326: printf("($0)");
327: return;
328:
329: case 4: /* immediate */
330: switch((int)size) {
331: case B:
332: disp = ENSIGN(ctow(cget(dot+dotinc, dsp)));
333: dotinc += 2; /* sic */
334: printf("$");
335: psymoff(disp, dsp, "");
336: return;
337:
338: case W:
339: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
340: dotinc += 2;
341: printf("$");
342: psymoff(disp, dsp, "");
343: return;
344:
345: case L:
346: disp = ltow(lget(dot+dotinc, dsp));
347: dotinc += 4;
348: printf("$");
349: psymoff(disp, dsp, "");
350: return;
351:
352: case D:
353: fget(dot+dotinc, dsp, (char *)&dval, sizeof dval);
354: printf("$");
355: fpout('f', &dval);
356: dotinc += sizeof dval;
357: return;
358:
359: case F:
360: fget(dot+dotinc, dsp, (char *)&sval, sizeof sval);
361: printf("$");
362: dval = sval;
363: fpout('f', &dval);
364: dotinc += sizeof sval;
365: return;
366: }
367: }
368: }
369: printf("gok%d:%d", mode, reg);
370: }
371:
372: static
373: doindex(reg)
374: int reg;
375: {
376: register WORD w;
377: register WORD base, outer;
378:
379: base = outer = 0;
380: w = stow(sget(dot+dotinc, dsp));
381: dotinc += 2;
382: if ((w & 0x100) == 0) { /* brief format */
383: base = w & 0x7f;
384: if (base & 0x40)
385: base |= ~0x7f;
386: }
387: else { /* full format */
388: switch ((int)(w & 0x30)) {
389: case 0: /* ugh */
390: case 0x10: /* null displacement */
391: break;
392:
393: case 0x20:
394: base = stow(sget(dot+dotinc, dsp));
395: if (base & 0x8000)
396: base |= 0xFFFF0000; /* sign extend */
397: outer = stow(sget(dot+dotinc+2, dsp));
398: if (!(w&0x80))
399: dotinc += 2; /* for base */
400: if ((w&7)==2 || (w&7)==3)
401: dotinc += 2; /* for outer */
402: break;
403:
404: case 0x30:
405: base = ltow(lget(dot+dotinc, dsp));
406: if (base & 0x8000)
407: base |= 0xFFFF0000; /* sign extend */
408: outer = ltow(lget(dot+dotinc+4, dsp));
409: if (!(w&0x80))
410: dotinc += 4; /* for base */
411: if ((w&7)==2 || (w&7)==3)
412: dotinc += 2; /* for outer */
413: break;
414: }
415: }
416: if ((w & 0x100) && (w & 0x47)) {
417: if ((w&7)==2 || (w&7)==3 && outer)
418: psymoff(outer, dsp, "");
419: printf("(");
420: }
421: if (base)
422: psymoff(base, dsp, "");
423: printf("(A%d)", reg);
424: if ((w & 0x100) && (w & 0x4))
425: printf(")");
426: if (reg == 6) {
427: printf(".");
428: psymoff(base+A6base, DATASP, "");
429: }
430: if (!(w & 0x40)) {
431: printf("(%c%d.%c", w&0100000 ? 'A' : 'R', (int)(w>>12)&07,
432: w&04000 ? 'L' : 'W');
433: printf("*%D)", (WORD)1<<((w>>9)&03));
434: }
435: if ((w & 0x100) && (w & 0x43) && !(w & 0x4))
436: printf(")");
437: }
438:
439: static
440: dcr(reg)
441: int reg;
442: {
443:
444: switch (reg) {
445: case 0x000:
446: printf("SFC");
447: return;
448:
449: case 0x001:
450: printf("DFC");
451: return;
452:
453: case 0x002:
454: printf("CACR");
455: return;
456:
457: case 0x800:
458: printf("USP");
459: return;
460:
461: case 0x801:
462: printf("VBR");
463: return;
464:
465: case 0x802:
466: printf("CAAR");
467: return;
468:
469: case 0x803:
470: printf("MSP");
471: return;
472:
473: case 0x804:
474: printf("ISP");
475: return;
476:
477: default:
478: printf("CR%x", reg);
479: return;
480: }
481: }
482:
483: static struct{
484: int c;
485: char *name;
486: }fcrtab[]={
487: 0x00, "C_PI",
488: 0x0b, "C_LOG10(2)",
489: 0x0c, "C_E",
490: 0x0d, "C_LOG2(E)",
491: 0x0e, "C_LOG10(E)",
492: 0x0f, "C_0.0",
493: 0x30, "C_LOGN(2)",
494: 0x31, "C_LOGN(10)",
495: 0x32, "C_TENTO0",
496: 0x33, "C_TENTO1",
497: 0x34, "C_TENTO2",
498: 0x35, "C_TENTO4",
499: 0x36, "C_TENTO8",
500: 0x37, "C_TENTO16",
501: 0x38, "C_TENTO32",
502: 0x39, "C_TENTO64",
503: 0x3a, "C_TENTO128",
504: 0x3b, "C_TENTO256",
505: 0x3c, "C_TENTO512",
506: 0x3d, "C_TENTO1024",
507: 0x3e, "C_TENTO2048",
508: 0x3f, "C_TENTO4096",
509: 0x00, (char *)0,
510: };
511:
512: static
513: char *
514: fcr(c)
515: {
516: int i;
517:
518: for (i=0; fcrtab[i].name; i++)
519: if (c == fcrtab[i].c)
520: return fcrtab[i].name;
521: return "strangeconstant";
522: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.