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