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