/* This file is in the public domain. */ #include #include "machine.h" #include "fnprintf.h" typedef struct instr INSTR; struct instr { const char *name; unsigned char variant; #define V_6800 1 #define V_6303 2 unsigned char kind; #define IK_IMM1 1 /* immediate, one byte of data */ #define IK_IMM2 2 /* immediate, two bytes of data */ #define IK_PGZ 3 /* page zero, one following byte of address */ #define IK_EXT 4 /* "extended", two following bytes of absolute address */ #define IK_INX1 5 /* indexed, one byte of following offset */ #define IK_INX2 6 /* indexed, two bytes of following offset */ #define IK_IMP 7 /* implied, no following bytes */ #define IK_BR 8 /* branch, one byte of offset */ int nbytes; } ; #define A V_6800 #define B (V_6800|V_6303) /* Until we know which are 6800 and which are 6303 extensions, all are marked as 6303. */ static INSTR instrs[256] = { { /*00*/ 0, 0, IK_IMP }, { /*01*/ "nop", B, IK_IMP }, { /*02*/ 0, 0, IK_IMP }, { /*03*/ 0, 0, IK_IMP }, { /*04*/ "lsrd", B, IK_IMP }, { /*05*/ "asld", B, IK_IMP }, { /*06*/ "tap", B, IK_IMP }, { /*07*/ "tpa", B, IK_IMP }, { /*08*/ "inx", B, IK_IMP }, { /*09*/ "dex", B, IK_IMP }, { /*0a*/ "clv", B, IK_IMP }, { /*0b*/ "sev", B, IK_IMP }, { /*0c*/ "clc", B, IK_IMP }, { /*0d*/ "sec", B, IK_IMP }, { /*0e*/ "cli", B, IK_IMP }, { /*0f*/ "sei", B, IK_IMP }, { /*10*/ "sba", B, IK_IMP }, { /*11*/ "cba", B, IK_IMP }, { /*12*/ 0, 0, IK_IMP }, { /*13*/ 0, 0, IK_IMP }, { /*14*/ 0, 0, IK_IMP }, { /*15*/ 0, 0, IK_IMP }, { /*16*/ "tab", B, IK_IMP }, { /*17*/ "tba", B, IK_IMP }, { /*18*/ "xdgx", B, IK_IMP }, { /*19*/ "daa", B, IK_IMP }, { /*1a*/ "slp", B, IK_IMP }, { /*1b*/ "aba", B, IK_IMP }, { /*1c*/ 0, 0, IK_IMP }, { /*1d*/ 0, 0, IK_IMP }, { /*1e*/ 0, 0, IK_IMP }, { /*1f*/ 0, 0, IK_IMP }, { /*20*/ "bra", B, IK_BR }, { /*21*/ "brn", B, IK_BR }, { /*22*/ "bhi", B, IK_BR }, { /*23*/ "bls", B, IK_BR }, { /*24*/ "bcc", B, IK_BR }, { /*25*/ "bcs", B, IK_BR }, { /*26*/ "bne", B, IK_BR }, { /*27*/ "beq", B, IK_BR }, { /*28*/ "bvc", B, IK_BR }, { /*29*/ "bvs", B, IK_BR }, { /*2a*/ "bpl", B, IK_BR }, { /*2b*/ "bmi", B, IK_BR }, { /*2c*/ "bge", B, IK_BR }, { /*2d*/ "blt", B, IK_BR }, { /*2e*/ "bgt", B, IK_BR }, { /*2f*/ "ble", B, IK_BR }, { /*30*/ "tsx", B, IK_IMP }, { /*31*/ "ins", B, IK_IMP }, { /*32*/ "pula", B, IK_IMP }, { /*33*/ "pulb", B, IK_IMP }, { /*34*/ "des", B, IK_IMP }, { /*35*/ "txs", B, IK_IMP }, { /*36*/ "psha", B, IK_IMP }, { /*37*/ "pshb", B, IK_IMP }, { /*38*/ "pulx", B, IK_IMP }, { /*39*/ "rts", B, IK_IMP }, { /*3a*/ "abx", B, IK_IMP }, { /*3b*/ "rti", B, IK_IMP }, { /*3c*/ "pshx", B, IK_IMP }, { /*3d*/ "mul", B, IK_IMP }, { /*3e*/ "wai", B, IK_IMP }, { /*3f*/ "swi", B, IK_IMP }, { /*40*/ "nega", B, IK_IMP }, { /*41*/ 0, 0, IK_IMP }, { /*42*/ 0, 0, IK_IMP }, { /*43*/ "coma", B, IK_IMP }, { /*44*/ "lsra", B, IK_IMP }, { /*45*/ 0, 0, IK_IMP }, { /*46*/ "rora", B, IK_IMP }, { /*47*/ "asra", B, IK_IMP }, { /*48*/ "asla", B, IK_IMP }, { /*49*/ "rola", B, IK_IMP }, { /*4a*/ "deca", B, IK_IMP }, { /*4b*/ 0, 0, IK_IMP }, { /*4c*/ "inca", B, IK_IMP }, { /*4d*/ "tsta", B, IK_IMP }, { /*4e*/ 0, 0, IK_IMP }, { /*4f*/ "clra", B, IK_IMP }, { /*50*/ "negb", B, IK_IMP }, { /*51*/ 0, 0, IK_IMP }, { /*52*/ 0, 0, IK_IMP }, { /*53*/ "comb", B, IK_IMP }, { /*54*/ "lsrb", B, IK_IMP }, { /*55*/ 0, 0, IK_IMP }, { /*56*/ "rorb", B, IK_IMP }, { /*57*/ "asrb", B, IK_IMP }, { /*58*/ "aslb", B, IK_IMP }, { /*59*/ "rolb", B, IK_IMP }, { /*5a*/ "decb", B, IK_IMP }, { /*5b*/ 0, 0, IK_IMP }, { /*5c*/ "incb", B, IK_IMP }, { /*5d*/ "tstb", B, IK_IMP }, { /*5e*/ 0, 0, IK_IMP }, { /*5f*/ "clrb", B, IK_IMP }, { /*60*/ "neg", B, IK_INX1 }, { /*61*/ "aim", B, IK_INX2 }, { /*62*/ "oim", B, IK_INX2 }, { /*63*/ "com", B, IK_INX1 }, { /*64*/ "lsr", B, IK_INX1 }, { /*65*/ "eim", B, IK_INX2 }, { /*66*/ "ror", B, IK_INX1 }, { /*67*/ "asr", B, IK_INX1 }, { /*68*/ "asl", B, IK_INX1 }, { /*69*/ "rol", B, IK_INX1 }, { /*6a*/ "dec", B, IK_INX1 }, { /*6b*/ "tim", B, IK_INX2 }, { /*6c*/ "inc", B, IK_INX1 }, { /*6d*/ "tst", B, IK_INX1 }, { /*6e*/ "jmp", B, IK_INX1 }, { /*6f*/ "clr", B, IK_INX1 }, { /*70*/ "neg", B, IK_EXT }, { /*71*/ "aim", B, IK_PGZ }, { /*72*/ "oim", B, IK_PGZ }, { /*73*/ "com", B, IK_EXT }, { /*74*/ "lsr", B, IK_EXT }, { /*75*/ "eim", B, IK_PGZ }, { /*76*/ "ror", B, IK_EXT }, { /*77*/ "asr", B, IK_EXT }, { /*78*/ "asl", B, IK_EXT }, { /*79*/ "rol", B, IK_EXT }, { /*7a*/ "dec", B, IK_EXT }, { /*7b*/ "tim", B, IK_PGZ }, { /*7c*/ "inc", B, IK_EXT }, { /*7d*/ "tst", B, IK_EXT }, { /*7e*/ "jmp", B, IK_EXT }, { /*7f*/ "clr", B, IK_EXT }, { /*80*/ "suba", B, IK_IMM1 }, { /*81*/ "cmpa", B, IK_IMM1 }, { /*82*/ "sbca", B, IK_IMM1 }, { /*83*/ "subd", B, IK_IMM2 }, { /*84*/ "anda", B, IK_IMM1 }, { /*85*/ "bita", B, IK_IMM1 }, { /*86*/ "ldaa", B, IK_IMM1 }, { /*87*/ 0, 0, IK_IMP }, { /*88*/ "eora", B, IK_IMM1 }, { /*89*/ "adca", B, IK_IMM1 }, { /*8a*/ "oraa", B, IK_IMM1 }, { /*8b*/ "adda", B, IK_IMM1 }, { /*8c*/ "cpx", B, IK_IMM2 }, { /*8d*/ "bsr", B, IK_BR }, { /*8e*/ "lds", B, IK_IMM2 }, { /*8f*/ 0, 0, IK_IMP }, { /*90*/ "suba", B, IK_PGZ }, { /*91*/ "cmpa", B, IK_PGZ }, { /*92*/ "sbca", B, IK_PGZ }, { /*93*/ "subd", B, IK_PGZ }, { /*94*/ "anda", B, IK_PGZ }, { /*95*/ "bita", B, IK_PGZ }, { /*96*/ "ldaa", B, IK_PGZ }, { /*97*/ "staa", B, IK_PGZ }, { /*98*/ "eora", B, IK_PGZ }, { /*99*/ "adca", B, IK_PGZ }, { /*9a*/ "oraa", B, IK_PGZ }, { /*9b*/ "adda", B, IK_PGZ }, { /*9c*/ "cpx", B, IK_PGZ }, { /*9d*/ "jsr", B, IK_PGZ }, { /*9e*/ "lds", B, IK_PGZ }, { /*9f*/ "sts", B, IK_PGZ }, { /*a0*/ "suba", B, IK_INX1 }, { /*a1*/ "cmpa", B, IK_INX1 }, { /*a2*/ "sbca", B, IK_INX1 }, { /*a3*/ "subd", B, IK_INX1 }, { /*a4*/ "anda", B, IK_INX1 }, { /*a5*/ "bita", B, IK_INX1 }, { /*a6*/ "ldaa", B, IK_INX1 }, { /*a7*/ "staa", B, IK_INX1 }, { /*a8*/ "eora", B, IK_INX1 }, { /*a9*/ "adca", B, IK_INX1 }, { /*aa*/ "oraa", B, IK_INX1 }, { /*ab*/ "adda", B, IK_INX1 }, { /*ac*/ "cpx", B, IK_INX1 }, { /*ad*/ "jsr", B, IK_INX1 }, { /*ae*/ "lds", B, IK_INX1 }, { /*af*/ "sts", B, IK_INX1 }, { /*b0*/ "suba", B, IK_EXT }, { /*b1*/ "cmpa", B, IK_EXT }, { /*b2*/ "sbca", B, IK_EXT }, { /*b3*/ "subd", B, IK_EXT }, { /*b4*/ "anda", B, IK_EXT }, { /*b5*/ "bita", B, IK_EXT }, { /*b6*/ "ldaa", B, IK_EXT }, { /*b7*/ "staa", B, IK_EXT }, { /*b8*/ "eora", B, IK_EXT }, { /*b9*/ "adca", B, IK_EXT }, { /*ba*/ "oraa", B, IK_EXT }, { /*bb*/ "adda", B, IK_EXT }, { /*bc*/ "cpx", B, IK_EXT }, { /*bd*/ "jsr", B, IK_EXT }, { /*be*/ "lds", B, IK_EXT }, { /*bf*/ "sts", B, IK_EXT }, { /*c0*/ "subb", B, IK_IMM1 }, { /*c1*/ "cmpb", B, IK_IMM1 }, { /*c2*/ "sbcb", B, IK_IMM1 }, { /*c3*/ "addd", B, IK_IMM2 }, { /*c4*/ "andb", B, IK_IMM1 }, { /*c5*/ "bitb", B, IK_IMM1 }, { /*c6*/ "ldab", B, IK_IMM1 }, { /*c7*/ 0, 0, IK_IMP }, { /*c8*/ "eorb", B, IK_IMM1 }, { /*c9*/ "adcb", B, IK_IMM1 }, { /*ca*/ "orab", B, IK_IMM1 }, { /*cb*/ "addb", B, IK_IMM1 }, { /*cc*/ "lddb", B, IK_IMM2 }, { /*cd*/ 0, 0, IK_IMP }, { /*ce*/ "ldx", B, IK_IMM2 }, { /*cf*/ 0, 0, IK_IMP }, { /*d0*/ "subb", B, IK_PGZ }, { /*d1*/ "cmpb", B, IK_PGZ }, { /*d2*/ "sbcb", B, IK_PGZ }, { /*d3*/ "addd", B, IK_PGZ }, { /*d4*/ "andb", B, IK_PGZ }, { /*d5*/ "bitb", B, IK_PGZ }, { /*d6*/ "ldab", B, IK_PGZ }, { /*d7*/ "stab", B, IK_PGZ }, { /*d8*/ "eorb", B, IK_PGZ }, { /*d9*/ "adcb", B, IK_PGZ }, { /*da*/ "orab", B, IK_PGZ }, { /*db*/ "addb", B, IK_PGZ }, { /*dc*/ "lddb", B, IK_PGZ }, { /*dd*/ "std", B, IK_PGZ }, { /*de*/ "ldx", B, IK_PGZ }, { /*df*/ "stx", B, IK_PGZ }, { /*e0*/ "subb", B, IK_INX1 }, { /*e1*/ "cmpb", B, IK_INX1 }, { /*e2*/ "sbcb", B, IK_INX1 }, { /*e3*/ "addd", B, IK_INX1 }, { /*e4*/ "andb", B, IK_INX1 }, { /*e5*/ "bitb", B, IK_INX1 }, { /*e6*/ "ldab", B, IK_INX1 }, { /*e7*/ "stab", B, IK_INX1 }, { /*e8*/ "eorb", B, IK_INX1 }, { /*e9*/ "adcb", B, IK_INX1 }, { /*ea*/ "orab", B, IK_INX1 }, { /*eb*/ "addb", B, IK_INX1 }, { /*ec*/ "lddb", B, IK_INX1 }, { /*ed*/ "std", B, IK_INX1 }, { /*ee*/ "ldx", B, IK_INX1 }, { /*ef*/ "stx", B, IK_INX1 }, { /*f0*/ "subb", B, IK_EXT }, { /*f1*/ "cmpb", B, IK_EXT }, { /*f2*/ "sbcb", B, IK_EXT }, { /*f3*/ "addd", B, IK_EXT }, { /*f4*/ "andb", B, IK_EXT }, { /*f5*/ "bitb", B, IK_EXT }, { /*f6*/ "ldab", B, IK_EXT }, { /*f7*/ "stab", B, IK_EXT }, { /*f8*/ "eorb", B, IK_EXT }, { /*f9*/ "adcb", B, IK_EXT }, { /*fa*/ "orab", B, IK_EXT }, { /*fb*/ "addb", B, IK_EXT }, { /*fc*/ "lddb", B, IK_EXT }, { /*fd*/ "std", B, IK_EXT }, { /*fe*/ "ldx", B, IK_EXT }, { /*ff*/ "stx", B, IK_EXT } }; #undef A #undef B static int max_nbytes; static void print_with_symbol(void (*fn)(char), ADDR a, const char *fmt) { SYMBOL *s; s = symbol_for_addr(a); if (s) { fnprintf(fn,"%s",s->name); } else { fnprintf(fn,fmt,(unsigned long int)a); } maybe_print_stringptr(fn,a); } static int do_dis_inst(ADDR addr, void (*fn)(char), CFLAG flg, int mkind) { unsigned char opc; int i; addr -= corebase; if (addr >= coresize) return(-1); opc = corefetchu(addr,1); if ( !(instrs[opc].variant & mkind) || (addr+instrs[opc].nbytes > coresize) ) { flags[addr] = CF_BYTE; return(0); } for (i=0;i0;i--) flags[addr+i] = CF_PREV; return(instrs[opc].nbytes); } static void common_init(int mkind) { int nb; int i; max_nbytes = 0; for (i=0;i<256;i++) { if (! (instrs[i].variant & mkind)) continue; switch (instrs[i].kind) { default: abort(); break; case IK_IMM1: nb = 2; break; case IK_IMM2: nb = 3; break; case IK_PGZ: nb = 2; break; case IK_EXT: nb = 3; break; case IK_INX1: nb = 2; break; case IK_INX2: nb = 3; break; case IK_IMP: nb = 1; break; case IK_BR: nb = 2; break; } instrs[i].nbytes = nb; if (nb > max_nbytes) max_nbytes = nb; } } static void h6303_init(void) { common_init(V_6303); } static int h6303_dis(ADDR addr, void (*fn)(char)) { int rv; if (ISINST(flags[addr-corebase])) { rv = do_dis_inst(addr,fn,flags[addr-corebase],V_6303); } else { fnprintf(fn,"",(unsigned long int)flags[addr-corebase]); rv = 1; } return(rv); } static unsigned long int m6800_fetch(const void *base, int size) #define bp(n) ((unsigned long int)(((const unsigned char *)base)[(n)])) { switch (size) { case 1: return(bp(0)); break; case 2: return((bp(0)<<8)|bp(1)); break; case 4: return((bp(0)<<24)|(bp(1)<<16)|(bp(2)<<8)|bp(3)); break; } abort(); } #undef bp static const char *h6303_names[] = { "6303", 0 }; MACHINE machine_6303 = { &h6303_names[0], 2, &h6303_init, 0, &h6303_dis, &m6800_fetch, 0 };