Path: utzoo!attcan!uunet!husc6!rutgers!att!lzaz!bds From: bds@lzaz.ATT.COM (B.SZABLAK) Newsgroups: comp.os.minix Subject: Minix Debugger for the ATARI ST (Part 4/4) Message-ID: <327@lzaz.ATT.COM> Date: 21 Dec 88 22:05:39 GMT Organization: AT&T ISL Lincroft NJ USA Lines: 428 /* * mdbdis.c - MINIX program disassembler for the debugger * * Written by Bruce D. Szablak * * This free software is provided for non-commerical use. No warrantee * of fitness for any use is implied. You get what you pay for. Anyone * may make modifications and distribute them, but please keep this header * in the distribution. */ #include #define BYTE 0 #define WORD 1 #define LONG 2 #define BFIELD(w,b,l) (((w) >> ((b)-(l)+1)) & (int)((1L<<(l))-1)) #define BTST(w,b) ((w) & (1 << (b))) char opwfmt[] = "%s.%c\t"; #define OPI(s,w) printf(opwfmt, s, w) char size[] = "bwl"; char *cc[] = {"ra", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le" }; char *bitop[] = { "btst", "bchg", "bclr", "bset" }; char *imedop[] = { "ori", "andi", "subi", "addi", "?", "eori", "cmpi" }; char *misc1[] = { "negx", "clr", "neg", "not" }; char *misc2[] = { "reset", "nop", "stop", "rte", "??", "rts", "trapv", "rtr" }; char *shf[] = { "as", "ls", "rox", "ro" }; char *fmts[] = { "d%d", "a%d", "(a%d)", "(a%d)+", "-(a%d)" }; extern curpid; extern char *addr_to_name(); extern long saddr, eaddr; long gaddr, gbuf, ptrace(); int gempty, gisize, gjmp; short gword() { if (gempty) { gempty = 0; gbuf = ptrace(1, curpid, gaddr, 0L); gaddr += 2; return gbuf >> 16; } gempty = 1; gaddr += 2; return gbuf; } long glong() { gempty = 1; gbuf = ptrace(1, curpid, gaddr, 0L); gaddr += 4; return gbuf; } reladdr(sep) char sep; { int d = gword(); symbolic(gaddr + d - 2, sep); } movem(from, predec, rmsk) { int b, f = 0; if (!from) putc(',', stdout); for (b = 16; b--; rmsk >>= 1) { if (rmsk & 1) { if (f) putc('/', stdout); else f = 1; if (predec) printf("%c%d", b>7 ? 'a' : 'd', b % 8); else printf("%c%d", b>7 ? 'd' : 'a', 7 - b % 8); } } if (from) putc(',', stdout); } op1(mode,reg) { int d; char *s; long l; if (mode < 5) { printf(fmts[mode], reg); return; } if (mode == 5) { printf("%d(a%d)", gword(), reg); return; } if (mode == 6) { d = gword(); printf("%d(a%d,%c%d.%c)", BFIELD(d,7,8) | (BTST(d,7) ? 0xFF00 : 0), reg, BTST(d,15) ? 'a' : 'd', BFIELD(d,14,3), BTST(d,11) ? 'l' : 'w'); return; } switch (reg) { case 0: printf("%d", gword()); break; case 1: symbolic(glong(), '\0'); break; case 2: l = gaddr; printf("%d(pc) {", d = gword()); symbolic(l+d, '}'); break; case 3: d = gword(); printf("%d(pc,%c%d.%c)", BFIELD(d,7,8) | (BTST(d,7) ? 0xFF00 : 0), BTST(d,15) ? 'a' : 'd', BFIELD(d,14,3), BTST(d,11) ? 'l' : 'w'); break; case 4: putc('#', stdout); if (gisize == LONG) symbolic(glong(), '\0'); else if (gisize == BYTE) printf("%d", (char)gword()); else printf("%d", gword()); break; case 5: printf("sr"); break; } } op2(f,m1,r1,m2,r2) /* f set means order passed, clear reverses order */ { if (f) op1(m1,r1); else op1(m2,r2); putc(',',stdout); if (f) op1(m2,r2); else op1(m1,r1); } opmode(op, opm, reg, m, r) char *op; { OPI(op, size[gisize=BFIELD(opm,1,2)]); op2(BTST(opm,2),0,reg,m,r); } long dasm(addr,cnt, symflg) long addr; { int tflg = 0; register unsigned int w, m1, m2, r1, r2, op; char ds; gaddr = addr; gempty = 1; while (tflg || cnt--) { tflg = 0; if (symflg) symbolic(gaddr, '\t'); else printf("0x%lx ", gaddr); w = gword(); m1 = BFIELD(w,8,3); m2 = BFIELD(w,5,3); r1 = BFIELD(w,11,3); r2 = BFIELD(w,2,3); op = BFIELD(w,15,4); switch (op) { case 0x0: if (m2 == 1) { OPI("movep", BTST(w,6) ? 'l' : 'w'); op2(BTST(w,7),0,r1,5,r2); break; } if (BTST(w,8)) { OPI(bitop[BFIELD(w,7,2)], m2 ? 'b' : 'l'); op2(1,0,r1,m2,r2); break; } if (r2 == 4) { OPI(bitop[BFIELD(w,7,2)], m2 ? 'b' : 'l'); gisize = WORD; op2(1,7,4,m2,r2); break; } OPI(imedop[r1],size[gisize = m1]); op2(1,7,4,m2,r2); break; case 0x1: gisize = BYTE; goto domove; case 0x2: gisize = LONG; goto domove; case 0x3: gisize = WORD; domove: OPI("move", size[gisize]); op2(1,m2,r2,m1,r1); break; case 0x4: if (BTST(w,8)) { if (BTST(w,6)) { printf("lea\t"); op1(m2,r2); printf(",a%d", r1); break; } printf("chk\t"); op1(m2,r2); printf(",d%d", r1); break; } if (r1 < 4) { if (m1 == 3) { printf("move\t"); gisize = WORD; if (r1 == 0) printf("sr,"); op1(m2,r2); if (r1 == 2) printf(",ccr"); if (r1 == 3) printf(",sr"); break; } OPI(misc1[r1], size[m1]); op1(m2,r2); break; } else if (r1 == 4) { switch(m1) { case 0: printf("nbcd\t"); break; case 1: printf(m2 ? "pea\t" : "swap\t"); break; case 2: case 3: OPI(m2 ? "movem" : "ext", BTST(w,6) ? 'l' : 'w'); if (m2) movem(1,m2==4, gword()); break; } op1(m2,r2); break; } if (r1 == 5) { if (m1 == 3) printf("tas\t"); else OPI("tst", size[m1]); op1(m2,r2); break; } if (r1 == 6) { OPI("movem", BTST(w,6) ? 'l' : 'w'); op = gword(); op1(m2,r2); movem(0,m2==4,op); break; } if (BTST(w,7)) { printf(BTST(w,6) ? "jmp\t" : "jsr\t"); op1(m2,r2); break; } switch (m2) { case 0: case 1: printf("trap\t#%d", BFIELD(w,3,4)); tflg = 1; break; case 2: printf("link\ta%d,#%d", r2, gword()); break; case 3: printf("unlk\ta%d", r2); break; case 4: printf("move.l a%d,usp", r2); break; case 5: printf("move.l usp,a%d", r2); break; case 6: printf(misc2[r2]); break; } break; case 0x5: if (BFIELD(w,7,2) == 3) { op = BFIELD(w,11,4); if (m2 == 1) { printf("db%s\td%d,",cc[op], r2); reladdr('\0'); } else { printf("s%s\t",cc[op]); op1(m2,r2); } } else { printf("%sq\t#%d,",BTST(w,8)?"sub":"add", ((r1 - 1) & 7) + 1); op1(m2,r2); } break; case 0x6: ds = BFIELD(w,7,8); printf("b%s.%c\t", cc[BFIELD(w,11,4)], ds ? 's' : 'w'); if (m1) symbolic(gaddr+ds); else reladdr('\0'); break; case 0x7: printf("moveq\t#%d,d%d",BFIELD(w,7,8),r1); break; case 0x8: if (m1 == 3 || m1 == 7) { printf("div%c\t", BTST(w,8) ? 's' : 'u'); op2(0,0,r1,m2,r2); } else if (m1 == 4 && (m2 == 1 || m2 == 0)) { printf(m2 ? "sbcd\t-(a%d),-(a%d)" : "sbcd\td%d,d%d", r2, r1); } else { opmode("or",m1,r1,m2,r2); } break; case 0x9: case 0xD: if ((m2 == 0 || m2 == 1) && m1 > 3 && m1 < 7) { OPI(op == 9 ? "subx" : "addx", size[BFIELD(w,7,2)]); m2 <<= 2; op2(1,m2,r2,m2,r1); } else if (m1 == 3 || m1 == 7) { gisize = m1 == 3 ? WORD : LONG; OPI(op==9 ? "sub" : "add", size[gisize]); op2(1,m2,r2,1,r1); } else { opmode(op==9 ? "sub" : "add",m1,r1,m2,r2); } break; case 0xB: if (BTST(w,8)) { if (m2 == 1) { OPI("cmpm", size[BFIELD(w,7,2)]); printf("(a%d)+,(a%d)+",r2,r1); } else { opmode("eor",m1,r1,m2,r2); } } else { opmode("cmp",m1,r1,m2,r2); } break; case 0xC: if (m1 == 3 || m1 == 7) { printf("mul%c\t", m1==7 ? 's' : 'u'); op2(0,0,r1,m2,r2); } else if (m1 == 4 && (m2 == 1 || m2 == 0)) { printf(m2 ? "abcd\t-(a%d),-(a%d)" : "abcd\td%d,d%d", r2, r1); } else if (m1 == 5) { op = BTST(w,3) ? 'a' : 'd'; printf("exg\t%c%d,%c%d",op,r1,op,r2); } else if (m1 == 6) { printf("exg\td%d,a%d",r1,r2); } else { opmode("and",m1,r1,m2,r2); } break; case 0xE: if (BFIELD(w,7,2) == 3) { printf("%s%c\t",shf[BFIELD(w,10,2)], BTST(w,8) ? 'l' : 'r'); op1(m2,r2); } else { printf("%s%c\t",shf[BFIELD(w,4,2)], BTST(w,8) ? 'l' : 'r'); if (BTST(w,5)) { op2(1,0,r1,0,r2); } else { printf("#%d,",r1); op1(0,r2); } } break; case 0xA: case 0xF: printf("%x", w); break; } putc('\n',stdout); } return gaddr; }