|
|
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:
35: printins(isp)
36: int isp;
37: {
38: register struct optab *op;
39: register int i;
40: register WORD w, w1;
41: int w1f = 0;
42: extern struct optab optab[];
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 DMQ: /* 8-bit quick */
134: case DBH: /* 6-bit strange quick */
135: case DTRAP: /* 4-bit quick */
136: case DBL: /* other 6-bit strange quick */
137: printf("&");
138: psymoff(val, dsp, "");
139: return;
140:
141: case DAQ: /* silly 3-bit immediate */
142: if (val == 0)
143: val = 8;
144: printf("&");
145: psymoff(val, dsp, "");
146: return;
147:
148: case DIM: /* immediate */
149: if (rand & AONE) {
150: printf("&1");
151: return;
152: }
153: if (rand & AWORD)
154: size = W;
155: switch (size) {
156: case B:
157: val = ENSIGN(ctow(cget(dot+dotinc, dsp)));
158: dotinc += 2; /* sic */
159: break;
160:
161: case W:
162: val = ENSIGN(stow(sget(dot+dotinc, dsp)));
163: dotinc += 2;
164: break;
165:
166: case L:
167: val = stow(sget(dot+dotinc, dsp));
168: dotinc += 2;
169: break;
170: }
171: printf("&");
172: psymoff(val, dsp, "");
173: return;
174:
175: case DEAM: /* assinine backwards ea */
176: ea(val & 07, val >> 3, size);
177: return;
178:
179: case DBCC: /* branch displacement a la dbcc */
180: val = stow(sget(dot+dotinc, dsp));
181: dotinc += 2;
182: val += dot + 2;
183: psymoff(val, dsp, "");
184: return;
185:
186: case DCR:
187: dcr(val);
188: return;
189:
190: case DSREG:
191: if (rand & C)
192: printf("%%ccr");
193: else if (rand & SR)
194: printf("%%sr");
195: else if (rand & U)
196: printf("%%usp");
197: else
198: printf("%%GOKdsreg");
199: return;
200: }
201: printf("GOK");
202: }
203:
204: static
205: ea(mode, reg, size)
206: int mode, reg;
207: {
208: WORD disp;
209:
210: switch(mode){
211: case 0:
212: printf("%%d%d", reg);
213: return;
214:
215: case 1:
216: printf("%%a%d", reg);
217: return;
218:
219: case 2:
220: printf("(%%a%d)", reg);
221: return;
222:
223: case 3:
224: printf("(%%a%d)+", reg);
225: return;
226:
227: case 4:
228: printf("-(%%a%d)", reg);
229: return;
230:
231: case 5:
232: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
233: dotinc += 2;
234: psymoff(disp, dsp, "");
235: printf("(%%a%d)", reg);
236: return;
237:
238: case 6:
239: doindex(); /* ugh */
240: return;
241:
242: case 7:
243: switch (reg) {
244: case 0:
245: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
246: dotinc += 2;
247: psymoff(disp, dsp, "");
248: return;
249:
250: case 1:
251: disp = ltow(lget(dot+dotinc, dsp));
252: dotinc += 4;
253: psymoff(disp, dsp, "");
254: return;
255:
256: case 4:
257: switch(size) {
258: case B:
259: disp = ENSIGN(ctow(cget(dot+dotinc, dsp)));
260: dotinc += 2; /* sic */
261: psymoff(disp, dsp, "");
262: return;
263:
264: case W:
265: disp = ENSIGN(stow(sget(dot+dotinc, dsp)));
266: dotinc += 2;
267: psymoff(disp, dsp, "");
268: return;
269:
270: case L:
271: disp = ltow(lget(dot+dotinc, dsp));
272: dotinc += 4;
273: psymoff(disp, dsp, "");
274: return;
275: }
276: }
277: }
278: printf("gok%d:%d", mode, reg);
279: }
280:
281: static
282: doindex()
283: {
284: register WORD w;
285: register WORD base, outer;
286:
287: base = outer = 0;
288: w = stow(sget(dot+dotinc, dsp));
289: dotinc += 2;
290: if ((w & 0x80) == 0) { /* brief format */
291: base = w & 0x7f;
292: if (base & 0x40)
293: base |= ~0x7f;
294: }
295: else { /* full format */
296: switch (w & 0x30) {
297: case 0: /* ugh */
298: case 0x10: /* null displacement */
299: break;
300:
301: case 0x20:
302: base = stow(sget(dot+dotinc, dsp));
303: outer = stow(sget(dot+dotinc+2, dsp));
304: dotinc += 4;
305: break;
306:
307: case 0x30:
308: base = ltow(lget(dot+dotinc, dsp));
309: outer = ltow(lget(dot+dotinc+4, dsp));
310: dotinc += 8;
311: break;
312: }
313: }
314: /* stuff */
315: printf("index");
316: }
317:
318: static
319: dcr(reg)
320: int reg;
321: {
322:
323: switch (reg) {
324: case 0x000:
325: printf("%sfc");
326: return;
327:
328: case 0x001:
329: printf("%dfc");
330: return;
331:
332: case 0x002:
333: printf("%cacr");
334: return;
335:
336: case 0x800:
337: printf("%usp");
338: return;
339:
340: case 0x801:
341: printf("%vbr");
342: return;
343:
344: case 0x802:
345: printf("%caar");
346: return;
347:
348: case 0x803:
349: printf("%msp");
350: return;
351:
352: case 0x804:
353: printf("%isp");
354: return;
355:
356: default:
357: printf("%cr%x", reg);
358: return;
359: }
360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.