/* * Disassembler. * Based on old macro code I wrote * years ago. */ #include #define NONE 0 /* halt */ #define RTS 1 /* rts reg */ #define DOUBLE 2 /* mov src,dst */ #define SWBYTE 3 /* sop[b] dst */ #define SINGLE 4 /* sop dst */ #define JSR 5 /* jsr reg,dst */ #define MUL 6 /* mul src,reg */ #define BR 7 /* br addr */ #define SOB 8 /* sob reg,addr */ #define SPL 9 /* spl n */ #define MARK 10 /* mark n */ #define TRAP 11 /* trap n */ #define CODE 12 /* se[cvnz] */ struct tab { int t_mask; int t_op; char *t_str; int t_kind; }; static struct tab tab[] = { 0000000, 0000000, "halt", NONE, 0000000, 0000001, "wait", NONE, 0000000, 0000002, "rti", NONE, 0000000, 0000003, "bpt", NONE, 0000000, 0000004, "iot", NONE, 0000000, 0000005, "reset", NONE, 0000000, 0000006, "rtt", NONE, 0000007, 0000000, "illop", NONE, 0000077, 0000100, "jmp", SINGLE, 0000007, 0000200, "rts", RTS, 0000017, 0000210, "illop", NONE, 0000007, 0000230, "spl", SPL, 0000000, 0000240, "nop", NONE, 0000000, 0000241, "clc", NONE, 0000017, 0000240, "clear", CODE, 0000000, 0000261, "sec", NONE, 0000017, 0000260, "set", CODE, 0000077, 0000300, "swab", SINGLE, 0000377, 0000400, "br", BR, 0000377, 0001000, "bne", BR, 0000377, 0001400, "beq", BR, 0000377, 0002000, "bge", BR, 0000377, 0002400, "blt", BR, 0000377, 0003000, "bgt", BR, 0000377, 0003400, "ble", BR, 0000777, 0004000, "jsr", JSR, 0100077, 0005000, "clr", SWBYTE, 0100077, 0005100, "com", SWBYTE, 0100077, 0005200, "inc", SWBYTE, 0100077, 0005300, "dec", SWBYTE, 0100077, 0005400, "neg", SWBYTE, 0100077, 0005500, "adc", SWBYTE, 0100077, 0005600, "sbc", SWBYTE, 0100077, 0005700, "tst", SWBYTE, 0100077, 0006000, "ror", SWBYTE, 0100077, 0006100, "rol", SWBYTE, 0100077, 0006200, "asr", SWBYTE, 0100077, 0006300, "asl", SWBYTE, 0000077, 0006400, "mark", MARK, 0000077, 0006500, "mfpi", SINGLE, 0000077, 0006600, "mtpi", SINGLE, 0000077, 0006700, "sxt", SINGLE, 0000777, 0007000, "illop", NONE, 0107777, 0010000, "mov", DOUBLE, 0107777, 0020000, "cmp", DOUBLE, 0107777, 0030000, "bit", DOUBLE, 0107777, 0040000, "bic", DOUBLE, 0107777, 0050000, "bis", DOUBLE, 0007777, 0060000, "add", DOUBLE, 0007777, 0160000, "su", DOUBLE, 0000777, 0070000, "mul", MUL, 0000777, 0071000, "div", MUL, 0000777, 0072000, "ash", MUL, 0000777, 0073000, "ashc", MUL, 0000777, 0074000, "xor", JSR, 0000007, 0075000, "fadd", RTS, 0000007, 0075010, "fsub", RTS, 0000007, 0075020, "fmul", RTS, 0000007, 0075030, "fdiv", RTS, 0000777, 0077000, "sob", SOB, 0003777, 0074000, "illop", NONE, 0000377, 0100000, "bpl", BR, 0000377, 0100400, "bmi", BR, 0000377, 0101000, "bhi", BR, 0000377, 0101400, "blos", BR, 0000377, 0102000, "bvc", BR, 0000377, 0102400, "bvs", BR, 0000377, 0103000, "bhis", BR, 0000377, 0103400, "blo", BR, 0000377, 0104000, "emt", TRAP, 0000377, 0104400, "trap", TRAP, 0000077, 0106400, "illop", NONE, 0000077, 0106500, "mfpd", SINGLE, 0000077, 0106600, "mtpd", SINGLE, 0001777, 0106000, "illop", NONE, 0007777, 0170000, "45fpp", NONE, 0177777, 0000000, "illop", NONE }; #define NTAB (sizeof(tab) / sizeof(tab[0])) int * pinst(pc) register *pc; { register struct tab *tp; register op; int i, m; int *paddr(); printf("%06o\t", pc); op = *pc++; tp = &tab[0]; while (tp < &tab[NTAB]) { if ((op&~tp->t_mask) == tp->t_op) break; ++tp; } if (tp == &tab[NTAB]) { printf("[No match]\n"); return (pc); } printf("%s", tp->t_str); switch (tp->t_kind) { case SPL: printf("\t%d", op&07); break; case RTS: putchar('\t'); preg(op); break; case SWBYTE: if (op < 0) putchar('b'); case SINGLE: putchar('\t'); pc = paddr(pc, op); break; case DOUBLE: if (op < 0) putchar('b'); /* sub and bytes */ putchar('\t'); pc = paddr(pc, op>>6); putchar(','); pc = paddr(pc, op); break; case JSR: putchar('\t'); preg(op>>6); putchar(','); pc = paddr(pc, op); break; case MUL: putchar('\t'); pc = paddr(pc, op); putchar(','); preg(op>>6); break; case BR: putchar('\t'); op &= 0377; if ((op & 0200) != 0) op |= ~0377; printf("%o", (int)pc + (op<<1)); break; case SOB: putchar('\t'); preg(op>>6); putchar(','); printf("%o", (int)pc + ((op|~077)<<1)); break; case MARK: case TRAP: putchar('\t'); if (tp->t_kind == MARK) op &= 077; else op &= 0377; printf("%o", op); break; case CODE: putchar('\t'); m = 01; for (i=0; i<4; ++i) { if ((op & m) != 0) putchar("czvn"[i]); m <<= 1; } } putchar('\n'); return (pc); } int * paddr(pc, m) register *pc; { register r, x; r = m&07; switch (m&070) { case 0: preg(r); break; case 010: putchar('('); preg(r); putchar(')'); break; case 030: putchar('*'); case 020: if (r == 7) { putchar('$'); printf("%o", *pc++); break; } putchar('('); preg(r); putchar(')'); putchar('+'); break; case 050: putchar('*'); case 040: putchar('-'); putchar('('); preg(r); putchar(')'); break; case 070: putchar('*'); case 060: x = *pc++; if (r == 7) { printf("%o", (int)pc + x); break; } printf("%o(", x); preg(r); putchar(')'); } return (pc); } preg(r) register r; { r &= 07; if (r == 7) printf("pc"); else if (r == 6) printf("sp"); else printf("r%d", r); }