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