home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1990 by Sozobon, Limited. Authors: Johann Ruegg, Don Dugger
- *
- * Permission is granted to anyone to use this software for any purpose
- * on any computer system, and to redistribute it freely, with the
- * following restrictions:
- * 1) No charge may be made other than reasonable charges for reproduction.
- * 2) Modified versions must be clearly marked as such.
- * 3) The authors are not responsible for any harmful consequences
- * of using this software, even if they result from defects in it.
- *
- * dis3.c
- */
-
- #include "adb.h"
-
- extern long dot;
- extern int dotoff;
- #define DOT (dot+dotoff)
-
- int cursz;
-
- nextw()
- {
- return getwd();
- }
-
- long
- nextl()
- {
- unsigned int i[2];
-
- i[0] = getwd();
- i[1] = getwd();
- return ((long)i[0]) << 16 | i[1];
- }
-
- int op0(), op1(), op2(), op3(), op4(), op5(), op6(), op7();
- int op8(), op9(), opa(), opb(), opc(), opd(), ope(), opf();
-
- int (*funhi[])() = {
- op0, op1, op2, op3, op4, op5, op6, op7,
- op8, op9, opa, opb, opc, opd, ope, opf
- };
-
- puti()
- {
- unsigned int op;
-
- align(20);
-
- op = nextw();
-
- if ( (*funhi[op>>12])(op) )
- ;
- else
- prt("???");
- }
-
-
- #define M_IMM 1
- #define M_PX 2
- #define M_POFF 4
- #define M_ABSL 010
- #define M_ABSW 020
- #define M_AX 040
- #define M_AOFF 0100
- #define M_ADEC 0200
- #define M_AINC 0400
- #define M_ATA 01000
- #define M_AREG 02000
- #define M_DREG 04000
-
- valid(mode,reg,mask)
- {
- if (mode == 7)
- switch (reg) {
- case 0:
- return mask & M_ABSW;
- case 1:
- return mask & M_ABSL;
- case 2:
- return mask & M_POFF;
- case 3:
- return mask & M_PX;
- case 4:
- return mask & M_IMM;
- default:
- return 0;
- }
- else
- switch (mode) {
- case 0:
- return mask & M_DREG;
- case 1:
- return mask & M_AREG;
- case 2:
- return mask & M_ATA;
- case 3:
- return mask & M_AINC;
- case 4:
- return mask & M_ADEC;
- case 5:
- return mask & M_AOFF;
- case 6:
- return mask & M_AX;
- }
- }
-
- ix_str(n)
- {
- int op, r;
- char c;
- char *fmt;
-
- op = nextw();
- r = (op>>12) & 7;
- c = (op & 0x800) ? 'l' : 'w';
- if (n >= 8) {
- if (op<0)
- fmt = "%i(pc,%a.%c)";
- else
- fmt = "%i(pc,%d.%c)";
- prtf(fmt, (char)op, r, c);
- } else {
- if (op < 0)
- fmt = "%i(%a,%a.%c)";
- else
- fmt = "%i(%a,%d.%c)";
- prtf(fmt, (char)op, n, r, c);
- }
- }
-
- modepr(mode,reg)
- {
- char *p;
-
- switch (mode) {
- case 0:
- prtf("%d", reg);
- break;
- case 1:
- prtf("%a", reg);
- break;
- case 2:
- prtf("(%a)", reg);
- break;
- case 3:
- prtf("(%a)+", reg);
- break;
- case 4:
- prtf("-(%a)", reg);
- break;
- case 5:
- prtf("%i(%a)", nextw(), reg);
- break;
- case 6:
- ix_str(reg);
- break;
- case 7:
- switch (reg) {
- case 0:
- prtf("%i", nextw());
- break;
- case 1:
- longval();
- break;
- case 2:
- prtf("%i(pc)", nextw());
- break;
- case 3:
- ix_str(8);
- break;
- case 4:
- switch (cursz) {
- case 0:
- case 1:
- prtf("#%i", nextw());
- break;
- case 2:
- putchr('#');
- longval();
- break;
- }
- break;
- }
- }
- }
-
- longval()
- {
- long l;
- struct sym *sp;
-
- prtf("%A", nextl());
- }
-
- char szchr[] = { 'b', 'w', 'l' };
-
- struct optbl {
- char sel[6];
- char *name;
- int allow;
- char arg[4];
- char sz;
- };
-
- struct optbl t0[] = {
- { "0s", "or", 05770, "ie"},
- { "00", "or", 1, "ic"},
- { "01", "or", 1, "is", 1},
- { "*4", "btst", 05777, "De"},
- { "*5", "bchg", 05770, "De"},
- { "*6", "bclr", 05770, "De"},
- { "*7", "bset", 05770, "De"},
- { "*4", "movep.w", 02000, "oD"},
- { "*5", "movep.l", 02000, "oD"},
- { "*6", "movep.w", 02000, "Do"},
- { "*7", "movep.l", 02000, "Do"},
- { "1s", "and", 05770, "ie"},
- { "10", "and", 1, "ic"},
- { "11", "and", 1, "is", 1},
- { "2s", "sub", 05770, "ie"},
- { "3s", "add", 05770, "ie"},
- { "40", "btst", 05776, "ie"},
- { "41", "bchg", 05770, "ie"},
- { "42", "bclr", 05770, "ie"},
- { "43", "bset", 05770, "ie"},
- { "5s", "eor", 05770, "ie"},
- { "50", "eor", 1, "ic"},
- { "51", "eor", 1, "is", 1},
- { "6s", "cmp", 05770, "ie"},
- { 0, 0, 0, 0 }
- };
-
- op0(op)
- {
- return tblop(op, t0);
- }
-
- match(c, val)
- {
- switch (c) {
- case '*':
- return 1;
- case 's':
- return val <= 2;
- case 'S':
- return val >= 4 && val <= 6;
- case 'z':
- return val >= 1 && val <= 2;
- case 'Z':
- return val == 3 || val == 7;
- default:
- return val == (c - '0');
- }
- }
-
- op1(op)
- {
- int sm, sr, dm, dr;
-
- sm = (op>>3) & 7;
- sr = op & 7;
- dm = (op>>6) & 7;
- dr = (op>>9) & 7;
- cursz = 0;
- if (valid(sm,sr,07777) && valid(dm,dr,05770)) {
- prt("move.b\t");
- modepr(sm,sr);
- putchr(',');
- modepr(dm,dr);
- return 1;
- }
- return 0;
- }
-
- op2(op)
- {
- int sm, sr, dm, dr;
-
- sm = (op>>3) & 7;
- sr = op & 7;
- dm = (op>>6) & 7;
- dr = (op>>9) & 7;
- cursz = 2;
- if (valid(sm,sr,07777) && valid(dm,dr,07770)) {
- prt("move.l\t");
- modepr(sm,sr);
- putchr(',');
- modepr(dm,dr);
- return 1;
- }
- return 0;
- }
-
- op3(op)
- {
- int sm, sr, dm, dr;
-
- sm = (op>>3) & 7;
- sr = op & 7;
- dm = (op>>6) & 7;
- dr = (op>>9) & 7;
- cursz = 1;
- if (valid(sm,sr,07777) && valid(dm,dr,07770)) {
- prt("move.w\t");
- modepr(sm,sr);
- putchr(',');
- modepr(dm,dr);
- return 1;
- }
- return 0;
- }
-
- struct optbl t4[] = {
- { "0s", "negx", 05770, "e"},
- { "03", "move.w", 05770, "se"},
- { "*6", "chk", 05777, "eD"},
- { "*7", "lea", 01176, "eA"},
- { "1s", "clr", 05770, "e"},
- { "2s", "neg", 05770, "e"},
- { "23", "move.b", 05777, "ec"},
- { "3s", "not", 05770, "e"},
- { "33", "move.w", 05777, "es", 1},
- { "40", "nbcd", 05770, "e"},
- { "41", "swap", 04000, "d"},
- { "41", "pea", 01176, "e"},
- { "42", "ext.w", 04000, "d"},
- { "42", "movem.w", 01170, "le"},
- { "42", "movem.w", 00200, "Le"},
- { "43", "movem.l", 01170, "le"},
- { "43", "movem.l", 00200, "Le"},
- { "43", "ext.l", 04000, "d"},
- { "5s", "tst", 05770, "e"},
- { "53", "tas", 05770, "e"},
- { "53", "illegal", 0001, ""},
- { "71", "trap", 06000, "t"},
- { "71", "link", 01000, "ai", 1},
- { "71", "unlk", 00400, "a"},
- { "71", "move", 00200, "au"},
- { "71", "move", 00100, "ua"},
- { "7160", "reset", 0, ""},
- { "7161", "nop", 0, ""},
- { "7162", "stop", 0, ""},
- { "7163", "rte", 0, ""},
- { "7165", "rts", 0, ""},
- { "7166", "trapv", 0, ""},
- { "7167", "rtr", 0, ""},
- { "72", "jsr", 01176, "e"},
- { "73", "jmp", 01176, "e"},
- { 0, 0, 0, 0 }
- };
-
- op4(op)
- {
- int mode, reg, list;
-
- if ((op & 07600) == 06200) {
- reg = op & 7;
- mode = (op>>3) & 7;
- if (valid(mode,reg,01576)) {
- prtf("movem.%c\t", op & 0100 ? 'l' : 'w');
- list = nextw();
- modepr(mode,reg);
- putchr(',');
- rlist(list);
- return 1;
- } else
- return 0;
- }
- return tblop(op, t4);
- }
-
- tblop(op, tp)
- register struct optbl *tp;
- {
- int mode, reg;
- int hi,lo;
-
- reg = op & 7;
- mode = (op>>3) & 7;
- lo = (op>>6) & 7;
- hi = (op>>9) & 7;
-
- for (; tp->name; tp++)
- if (match(tp->sel[0], hi) &&
- match(tp->sel[1], lo) &&
- (tp->allow == 0 || valid(mode,reg,tp->allow)) &&
- (tp->sel[2] == 0 || match(tp->sel[2], mode)) &&
- (tp->sel[3] == 0 || match(tp->sel[3], reg)) ) {
-
- prt(tp->name);
-
- switch (tp->sel[1]) {
- case 's':
- cursz = lo;
- break;
- case 'S':
- cursz = lo-4;
- break;
- case 'z':
- cursz = (lo==1) ? 1 : 2;
- break;
- case 'Z':
- cursz = (lo==3) ? 1 : 2;
- break;
- default:
- cursz = tp->sz;
- goto noszpr;
- }
-
- prtf(".%c", szchr[cursz]);
- noszpr:
- putchr('\t');
-
- if (tp->arg[0]) {
- puta(tp->arg[0],op);
- if (tp->arg[1]) {
- putchr(',');
- puta(tp->arg[1],op);
- }
- }
- return 1;
- }
- return 0;
- }
-
- puta(c, op)
- {
- int reg,mode,hi;
-
- reg = op & 7;
- mode = (op>>3) & 7;
- hi = (op>>9) & 7;
-
- switch (c) {
- case 'i':
- modepr(7,4);
- break;
- case 'e':
- modepr(mode,reg);
- break;
- case 'c':
- prt("ccr");
- break;
- case 's':
- prt("sr");
- break;
- case 'D':
- modepr(0,hi);
- break;
- case 'd':
- modepr(0,reg);
- break;
- case 'A':
- modepr(1,hi);
- break;
- case 'a':
- modepr(1,reg);
- break;
- case 'o':
- modepr(5,reg);
- break;
- case 'm':
- modepr(4,reg);
- break;
- case 'M':
- modepr(4,hi);
- break;
- case 'p':
- modepr(3,reg);
- break;
- case 'P':
- modepr(3,hi);
- break;
- case 'l':
- rlist(nextw());
- break;
- case 'L':
- blist(nextw());
- break;
- case 'u':
- prt("usp");
- break;
- case 't':
- prtf("#%i", op & 0xf);
- break;
- case 'k':
- prtf("#%i", hi ? hi : 8);
- break;
- }
- }
-
- rlist(x)
- {
- int as, ds;
-
- ds = x & 0xff;
- as = (x>>8) & 0xff;
- putchr('[');
- if (ds) {
- listc('d', ds);
- if (as) {
- putchr(',');
- listc('a', as);
- }
- } else if (as)
- listc('a', as);
- putchr(']');
- }
-
- listc(c, x)
- char c;
- {
- int i;
-
- for (i=0; i<8; )
- if (x & (1<<i))
- i += chunk(c, x, i);
- else
- i++;
- }
-
- chunk(c, x, i)
- char c;
- {
- int j;
-
- putchr(c);
- j = cnt1s(x>>i);
- if (j == 1) {
- putchr('0'+i);
- return j;
- } else {
- putchr('0'+i);
- putchr('-');
- putchr('0'+i+(j-1));
- return j;
- }
- }
-
- cnt1s(x)
- {
- int i;
-
- for (i=0; i<9; i++)
- if ((x & (1<<i)) == 0)
- return i;
- }
-
- blist(x)
- {
- int y;
- int i;
- unsigned uw = 0x8000;
-
- y = 0;
- for (i=0; i<16; i++)
- if (x & (1<<i))
- y |= (uw>>i);
- rlist(y);
- }
-
- char *bnm[] = { "t", "f", "hi", "ls",
- "cc", "cs", "ne", "eq",
- "vc", "vs", "pl", "mi",
- "ge", "lt", "gt", "le" };
-
- op5(op)
- {
- int cond, mode, reg;
- int sz, k;
- long svdot = DOT;
-
- sz = (op>>6) & 3;
- reg = op & 7;
- mode = (op>>3) & 7;
-
- if (sz == 3) {
- cond = (op>>8) & 0xf;
- if (mode == 1) {
- prtf("db%s\t%d,%A", bnm[cond], reg,
- svdot+nextw());
- return 1;
- } else if (valid(mode,reg,05770)) {
- prtf("s%s\t", bnm[cond]);
- modepr(mode,reg);
- return 1;
- }
- } else {
- k = (op>>9) & 7;
- if (k == 0) k = 8;
- if (valid(mode,reg, sz ? 07770 : 05770)) {
- prtf((op&0x100) ? "subq.%c\t" : "addq.%c\t",
- szchr[sz]);
- prtf("#%i,", k);
- modepr(mode,reg);
- return 1;
- }
- }
- return 0;
- }
-
- op6(op)
- {
- int cond, k;
- long svdot = DOT;
-
- cond = (op>>8) & 0xf;
- k = (char)op;
- if (k == 0)
- svdot += nextw();
- else
- svdot += k;
- if (cond < 2)
- prt(cond ? "bsr" : "bra");
- else
- prtf("b%s", bnm[cond]);
- prtf("\t%A", svdot);
- return 1;
- }
-
- op7(op)
- {
- int reg, k;
-
- if (op & 0x100)
- return;
- k = (char)op;
- reg = (op>>9) & 7;
- prtf("moveq\t#%i,%d", k, reg);
- return 1;
- }
-
- struct optbl t8[] = {
- { "*s", "or", 05777, "eD"},
- { "*S", "or", 01770, "De"},
- { "*3", "divu", 05777, "eD"},
- { "*7", "divs", 05777, "eD"},
- { "*4", "sbcd", 04000, "dD"},
- { "*4", "sbcd", 02000, "mM"},
- { 0, 0, 0, 0}
- };
-
- op8(op)
- {
- return tblop(op, t8);
- }
-
- struct optbl t9[] = {
- {"*0", "sub.b", 05777, "eD"},
- {"*z", "sub", 07777, "eD"},
- {"*S", "sub", 01770, "De"},
- {"*Z", "sub", 07777, "eA"},
- {"*S", "subx", 04000, "dD"},
- {"*S", "subx", 02000, "mM"},
- { 0, 0, 0, 0}
- };
-
- op9(op)
- {
- return tblop(op, t9);
- }
-
- opa()
- {
- return 0;
- }
-
- struct optbl tb[] = {
- {"*0", "cmp.b", 05777, "eD"},
- {"*z", "cmp", 07777, "eD"},
- {"*Z", "cmp", 07777, "eA"},
- {"*S", "eor", 05770, "De"},
- {"*S", "cmpm", 02000, "pP"},
- {0, 0, 0, 0}
- };
-
- opb(op)
- {
- return tblop(op, tb);
- }
-
- struct optbl tc[] = {
- {"*s", "and", 05777, "eD"},
- {"*S", "and", 01770, "De"},
- {"*3", "mulu", 05777, "eD"},
- {"*7", "muls", 05777, "eD"},
- {"*4", "abcd", 04000, "dD"},
- {"*4", "abcd", 02000, "mM"},
- {"*5", "exg", 04000, "dD"},
- {"*5", "exg", 02000, "aA"},
- {"*6", "exg", 02000, "aD"},
- {0, 0, 0, 0}
- };
-
- opc(op)
- {
- return tblop(op, tc);
- }
-
- struct optbl td[] = {
- {"*0", "add.b", 05777, "eD"},
- {"*z", "add", 07777, "eD"},
- {"*S", "add", 01770, "De"},
- {"*Z", "add", 07777, "eA"},
- {"*S", "addx", 04000, "dD"},
- {"*S", "addx", 02000, "mM"},
- { 0, 0, 0, 0}
- };
-
- opd(op)
- {
- return tblop(op, td);
- }
-
- char *shiftnm[] = { "as", "ls", "rox", "ro" };
-
- ope(op)
- {
- int sz, c_r;
- int mode, reg;
-
- sz = (op>>6) & 3;
- if (sz == 3) {
- mode = (op>>3) & 7;
- reg = op & 7;
- if (valid(mode,reg,01770)) {
- prtf("%s%c.w\t #1,", shiftnm[(op>>9)&3],
- (op&0x100) ? 'l' : 'r');
- modepr(mode,reg);
- return 1;
- }
- } else {
- prtf("%s%c.%c\t", shiftnm[(op>>3)&3],
- (op&0x100) ? 'l' : 'r',
- szchr[sz]);
- c_r = (op>>9) & 7;
- if (op & 040)
- prtf("%d", c_r);
- else
- prtf("#%i", c_r ? c_r : 8);
- prtf(",%d", op & 7);
- return 1;
- }
- return 0;
- }
-
- opf()
- {
- return 0;
- }
-