|
|
1.1 root 1: /*
2: * disassemble 68020 opcodes
3: */
4:
5: #include "defs.h"
6: #include "optab.h"
7:
8: #define SZ_MASK 00300
9: #define SZ_SHIFT 6 /* bits (7-6) */
10:
11: static struct opmask {
12: long mask;
13: int shift;
14: } opmask[] = {
15: 0, 0, /* DIG 0 ignore this address */
16: 0x0000003f, 0, /* DEA 1 E.A. to low order 6 bits */
17: 0x00000007, 0, /* DRG 2 register to low order 3 bits */
18: 0x00000e00, 9, /* DRGL 3 register to bits 11-9 */
19: 0x000000ff, 0, /* DBR 4 branch offset (short) */
20: 0x000000ff, 0, /* DMQ 5 move-quick 8-bit value */
21: 0x00000e00, 9, /* DAQ 6 add-quick 3-bit value in 11-9 */
22: 0, 0, /* DIM 7 Immediate value, according to size */
23: 0x00000fc0, 6, /* DEAM 8 E.A. to bits 11-6 as in move */
24: 0, 0, /* DBCC 9 branch address as in "dbcc" */
25: 0x0000000f, 0, /* DTRAP 10 immediate in low 4 bits */
26: 0x00070000, 16, /* D2L 11 register to bits 0-2 of next word */
27: 0x70000000, 16+12, /* D2H 12 register to bits 12-14 of next word */
28: 0x001f0000, 16, /* DBL 13 qty in bits 0-5 of next word */
29: 0x07c00000, 16+6, /* DBH 14 qty in bits 6-11 of next word */
30: 0x0fff0000, 16, /* DCR 15 control reg a bit combination in 0-11 */
31: };
32:
33: static int dsp;
34: extern struct optab optab[];
35:
36: printins(isp)
37: int isp;
38: {
39: register struct optab *op;
40: register int i;
41: register WORD w, w1;
42: int w1f = 0;
43:
44: dsp = isp;
45: w = stow(sget(dot, isp));
46: chkerr();
47: for (op = optab; op->opname; op++) {
48: if ((w & op->mask) != op->opcode)
49: continue;
50: if ((op->flags & I2W) == 0)
51: break; /* 1-word match */
52: if (w1f == 0) {
53: w1 = stow(sget(dot+2, isp));
54: w1f++;
55: }
56: if ((w1 & op->mk2) == op->op2)
57: break; /* 2-word match */
58: }
59: if (op->opname == NULL) {
60: printf("\tnumber\t%R", w);
61: dotinc = 2;
62: return;
63: }
64: w &= 0xffff;
65: if ((op->flags & I2W) == 0)
66: dotinc = 2;
67: else {
68: w |= w1 << 16;
69: dotinc = 4;
70: }
71: printf("\t%s", op->opname);
72: for (i = 0; i < op->nrand; i++) {
73: if (i == 0)
74: printf("\t");
75: else
76: printf(",");
77: dorand(w, op->rand[i], op->flags & SZ);
78: }
79: }
80:
81: #define ENSIGN(x) ((WORD)(short)(x))
82:
83: static
84: dorand(w, rand, size)
85: register WORD w;
86: register short rand;
87: int size;
88: {
89: struct opmask *om;
90: WORD lval;
91: register int val;
92:
93: om = &opmask[rand & DMASK];
94: if (om->mask)
95: val = (w & om->mask) >> om->shift;
96: switch(rand & DMASK) {
97: case DEA: /* effective address spec */
98: ea(val >> 3, val & 07, size);
99: return;
100:
101: case DRG: /* abs register */
102: case DRGL:
103: case D2H:
104: case D2L:
105: if (rand & ADEC)
106: printf("-(%%a%d)", val);
107: else if (rand & AINC)
108: printf("(%%a%d)+", val);
109: else if (rand & AAREG)
110: printf("%%a%d", val);
111: else if (rand & ADREG)
112: printf("%%d%d", val);
113: else
114: printf("DRGgok");
115: return;
116:
117: case DBR: /* branch displacement */
118: lval = val;
119: if (val == 0) {
120: lval = stow(sget(dot+dotinc, dsp));
121: if (lval & 0x8000)
122: lval |= ~0xffff;
123: dotinc += 2;
124: }
125: else if (val == 0xff) {
126: lval = ltow(lget(dot+dotinc, dsp));
127: dotinc += 4;
128: }
129: else if (val & 0x80)
130: lval |= ~0xff;
131: lval += dot + 2;
132: psymoff(lval, dsp, "");
133: return;
134:
135: case DBH: /* 6-bit strange quick */
136: case DBL: /* other 6-bit strange quick */
137: if (val & 040) {
138: printf("%%d%d", val & 07);
139: return;
140: }
141: /* fall through */
142: case DMQ: /* 8-bit quick */
143: case DTRAP: /* 4-bit quick */
144: printf("&");
145: psymoff((WORD)val, dsp, "");
146: return;
147:
148: case DAQ: /* silly 3-bit immediate */
149: if (val == 0)
150: val = 8;
151: printf("&");
152: psymoff((WORD)val, dsp, "");
153: return;
154:
155: case DIM: /* immediate */
156: if (rand & AONE) {
157: printf("&1");
158: return;
159: }
160: if (rand & AWORD)
161: size = W;
162: switch ((int)size) {
163: case B:
164: lval = stow(sget(dot+dotinc, dsp)) & 0377;
165: if (val & 0200)
166: val |= ~0377; /* sign extend */
167: dotinc += 2; /* sic */
168: break;
169:
170: case W:
171: lval = ENSIGN(stow(sget(dot+dotinc, dsp)));
172: dotinc += 2;
173: break;
174:
175: case L:
176: lval = ltow(lget(dot+dotinc, dsp));
177: dotinc += 4;
178: break;
179:
180: default:
181: lval = 0;
182: }
183: printf("&");
184: psymoff(lval, dsp, "");
185: return;
186:
187: case DEAM: /* assinine backwards ea */
188: ea(val & 07, val >> 3, size);
189: return;
190:
191: case DBCC: /* branch displacement a la dbcc */
192: lval = stow(sget(dot+dotinc, dsp));
193: dotinc += 2;
194: lval += dot + 2;
195: psymoff(lval, dsp, "");
196: return;
197:
198: case DCR:
199: dcr(val);
200: return;
201:
202: case DSREG:
203: if (rand & C)
204: printf("%%ccr");
205: else if (rand & SR)
206: printf("%%sr");
207: else if (rand & U)
208: printf("%%usp");
209: else
210: printf("%%GOKdsreg");
211: return;
212: }
213: printf("GOK");
214: }
215:
216: static
217: ea(mode, reg, size)
218: int mode, reg;
219: {
220: WORD disp;
221:
222: switch((int)mode){
223: case 0: /* data reg */
224: printf("%%d%d", reg);
225: return;
226:
227: case 1: /* addr reg */
228: printf("%%a%d", reg);
229: return;
230:
231: case 2: /* addr reg indir */
232: printf("(%%a%d)", reg);
233: return;
234:
235: case 3: /* addr reg indir incr */
236: printf("(%%a%d)+", reg);
237: return;
238:
239: case 4: /* addr reg indir decr */
240: printf("-(%%a%d)", reg);
241: return;
242:
243: case 5: /* addr reg indir with displ */
244: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
245: dotinc += 2;
246: psymoff(disp, dsp, "");
247: printf("(%%a%d)", reg);
248: return;
249:
250: case 6: /* wretched indexing */
251: doindex(reg); /* ugh */
252: return;
253:
254: case 7: /* non-register stuff: */
255: switch ((int)reg) {
256: case 0: /* absolute short */
257: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
258: dotinc += 2;
259: psymoff(disp, dsp, "");
260: return;
261:
262: case 1: /* absolute long */
263: disp = ltow(lget(dot+dotinc, dsp));
264: dotinc += 4;
265: psymoff(disp, dsp, "");
266: return;
267:
268: case 4: /* immediate */
269: switch((int)size) {
270: case B:
271: disp = ENSIGN(ctow(cget(dot+dotinc, dsp)));
272: dotinc += 2; /* sic */
273: printf("&");
274: psymoff(disp, dsp, "");
275: return;
276:
277: case W:
278: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
279: dotinc += 2;
280: printf("&");
281: psymoff(disp, dsp, "");
282: return;
283:
284: case L:
285: disp = ltow(lget(dot+dotinc, dsp));
286: dotinc += 4;
287: printf("&");
288: psymoff(disp, dsp, "");
289: return;
290: }
291: }
292: }
293: printf("gok%d:%d", mode, reg);
294: }
295:
296: static
297: doindex(reg)
298: int reg;
299: {
300: register WORD w;
301: register WORD base, outer;
302:
303: base = outer = 0;
304: w = stow(sget(dot+dotinc, dsp));
305: dotinc += 2;
306: if ((w & 0x80) == 0) { /* brief format */
307: base = w & 0x7f;
308: if (base & 0x40)
309: base |= ~0x7f;
310: }
311: else { /* full format */
312: switch ((int)(w & 0x30)) {
313: case 0: /* ugh */
314: case 0x10: /* null displacement */
315: break;
316:
317: case 0x20:
318: base = stow(sget(dot+dotinc, dsp));
319: outer = stow(sget(dot+dotinc+2, dsp));
320: dotinc += 4;
321: break;
322:
323: case 0x30:
324: base = ltow(lget(dot+dotinc, dsp));
325: outer = ltow(lget(dot+dotinc+4, dsp));
326: dotinc += 8;
327: break;
328: }
329: }
330: psymoff(base, dsp, "");
331: printf("(%%a%d,", reg);
332: printf("%%%c%d.%c", w&0100000 ? 'a' : 'd', (int)(w>>12)&07,
333: w&04000 ? 'l' : 'w');
334: printf("*%D)", (WORD)1<<((w>>9)&03));
335: if (w & 0x80)
336: psymoff(outer, dsp, "");
337: }
338:
339: static
340: dcr(reg)
341: int reg;
342: {
343:
344: switch (reg) {
345: case 0x000:
346: printf("%%sfc");
347: return;
348:
349: case 0x001:
350: printf("%%dfc");
351: return;
352:
353: case 0x002:
354: printf("%%cacr");
355: return;
356:
357: case 0x800:
358: printf("%%usp");
359: return;
360:
361: case 0x801:
362: printf("%%vbr");
363: return;
364:
365: case 0x802:
366: printf("%%caar");
367: return;
368:
369: case 0x803:
370: printf("%%msp");
371: return;
372:
373: case 0x804:
374: printf("%%isp");
375: return;
376:
377: default:
378: printf("%%cr%x", reg);
379: return;
380: }
381: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.