|
|
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 val;
91:
92: om = &opmask[rand & DMASK];
93: if (om->mask)
94: val = (w & om->mask) >> om->shift;
95: switch(rand & DMASK) {
96: case DEA: /* effective address spec */
97: ea(val >> 3, val & 07, size);
98: return;
99:
100: case DRG: /* abs register */
101: case DRGL:
102: case D2H:
103: case D2L:
104: if (rand & ADEC)
105: printf("-(%%a%d)", val);
106: else if (rand & AINC)
107: printf("(%%a%d)+", val);
108: else if (rand & AAREG)
109: printf("%%a%d", val);
110: else if (rand & ADREG)
111: printf("%%d%d", val);
112: else
113: printf("DRGgok");
114: return;
115:
116: case DBR: /* branch displacement */
117: if (val == 0) {
118: val = stow(sget(dot+dotinc, dsp));
119: if (val & 0x8000)
120: val |= ~0xffff;
121: dotinc += 2;
122: }
123: else if (val == 0xff) {
124: val = ltow(lget(dot+dotinc, dsp));
125: dotinc += 4;
126: }
127: else if (val & 0x80)
128: val |= ~0xff;
129: val += dot + 2;
130: psymoff(val, dsp, "");
131: return;
132:
133: case DBH: /* 6-bit strange quick */
134: case DBL: /* other 6-bit strange quick */
135: if (val & 040) {
136: printf("%%d%d", val & 07);
137: return;
138: }
139: /* fall through */
140: case DMQ: /* 8-bit quick */
141: case DTRAP: /* 4-bit quick */
142: printf("&");
143: psymoff(val, dsp, "");
144: return;
145:
146: case DAQ: /* silly 3-bit immediate */
147: if (val == 0)
148: val = 8;
149: printf("&");
150: psymoff(val, dsp, "");
151: return;
152:
153: case DIM: /* immediate */
154: if (rand & AONE) {
155: printf("&1");
156: return;
157: }
158: if (rand & AWORD)
159: size = W;
160: switch (size) {
161: case B:
162: val = ENSIGN(ctow(cget(dot+dotinc, dsp)));
163: dotinc += 2; /* sic */
164: break;
165:
166: case W:
167: val = ENSIGN(stow(sget(dot+dotinc, dsp)));
168: dotinc += 2;
169: break;
170:
171: case L:
172: val = ltow(lget(dot+dotinc, dsp));
173: dotinc += 4;
174: break;
175: }
176: printf("&");
177: psymoff(val, dsp, "");
178: return;
179:
180: case DEAM: /* assinine backwards ea */
181: ea(val & 07, val >> 3, size);
182: return;
183:
184: case DBCC: /* branch displacement a la dbcc */
185: val = stow(sget(dot+dotinc, dsp));
186: dotinc += 2;
187: val += dot + 2;
188: psymoff(val, dsp, "");
189: return;
190:
191: case DCR:
192: dcr(val);
193: return;
194:
195: case DSREG:
196: if (rand & C)
197: printf("%%ccr");
198: else if (rand & SR)
199: printf("%%sr");
200: else if (rand & U)
201: printf("%%usp");
202: else
203: printf("%%GOKdsreg");
204: return;
205: }
206: printf("GOK");
207: }
208:
209: static
210: ea(mode, reg, size)
211: int mode, reg;
212: {
213: WORD disp;
214:
215: switch(mode){
216: case 0: /* data reg */
217: printf("%%d%d", reg);
218: return;
219:
220: case 1: /* addr reg */
221: printf("%%a%d", reg);
222: return;
223:
224: case 2: /* addr reg indir */
225: printf("(%%a%d)", reg);
226: return;
227:
228: case 3: /* addr reg indir incr */
229: printf("(%%a%d)+", reg);
230: return;
231:
232: case 4: /* addr reg indir decr */
233: printf("-(%%a%d)", reg);
234: return;
235:
236: case 5: /* addr reg indir with displ */
237: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
238: dotinc += 2;
239: psymoff(disp, dsp, "");
240: printf("(%%a%d)", reg);
241: return;
242:
243: case 6: /* wretched indexing */
244: doindex(reg); /* ugh */
245: return;
246:
247: case 7: /* non-register stuff: */
248: switch (reg) {
249: case 0: /* absolute short */
250: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
251: dotinc += 2;
252: psymoff(disp, dsp, "");
253: return;
254:
255: case 1: /* absolute long */
256: disp = ltow(lget(dot+dotinc, dsp));
257: dotinc += 4;
258: psymoff(disp, dsp, "");
259: return;
260:
261: case 4: /* immediate */
262: switch(size) {
263: case B:
264: disp = ENSIGN(ctow(cget(dot+dotinc, dsp)));
265: dotinc += 2; /* sic */
266: printf("&");
267: psymoff(disp, dsp, "");
268: return;
269:
270: case W:
271: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
272: dotinc += 2;
273: printf("&");
274: psymoff(disp, dsp, "");
275: return;
276:
277: case L:
278: disp = ltow(lget(dot+dotinc, dsp));
279: dotinc += 4;
280: printf("&");
281: psymoff(disp, dsp, "");
282: return;
283: }
284: }
285: }
286: printf("gok%d:%d", mode, reg);
287: }
288:
289: static
290: doindex(reg)
291: int reg;
292: {
293: register WORD w;
294: register WORD base, outer;
295:
296: base = outer = 0;
297: w = stow(sget(dot+dotinc, dsp));
298: dotinc += 2;
299: if ((w & 0x80) == 0) { /* brief format */
300: base = w & 0x7f;
301: if (base & 0x40)
302: base |= ~0x7f;
303: }
304: else { /* full format */
305: switch (w & 0x30) {
306: case 0: /* ugh */
307: case 0x10: /* null displacement */
308: break;
309:
310: case 0x20:
311: base = stow(sget(dot+dotinc, dsp));
312: outer = stow(sget(dot+dotinc+2, dsp));
313: dotinc += 4;
314: break;
315:
316: case 0x30:
317: base = ltow(lget(dot+dotinc, dsp));
318: outer = ltow(lget(dot+dotinc+4, dsp));
319: dotinc += 8;
320: break;
321: }
322: }
323: psymoff(base, dsp, "");
324: printf("(%%a%d,", reg);
325: printf("%%%c%d.%c", w&0100000 ? 'a' : 'd', (w>>12)&07,
326: w&04000 ? 'l' : 'w');
327: printf("*%d)", 1<<((w>>9)&03));
328: if (w & 0x80)
329: psymoff(outer, dsp, "");
330: }
331:
332: static
333: dcr(reg)
334: int reg;
335: {
336:
337: switch (reg) {
338: case 0x000:
339: printf("%%sfc");
340: return;
341:
342: case 0x001:
343: printf("%%dfc");
344: return;
345:
346: case 0x002:
347: printf("%%cacr");
348: return;
349:
350: case 0x800:
351: printf("%%usp");
352: return;
353:
354: case 0x801:
355: printf("%%vbr");
356: return;
357:
358: case 0x802:
359: printf("%%caar");
360: return;
361:
362: case 0x803:
363: printf("%%msp");
364: return;
365:
366: case 0x804:
367: printf("%%isp");
368: return;
369:
370: default:
371: printf("%%cr%x", reg);
372: return;
373: }
374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.