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
- */
- /*
- * Modifications:
- * - in case of ailure to disassemble print operand as a constant
- * in 'dc.w' instruction
- * - make printout to align in a nicer way
- *
- * Michal Jaegermann, November 1990
- */
-
- #include "adb.h"
-
- extern long dot;
- extern int dotoff;
- extern int opcode_pos; /* this value depends on resolution */
-
- #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;
- int ar_pos;
-
- align (opcode_pos);
-
- op = nextw ();
-
- if (!(*funhi[op >> 12]) (op, ar_pos = opcode_pos + ALIGN_OP)) {
- prt ("dc.w");
- align (ar_pos);
- prtn ((unsigned long) op, 0);
- }
- }
-
-
- #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, pos)
- unsigned int op;
- int pos;
- {
- return tblop (op, t0, pos);
- }
-
- 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, pos)
- unsigned int op;
- int pos;
- {
- 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");
- align (pos);
- modepr (sm, sr);
- putchr (',');
- modepr (dm, dr);
- return 1;
- }
- return 0;
- }
-
- op2 (op, pos)
- unsigned int op;
- int pos;
- {
- 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");
- align (pos);
- modepr (sm, sr);
- putchr (',');
- modepr (dm, dr);
- return 1;
- }
- return 0;
- }
-
- op3 (op, pos)
- unsigned int op;
- int pos;
- {
- 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");
- align (pos);
- 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, pos)
- unsigned int op;
- int pos;
- {
- int mode, reg, list;
-
- if ((op & 07600) == 06200) {
- reg = op & 7;
- mode = (op >> 3) & 7;
- if (valid (mode, reg, 01576)) {
- prtf ("movem.%c", op & 0100 ? 'l' : 'w');
- align (pos);
- list = nextw ();
- modepr (mode, reg);
- putchr (',');
- rlist (list);
- return 1;
- }
- else
- return 0;
- }
- return tblop (op, t4, pos);
- }
-
- tblop (op, tp, pos)
- unsigned op;
- register struct optbl *tp;
- int pos;
- {
- 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:
- align (pos);
-
- 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, pos)
- unsigned int op;
- int pos;
- {
- 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", bnm[cond]);
- align (pos);
- prtf ("%d,%A", reg, svdot + nextw ());
- return 1;
- }
- else if (valid (mode, reg, 05770)) {
- prtf ("s%s", bnm[cond]);
- align (pos);
- 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" : "addq.%c", szchr[sz]);
- align (pos);
- prtf ("#%i,", k);
- modepr (mode, reg);
- return 1;
- }
- }
- return 0;
- }
-
- op6 (op, pos)
- unsigned int op;
- int pos;
- {
- 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]);
- align (pos);
- prtf ("%A", svdot);
- return 1;
- }
-
- op7 (op, pos)
- unsigned int op;
- int pos;
- {
- register int val, reg, k;
-
- if (val = (0 == (op & 0x100))) {
- k = (char) op;
- reg = (op >> 9) & 7;
- prt ("moveq");
- align (pos);
- prtf ("#%i,%d", k, reg);
- }
- return val;
- }
-
- 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, pos)
- unsigned int op;
- int pos;
- {
- return tblop (op, t8, pos);
- }
-
- 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, pos)
- unsigned int op;
- int pos;
- {
- return tblop (op, t9, pos);
- }
-
- opa (op, pos)
- unsigned int op;
- int pos;
- {
- 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, pos)
- unsigned int op;
- int pos;
- {
- return tblop (op, tb, pos);
- }
-
- 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, pos)
- unsigned op;
- int pos;
- {
- return tblop (op, tc, pos);
- }
-
- 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, pos)
- unsigned int op;
- int pos;
- {
- return tblop (op, td, pos);
- }
-
- char *shiftnm[] = {"as", "ls", "rox", "ro"};
-
- ope (op, pos)
- unsigned int op;
- int pos;
- {
- 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,", shiftnm[(op >> 9) & 3],
- (op & 0x100) ? 'l' : 'r');
- align (pos);
- prtf ("#1,");
- modepr (mode, reg);
- return 1;
- }
- }
- else {
- prtf ("%s%c.%c", shiftnm[(op >> 3) & 3],
- (op & 0x100) ? 'l' : 'r', szchr[sz]);
- align (pos);
- 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 (op, pos)
- unsigned int op;
- int pos;
- {
- return 0;
- }
-