|
|
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.