/* ** Starscream 680x0 emulation library ** Copyright 1997, 1998, 1999 Neill Corlett ** ** Refer to STARDOC.TXT for terms of use, API reference, and directions on ** how to compile. */ #include #include #include #include #include #include #include "starcpu.h" #include "cpudebug.h" void (*cpudebug_get)(char*, int); void (*cpudebug_put)(const char*); static void cpudebug_gets(char *s, int n) { if(cpudebug_get) cpudebug_get(s, n); else fgets(s, n, stdin); } static void cpudebug_putc(char c) { static char buffer[100]; static unsigned l = 0; buffer[l++] = c; if((c == '\n') || (l == (sizeof(buffer) - 1))) { buffer[l] = 0; if(cpudebug_put) cpudebug_put(buffer); else fputs(buffer, stdout); l = 0; } } static void cpudebug_printf(const char *fmt, ...) { static char buffer[400]; char *s = buffer; va_list ap; va_start(ap, fmt); vsprintf(s, fmt, ap); va_end(ap); while(*s) cpudebug_putc(*s++); } #define byte uint8_t #define word uit16_t #define dword uint32_t #define int08 int8_t #define int16 int16_t #define int32 int32_t int cpudebug_disabled(void){return 0;} #define ea eacalc[inst&0x3F]() /****************************** ** SNAGS / EA CONSIDERATIONS ** ******************************* - ADDX is encoded the same way as ADD->ea - SUBX is encoded the same way as SUB->ea - ABCD is encoded the same way as AND->ea - EXG is encoded the same way as AND->ea - SBCD is encoded the same way as OR->ea - EOR is encoded the same way as CMPM - ASR is encoded the same way as LSR (so are LSL and ASL, but they do the same thing) - Bcc does NOT support 32-bit offsets on the 68000. (this is a reminder, don't bother implementing 32-bit offsets!) - Look on p. 3-19 for how to calculate branch conditions (GE, LT, GT, etc.) - Bit operations are 32-bit for registers, 8-bit for memory locations. - MOVEM->memory is encoded the same way as EXT If the EA is just a register, then it's EXT, otherwise it's MOVEM. - MOVEP done the same way as the bit operations - Scc done the same way as DBcc. Assume it's Scc, unless the EA is a direct An mode (then it's a DBcc). - SWAP done the same way as PEA - TAS done the same way as ILLEGAL - LINK, NOP, RTR, RTS, TRAP, TRAPV, UNLK are encoded the same way. ******************************/ #define hex08 "%02X" #define hex16 "%04X" #define hex32 "%08X" #define hexlong "%06X" #define isregister ((inst&0x0030)==0x0000) #define isaddressr ((inst&0x0038)==0x0008) static char eabuffer[20],sdebug[80]; static dword debugpc,hexaddr; static int isize; static word inst; static word fetch(void){ debugpc+=2; isize+=2; return(s68000fetch(debugpc-2)&0xFFFF); } static dword fetchl(void){ dword t; t=(s68000fetch(debugpc)&0xFFFF); t<<=16; t|=(s68000fetch(debugpc+2)&0xFFFF); debugpc+=4; isize+=4; return t; } static int08 opsize[1024]={ 1,2,4,0,0,0,0,0,1,2,4,0,0,0,0,0,1,2,4,0,0,0,0,0,1,2,4,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,2,4,0,0,0,0,0,1,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 1,2,4,2,0,0,2,4,1,2,4,1,0,0,2,4,1,2,4,1,0,0,2,4,1,2,4,2,0,0,2,4, 1,4,2,4,0,0,2,4,1,2,4,1,0,0,2,4,0,0,2,4,0,0,2,4,0,2,0,0,0,0,2,4, 1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0, 1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0, 4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0,4,4,4,4,0,0,0,0, 1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2, 1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2, 1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4, 1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4, 1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4, 1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2, 1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2, 1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4, 1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4,1,2,4,2,1,2,4,4, 1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2,1,2,4,2, 1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0,1,2,4,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /******************** EA GENERATION ********************/ /* These are the functions to generate effective addresses. Here is the syntax: eacalc[mode](); mode is the EA mode << 3 + register number The function sets addr so you can use m68read and m68write. These routines screw around with the PC, and might call fetch() a couple times to get extension words. Place the eacalc() calls strategically to get the extension words in the right order. */ /* These are the jump tables for EA calculation. drd = data reg direct Dn ard = address reg direct An ari = address reg indirect (An) ari_inc = address reg indirect, postincrement (An)+ ari_dec = address reg indirect, predecrement -(An) ari_dis = address reg indirect, displacement (d16,An) ari_ind = address reg indirect, index (d8,An,Xn) pci_dis = prog. counter indirect, displacement (d16,PC) pci_ind = prog. counter indirect, index (d8,PC,Xn) */ #define eacalc_drd(n,r) static void n(void){sprintf(eabuffer,"d%d",r);} #define eacalc_ard(n,r) static void n(void){sprintf(eabuffer,"a%d",r);} #define eacalc_ari(n,r) static void n(void){sprintf(eabuffer,"(a%d)",r);} #define eacalc_ari_inc(n,r) static void n(void){sprintf(eabuffer,"(a%d)+",r);} #define eacalc_ari_dec(n,r) static void n(void){sprintf(eabuffer,"-(a%d)",r);} #define eacalc_ari_dis(n,r) static void n(void){\ int16 briefext=fetch();\ sprintf(eabuffer,"%c$" hex16 "(a%d)",(briefext<0)?'-':'+',(briefext<0)?-briefext:briefext,r);\ } #define eacalc_ari_ind(n,r) static void n(void){\ int16 briefext=fetch();\ if(briefext<0)sprintf(eabuffer,"-$" hex08 "(a%d,%c%d.%c)",\ (int08)-briefext,r,\ briefext&0x8000?'a':'d',(briefext>>12)&7,\ briefext&0x800?'l':'w');\ else sprintf(eabuffer,"+$" hex08 "(a%d,%c%d.%c)",\ (int08)briefext,r,\ briefext&0x8000?'a':'d',(briefext>>12)&7,\ briefext&0x800?'l':'w');\ } eacalc_drd(ea_0_0,0) eacalc_drd(ea_0_1,1) eacalc_drd(ea_0_2,2) eacalc_drd(ea_0_3,3) eacalc_drd(ea_0_4,4) eacalc_drd(ea_0_5,5) eacalc_drd(ea_0_6,6) eacalc_drd(ea_0_7,7) eacalc_ard(ea_1_0,0) eacalc_ard(ea_1_1,1) eacalc_ard(ea_1_2,2) eacalc_ard(ea_1_3,3) eacalc_ard(ea_1_4,4) eacalc_ard(ea_1_5,5) eacalc_ard(ea_1_6,6) eacalc_ard(ea_1_7,7) eacalc_ari(ea_2_0,0) eacalc_ari(ea_2_1,1) eacalc_ari(ea_2_2,2) eacalc_ari(ea_2_3,3) eacalc_ari(ea_2_4,4) eacalc_ari(ea_2_5,5) eacalc_ari(ea_2_6,6) eacalc_ari(ea_2_7,7) eacalc_ari_inc(ea_3_0,0) eacalc_ari_inc(ea_3_1,1) eacalc_ari_inc(ea_3_2,2) eacalc_ari_inc(ea_3_3,3) eacalc_ari_inc(ea_3_4,4) eacalc_ari_inc(ea_3_5,5) eacalc_ari_inc(ea_3_6,6) eacalc_ari_inc(ea_3_7,7) eacalc_ari_dec(ea_4_0,0) eacalc_ari_dec(ea_4_1,1) eacalc_ari_dec(ea_4_2,2) eacalc_ari_dec(ea_4_3,3) eacalc_ari_dec(ea_4_4,4) eacalc_ari_dec(ea_4_5,5) eacalc_ari_dec(ea_4_6,6) eacalc_ari_dec(ea_4_7,7) eacalc_ari_dis(ea_5_0,0) eacalc_ari_dis(ea_5_1,1) eacalc_ari_dis(ea_5_2,2) eacalc_ari_dis(ea_5_3,3) eacalc_ari_dis(ea_5_4,4) eacalc_ari_dis(ea_5_5,5) eacalc_ari_dis(ea_5_6,6) eacalc_ari_dis(ea_5_7,7) eacalc_ari_ind(ea_6_0,0) eacalc_ari_ind(ea_6_1,1) eacalc_ari_ind(ea_6_2,2) eacalc_ari_ind(ea_6_3,3) eacalc_ari_ind(ea_6_4,4) eacalc_ari_ind(ea_6_5,5) eacalc_ari_ind(ea_6_6,6) eacalc_ari_ind(ea_6_7,7) /* These are the "special" addressing modes: abshort absolute short address abslong absolute long address immdata immediate data */ static void eacalcspecial_abshort(void){ word briefext; briefext=fetch(); sprintf(eabuffer,"($" hex16 ")",briefext); } static void eacalcspecial_abslong(void){ dword briefext; briefext=fetch(); briefext<<=16; briefext|=fetch(); sprintf(eabuffer,"($"hexlong")",briefext); } static void eacalcspecial_immdata(void){ dword briefext; switch(opsize[inst>>6]){ case 1: briefext=fetch()&0xFF; sprintf(eabuffer,"#$" hex08,briefext); break; case 2: briefext=fetch(); sprintf(eabuffer,"#$" hex16,briefext); break; default: briefext=fetch(); briefext<<=16; briefext|=fetch(); sprintf(eabuffer,"#$" hex32,briefext); break; } } static void eacalcspecial_pci_dis(void){ dword dpc = debugpc; word briefext = fetch(); sprintf(eabuffer,"$" hexlong "(pc)",((int16)(briefext))+dpc); } static void eacalcspecial_pci_ind(void){ dword dpc = debugpc; word briefext = fetch(); sprintf(eabuffer,"$" hexlong "(pc,%c%d)", ((int08)(briefext))+dpc, briefext&0x8000?'a':'d',(briefext>>12)&7); } static void eacalcspecial_unknown(void){ sprintf(eabuffer,"*** UNKNOWN EA MODE ***"); } static void (*(eacalc[64]))(void)={ ea_0_0,ea_0_1,ea_0_2,ea_0_3,ea_0_4,ea_0_5,ea_0_6,ea_0_7, ea_1_0,ea_1_1,ea_1_2,ea_1_3,ea_1_4,ea_1_5,ea_1_6,ea_1_7, ea_2_0,ea_2_1,ea_2_2,ea_2_3,ea_2_4,ea_2_5,ea_2_6,ea_2_7, ea_3_0,ea_3_1,ea_3_2,ea_3_3,ea_3_4,ea_3_5,ea_3_6,ea_3_7, ea_4_0,ea_4_1,ea_4_2,ea_4_3,ea_4_4,ea_4_5,ea_4_6,ea_4_7, ea_5_0,ea_5_1,ea_5_2,ea_5_3,ea_5_4,ea_5_5,ea_5_6,ea_5_7, ea_6_0,ea_6_1,ea_6_2,ea_6_3,ea_6_4,ea_6_5,ea_6_6,ea_6_7, eacalcspecial_abshort,eacalcspecial_abslong,eacalcspecial_pci_dis,eacalcspecial_pci_ind, eacalcspecial_immdata,eacalcspecial_unknown,eacalcspecial_unknown,eacalcspecial_unknown}; static void m68unsupported(void){ sprintf(sdebug,"*** NOT RECOGNIZED ***"); } static void m68_unrecog_x(void){ sprintf(sdebug,"unrecognized"); } /******************** BIT TEST-AND-____ ********************/ static void m68_bitopdn_x(void){ int16 d16; if((inst&0x38)==0x08){ d16=fetch(); sprintf(eabuffer,"%c$" hex16 "(a%d)",(d16<0)?'-':'+',(d16<0)?-d16:d16,inst&7); if(!(inst&0x80)){ sprintf(sdebug,"movep%s %s,d%d", ((inst&0x40)==0x40)?".l":" ", eabuffer,inst>>9 ); }else{ sprintf(sdebug,"movep%s d%d,%s", ((inst&0x40)==0x40)?".l":" ", inst>>9,eabuffer ); } }else{ ea; switch((inst>>6)&3){ case 0:sprintf(sdebug,"btst d%d,%s",inst>>9,eabuffer);break; case 1:sprintf(sdebug,"bchg d%d,%s",inst>>9,eabuffer);break; case 2:sprintf(sdebug,"bclr d%d,%s",inst>>9,eabuffer);break; case 3:sprintf(sdebug,"bset d%d,%s",inst>>9,eabuffer);break; default:break; } } } #define bittest_st(name,dump) static void name(void){\ byte shiftby=(fetch()&0xFF);\ ea;sprintf(sdebug,"%s #$"hex08",%s",dump,shiftby,eabuffer);\ } bittest_st(m68_btst_st_x,"btst") bittest_st(m68_bclr_st_x,"bclr") bittest_st(m68_bset_st_x,"bset") bittest_st(m68_bchg_st_x,"bchg") /******************** Bcc ********************/ #define conditional_branch(name,dump) static void name(void){\ int16 disp;\ int32 currentpc=debugpc;\ disp=(int08)(inst&0xFF);\ if(!disp)disp=fetch();\ sprintf(sdebug,"%s ($"hexlong")",dump,currentpc+disp);\ } conditional_branch(m68_bra_____x,"bra") conditional_branch(m68_bhi_____x,"bhi") conditional_branch(m68_bls_____x,"bls") conditional_branch(m68_bcc_____x,"bcc") conditional_branch(m68_bcs_____x,"bcs") conditional_branch(m68_bne_____x,"bne") conditional_branch(m68_beq_____x,"beq") conditional_branch(m68_bvc_____x,"bvc") conditional_branch(m68_bvs_____x,"bvs") conditional_branch(m68_bpl_____x,"bpl") conditional_branch(m68_bmi_____x,"bmi") conditional_branch(m68_bge_____x,"bge") conditional_branch(m68_blt_____x,"blt") conditional_branch(m68_bgt_____x,"bgt") conditional_branch(m68_ble_____x,"ble") /******************** Scc, DBcc ********************/ #define scc_dbcc(name,dump1,dump2)\ static void name(void){\ ea;if(isaddressr){\ int16 disp;\ disp=fetch();\ sprintf(sdebug,"%s d%d,($"hexlong")",dump2,inst&7,debugpc+disp-2);\ }else sprintf(sdebug,"%s %s",dump1,eabuffer);\ } scc_dbcc(m68_st______x,"st ","dbt ") scc_dbcc(m68_sf______x,"sf ","dbra") scc_dbcc(m68_shi_____x,"shi","dbhi") scc_dbcc(m68_sls_____x,"sls","dbls") scc_dbcc(m68_scc_____x,"scc","dbcc") scc_dbcc(m68_scs_____x,"scs","dbcs") scc_dbcc(m68_sne_____x,"sne","dbne") scc_dbcc(m68_seq_____x,"seq","dbeq") scc_dbcc(m68_svc_____x,"svc","dbvc") scc_dbcc(m68_svs_____x,"svs","dbvs") scc_dbcc(m68_spl_____x,"spl","dbpl") scc_dbcc(m68_smi_____x,"smi","dbmi") scc_dbcc(m68_sge_____x,"sge","dbge") scc_dbcc(m68_slt_____x,"slt","dblt") scc_dbcc(m68_sgt_____x,"sgt","dbgt") scc_dbcc(m68_sle_____x,"sle","dble") /******************** JMP ********************/ static void m68_jmp_____x(void){ea;sprintf(sdebug,"jmp %s",eabuffer);} /******************** JSR/BSR ********************/ static void m68_jsr_____x(void){ea;sprintf(sdebug,"jsr %s",eabuffer);} static void m68_bsr_____x(void){ int16 disp; int32 currentpc=debugpc; disp=(int08)(inst&0xFF); if(!disp)disp=fetch(); sprintf(sdebug,"%s ($"hexlong")","bsr",disp+currentpc); } /******************** TAS ********************/ /* Test-and-set / illegal */ static void m68_tas_____b(void){ if(inst==0x4AFC){ sprintf(sdebug,"illegal"); }else{ ea; sprintf(sdebug,"tas %s",eabuffer); } } /******************** LEA ********************/ static void m68_lea___n_l(void){ ea;sprintf(sdebug,"lea %s,a%d",eabuffer,(inst>>9)&7); } /******************** PEA ********************/ static void m68_pea_____l(void){ ea;if(isregister){/* SWAP Dn */ sprintf(sdebug,"swap d%d",inst&7); }else{ sprintf(sdebug,"pea %s",eabuffer); } } /******************** CLR, NEG, NEGX, NOT, TST ********************/ #define negate_ea(name,dump) static void name(void){\ ea;sprintf(sdebug,"%s %s",dump,eabuffer);\ } negate_ea(m68_neg_____b,"neg.b ") negate_ea(m68_neg_____w,"neg ") negate_ea(m68_neg_____l,"neg.l ") negate_ea(m68_negx____b,"negx.b") negate_ea(m68_negx____w,"negx ") negate_ea(m68_negx____l,"negx.l") negate_ea(m68_not_____b,"not.b ") negate_ea(m68_not_____w,"not ") negate_ea(m68_not_____l,"not.l ") negate_ea(m68_clr_____b,"clr.b ") negate_ea(m68_clr_____w,"clr ") negate_ea(m68_clr_____l,"clr.l ") negate_ea(m68_tst_____b,"tst.b ") negate_ea(m68_tst_____w,"tst ") negate_ea(m68_tst_____l,"tst.l ") /******************** SOURCE: IMMEDIATE DATA ********************* DESTINATION: EFFECTIVE ADDRESS ********************/ #define im_to_ea(name,type,hextype,fetchtype,dump,r) static void name(void){\ type src=(type)fetchtype();\ if((inst&0x3F)==0x3C){\ sprintf(sdebug,"%s #$"hextype",%s",dump,src,r);\ }else{\ ea;sprintf(sdebug,"%s #$"hextype",%s",dump,src,eabuffer);\ }\ } im_to_ea(m68_ori_____b,byte ,hex08,fetch ,"or.b ","ccr") im_to_ea(m68_ori_____w,word ,hex16,fetch ,"or ","sr" ) im_to_ea(m68_ori_____l,dword,hex32,fetchl,"or.l ","" ) im_to_ea(m68_andi____b,byte ,hex08,fetch ,"and.b","ccr") im_to_ea(m68_andi____w,word ,hex16,fetch ,"and ","sr" ) im_to_ea(m68_andi____l,dword,hex32,fetchl,"and.l","" ) im_to_ea(m68_eori____b,byte ,hex08,fetch ,"eor.b","ccr") im_to_ea(m68_eori____w,word ,hex16,fetch ,"eor ","sr" ) im_to_ea(m68_eori____l,dword,hex32,fetchl,"eor.l","" ) im_to_ea(m68_addi____b,byte ,hex08,fetch ,"add.b","" ) im_to_ea(m68_addi____w,word ,hex16,fetch ,"add ","" ) im_to_ea(m68_addi____l,dword,hex32,fetchl,"add.l","" ) im_to_ea(m68_subi____b,byte ,hex08,fetch ,"sub.b","" ) im_to_ea(m68_subi____w,word ,hex16,fetch ,"sub ","" ) im_to_ea(m68_subi____l,dword,hex32,fetchl,"sub.l","" ) im_to_ea(m68_cmpi____b,byte ,hex08,fetch ,"cmp.b","" ) im_to_ea(m68_cmpi____w,word ,hex16,fetch ,"cmp ","" ) im_to_ea(m68_cmpi____l,dword,hex32,fetchl,"cmp.l","" ) /******************** SOURCE: EFFECTIVE ADDRESS ********************* DESTINATION: DATA REGISTER ********************/ #define ea_to_dn(name,dump) static void name(void){\ ea;sprintf(sdebug,"%s %s,d%d",dump,eabuffer,(inst>>9)&7);\ } ea_to_dn(m68_or__d_n_b,"or.b ") ea_to_dn(m68_or__d_n_w,"or ") ea_to_dn(m68_or__d_n_l,"or.l ") ea_to_dn(m68_and_d_n_b,"and.b") ea_to_dn(m68_and_d_n_w,"and ") ea_to_dn(m68_and_d_n_l,"and.l") ea_to_dn(m68_add_d_n_b,"add.b") ea_to_dn(m68_add_d_n_w,"add ") ea_to_dn(m68_add_d_n_l,"add.l") ea_to_dn(m68_sub_d_n_b,"sub.b") ea_to_dn(m68_sub_d_n_w,"sub ") ea_to_dn(m68_sub_d_n_l,"sub.l") ea_to_dn(m68_cmp_d_n_b,"cmp.b") ea_to_dn(m68_cmp_d_n_w,"cmp ") ea_to_dn(m68_cmp_d_n_l,"cmp.l") /******************** SOURCE: EFFECTIVE ADDRESS ********************* DESTINATION: ADDRESS REGISTER ********************/ #define ea_to_an(name,dump) static void name(void){\ ea;sprintf(sdebug,"%s %s,a%d",dump,eabuffer,((inst>>9)&7));\ } ea_to_an(m68_adda__n_w,"add ") ea_to_an(m68_adda__n_l,"add.l") ea_to_an(m68_suba__n_w,"sub ") ea_to_an(m68_suba__n_l,"sub.l") ea_to_an(m68_cmpa__n_w,"cmp ") ea_to_an(m68_cmpa__n_l,"cmp.l") /******************** SUPPORT ROUTINE: ADDX AND SUBX ********************/ #define support_addsubx(name,dump)\ static void name(void){\ word nregx=(inst>>9)&7,nregy=inst&7;\ if(inst&0x0008)sprintf(sdebug,"%s -(a%d),-(a%d)",dump,nregy,nregx);\ else sprintf(sdebug,"%s d%d,d%d",dump,nregy,nregx);\ } support_addsubx(m68support_addx_b,"addx.b") support_addsubx(m68support_addx_w,"addx ") support_addsubx(m68support_addx_l,"addx.l") support_addsubx(m68support_subx_b,"subx.b") support_addsubx(m68support_subx_w,"subx ") support_addsubx(m68support_subx_l,"subx.l") #define support_bcd(name,dump)\ static void name(void){\ word nregx=(inst>>9)&7,nregy=inst&7;\ if(inst&0x0008)sprintf(sdebug,"%s -(a%d),-(a%d)",dump,nregy,nregx);\ else sprintf(sdebug,"%s d%d,d%d",dump,nregy,nregx);\ } support_bcd(m68support_abcd,"abcd") support_bcd(m68support_sbcd,"sbcd") /******************** SUPPORT ROUTINE: CMPM ********************/ #define support_cmpm(name,dump) static void name(void){\ sprintf(sdebug,"%s (a%d)+,(a%d)+",dump,inst&7,(inst>>9)&7);\ } support_cmpm(m68support_cmpm_b,"cmp.b") support_cmpm(m68support_cmpm_w,"cmp ") support_cmpm(m68support_cmpm_l,"cmp.l") /******************** SUPPORT ROUTINE: EXG ********************/ static void m68support_exg_same(void){ dword rx; rx=(inst&8)|((inst>>9)&7); sprintf(sdebug,"exg %c%d,%c%d", rx&8?'a':'d',rx&7,inst&8?'a':'d',inst&7); } static void m68support_exg_diff(void){ sprintf(sdebug,"exg d%d,a%d",(inst>>9)&7,inst&7); } /******************** SOURCE: DATA REGISTER ********************* DESTINATION: EFFECTIVE ADDRESS ********************* ********************* calls a support routine if EA is a register ********************/ #define dn_to_ea(name,dump,s_cond,s_routine)\ static void name(void){\ ea;if(s_cond)s_routine();\ else sprintf(sdebug,"%s d%d,%s",dump,(inst>>9)&7,eabuffer);\ } dn_to_ea(m68_add_e_n_b,"add.b",isregister,m68support_addx_b) dn_to_ea(m68_add_e_n_w,"add ",isregister,m68support_addx_w) dn_to_ea(m68_add_e_n_l,"add.l",isregister,m68support_addx_l) dn_to_ea(m68_sub_e_n_b,"sub.b",isregister,m68support_subx_b) dn_to_ea(m68_sub_e_n_w,"sub ",isregister,m68support_subx_w) dn_to_ea(m68_sub_e_n_l,"sub.l",isregister,m68support_subx_l) dn_to_ea(m68_eor_e_n_b,"eor.b",isaddressr,m68support_cmpm_b) dn_to_ea(m68_eor_e_n_w,"eor ",isaddressr,m68support_cmpm_w) dn_to_ea(m68_eor_e_n_l,"eor.l",isaddressr,m68support_cmpm_l) dn_to_ea(m68_or__e_n_b,"or.b ",isregister,m68support_sbcd) dn_to_ea(m68_or__e_n_w,"or ",isregister,m68unsupported) dn_to_ea(m68_or__e_n_l,"or.l ",isregister,m68unsupported) dn_to_ea(m68_and_e_n_b,"and.b",isregister,m68support_abcd) dn_to_ea(m68_and_e_n_w,"and ",isregister,m68support_exg_same) dn_to_ea(m68_and_e_n_l,"and.l",isaddressr,m68support_exg_diff) /******************** SOURCE: QUICK DATA ********************* DESTINATION: EFFECTIVE ADDRESS ********************/ #define qn_to_ea(name,dump1) static void name(void){\ ea;sprintf(sdebug,"%s #%d,%s",dump1,(((inst>>9)&7)==0)?8:(inst>>9)&7,eabuffer);\ } qn_to_ea(m68_addq__n_b,"add.b") qn_to_ea(m68_addq__n_w,"add ") qn_to_ea(m68_addq__n_l,"add.l") qn_to_ea(m68_subq__n_b,"sub.b") qn_to_ea(m68_subq__n_w,"sub ") qn_to_ea(m68_subq__n_l,"sub.l") /******************** SOURCE: QUICK DATA ********************* DESTINATION: DATA REGISTER ********************/ /* MOVEQ is the only instruction that uses this form */ static void m68_moveq_n_l(void){ sprintf(sdebug,"moveq #$"hex08",d%d",inst&0xFF,(inst>>9)&7); } /******************** SOURCE: EFFECTIVE ADDRESS ********************* DESTINATION: EFFECTIVE ADDRESS ********************/ /* MOVE is the only instruction that uses this form */ #define ea_to_ea(name,dump) static void name(void){\ char tmpbuf[40];\ ea;strcpy(tmpbuf,eabuffer);\ eacalc[((((inst>>3)&(7<<3)))|((inst>>9)&7))]();\ sprintf(sdebug,"%s %s,%s",dump,tmpbuf,eabuffer);\ } ea_to_ea(m68_move____b,"move.b") ea_to_ea(m68_move____w,"move ") ea_to_ea(m68_move____l,"move.l") /******************** MOVEM, EXT ********************/ static void getreglistf(word mask,char*rl){ if(mask&0x0001){*(rl++)='d';*(rl++)='0';*(rl++)='/';} if(mask&0x0002){*(rl++)='d';*(rl++)='1';*(rl++)='/';} if(mask&0x0004){*(rl++)='d';*(rl++)='2';*(rl++)='/';} if(mask&0x0008){*(rl++)='d';*(rl++)='3';*(rl++)='/';} if(mask&0x0010){*(rl++)='d';*(rl++)='4';*(rl++)='/';} if(mask&0x0020){*(rl++)='d';*(rl++)='5';*(rl++)='/';} if(mask&0x0040){*(rl++)='d';*(rl++)='6';*(rl++)='/';} if(mask&0x0080){*(rl++)='d';*(rl++)='7';*(rl++)='/';} if(mask&0x0100){*(rl++)='a';*(rl++)='0';*(rl++)='/';} if(mask&0x0200){*(rl++)='a';*(rl++)='1';*(rl++)='/';} if(mask&0x0400){*(rl++)='a';*(rl++)='2';*(rl++)='/';} if(mask&0x0800){*(rl++)='a';*(rl++)='3';*(rl++)='/';} if(mask&0x1000){*(rl++)='a';*(rl++)='4';*(rl++)='/';} if(mask&0x2000){*(rl++)='a';*(rl++)='5';*(rl++)='/';} if(mask&0x4000){*(rl++)='a';*(rl++)='6';*(rl++)='/';} if(mask&0x8000){*(rl++)='a';*(rl++)='7';*(rl++)='/';} *(--rl)=0; } static void getreglistb(word mask,char*rl){ if(mask&0x0001){*(rl++)='a';*(rl++)='7';*(rl++)='/';} if(mask&0x0002){*(rl++)='a';*(rl++)='6';*(rl++)='/';} if(mask&0x0004){*(rl++)='a';*(rl++)='5';*(rl++)='/';} if(mask&0x0008){*(rl++)='a';*(rl++)='4';*(rl++)='/';} if(mask&0x0010){*(rl++)='a';*(rl++)='3';*(rl++)='/';} if(mask&0x0020){*(rl++)='a';*(rl++)='2';*(rl++)='/';} if(mask&0x0040){*(rl++)='a';*(rl++)='1';*(rl++)='/';} if(mask&0x0080){*(rl++)='a';*(rl++)='0';*(rl++)='/';} if(mask&0x0100){*(rl++)='d';*(rl++)='7';*(rl++)='/';} if(mask&0x0200){*(rl++)='d';*(rl++)='6';*(rl++)='/';} if(mask&0x0400){*(rl++)='d';*(rl++)='5';*(rl++)='/';} if(mask&0x0800){*(rl++)='d';*(rl++)='4';*(rl++)='/';} if(mask&0x1000){*(rl++)='d';*(rl++)='3';*(rl++)='/';} if(mask&0x2000){*(rl++)='d';*(rl++)='2';*(rl++)='/';} if(mask&0x4000){*(rl++)='d';*(rl++)='1';*(rl++)='/';} if(mask&0x8000){*(rl++)='d';*(rl++)='0';*(rl++)='/';} *(--rl)=0; } #define movem_mem(name,dumpm,dumpx)\ static void name(void){\ word regmask;\ char reglist[50];\ if((inst&0x38)==0x0000){ /* ext */\ sprintf(sdebug,dumpx"d%d",inst&7);\ }else if((inst&0x38)==0x0020){ /* predecrement addressing mode */\ regmask=fetch();\ getreglistb(regmask,reglist);\ sprintf(sdebug,dumpm"%s,-(a%d)",reglist,inst&7);\ }else{\ regmask=fetch();\ ea;getreglistf(regmask,reglist);\ sprintf(sdebug,dumpm "%s,%s",reglist,eabuffer);\ }\ } movem_mem(m68_movem___w,"movem ","ext ") movem_mem(m68_movem___l,"movem.l ","ext.l ") #define movem_reg(name,dump) static void name(void){\ word regmask;\ char reglist[50];\ regmask=fetch();\ ea;getreglistf(regmask,reglist);\ sprintf(sdebug,dump "%s,%s",eabuffer,reglist);\ } movem_reg(m68_movem_r_w,"movem ") movem_reg(m68_movem_r_l,"movem.l ") /******************** INSTRUCTIONS THAT INVOLVE SR/CCR ********************/ static void m68_move2sr_w(void){ea;sprintf(sdebug,"move %s,sr",eabuffer);} static void m68_movefsr_w(void){ea;sprintf(sdebug,"move sr,%s",eabuffer);} static void m68_move2cc_w(void){ea;sprintf(sdebug,"move.b %s,ccr",eabuffer);} static void m68_movefcc_w(void){ea;sprintf(sdebug,"move.b ccr,%s",eabuffer);} static void m68_rts_____x(void){sprintf(sdebug,"rts");} /******************** SHIFTS AND ROTATES ********************/ #define regshift(name,sizedump) \ static void name(void){\ char tmpbuf[10];\ if((inst&0x20)==0)sprintf(tmpbuf,"#$"hex08",d%d",(((inst>>9)&7)==0)?8:(inst>>9)&7,inst&7);\ else sprintf(tmpbuf,"d%d,d%d",(inst>>9)&7,inst&7);\ switch(inst&0x18){\ case 0x00:sprintf(sdebug,"as%s %s",sizedump,tmpbuf);break;\ case 0x08:sprintf(sdebug,"ls%s %s",sizedump,tmpbuf);break;\ case 0x10:sprintf(sdebug,"rox%s %s",sizedump,tmpbuf);break;\ case 0x18:sprintf(sdebug,"ro%s %s",sizedump,tmpbuf);break;\ }\ } regshift(m68_shl_r_n_b,"l.b") regshift(m68_shl_r_n_w,"l ") regshift(m68_shl_r_n_l,"l.l") regshift(m68_shr_r_n_b,"r.b") regshift(m68_shr_r_n_w,"r ") regshift(m68_shr_r_n_l,"r.l") /******************** NOP ********************/ static void m68_nop_____x(void){sprintf(sdebug,"nop");} /******************** LINK / UNLINK ********************/ static void m68_link_an_w(void){ int16 briefext=fetch(); sprintf(sdebug,"link a%d,%c#$"hex16,inst&7,briefext<0?'-':'+', briefext<0?-briefext:briefext ); } static void m68_unlk_an_x(void){ sprintf(sdebug,"unlk a%d",inst&7); } static void m68_stop____x(void){sprintf(sdebug,"stop #$%04X",fetch());} static void m68_rte_____x(void){sprintf(sdebug,"rte");} static void m68_rtr_____x(void){sprintf(sdebug,"rtr");} static void m68_reset___x(void){sprintf(sdebug,"reset");} static void m68_rtd_____x(void){ int16 briefext=fetch(); sprintf(sdebug,"rtd %c#$"hex16,briefext<0?'-':'+', briefext<0?-briefext:briefext); } static void m68_divu__n_w(void){ea;sprintf(sdebug,"divu %s,d%d",eabuffer,(inst>>9)&7);} static void m68_divs__n_w(void){ea;sprintf(sdebug,"divs %s,d%d",eabuffer,(inst>>9)&7);} static void m68_mulu__n_w(void){ea;sprintf(sdebug,"mulu %s,d%d",eabuffer,(inst>>9)&7);} static void m68_muls__n_w(void){ea;sprintf(sdebug,"muls %s,d%d",eabuffer,(inst>>9)&7);} static void m68_asr_m___w(void){ea;sprintf(sdebug,"asr %s",eabuffer);} static void m68_asl_m___w(void){ea;sprintf(sdebug,"asl %s",eabuffer);} static void m68_lsr_m___w(void){ea;sprintf(sdebug,"lsr %s",eabuffer);} static void m68_lsl_m___w(void){ea;sprintf(sdebug,"lsl %s",eabuffer);} static void m68_roxr_m__w(void){ea;sprintf(sdebug,"roxr %s",eabuffer);} static void m68_roxl_m__w(void){ea;sprintf(sdebug,"roxl %s",eabuffer);} static void m68_ror_m___w(void){ea;sprintf(sdebug,"ror %s",eabuffer);} static void m68_rol_m___w(void){ea;sprintf(sdebug,"rol %s",eabuffer);} static void m68_nbcd____b(void){ea;sprintf(sdebug,"nbcd.b %s",eabuffer);} static void m68_chk___n_w(void){ea;sprintf(sdebug,"chk %s,d%d",eabuffer,(inst>>9)&7);} static void m68_trap_nn_x(void){sprintf(sdebug,"trap #%d",inst&0xF);} static void m68_move_2u_l(void){sprintf(sdebug,"move.l a%d,usp",inst&7);} static void m68_move_fu_l(void){sprintf(sdebug,"move.l usp,a%d",inst&7);} static void m68_trapv___x(void){sprintf(sdebug,"trapv");} static char*specialregister(unsigned short int code){ switch(code&0xFFF){ case 0x000:return("sfc"); case 0x001:return("dfc"); case 0x800:return("usp"); case 0x801:return("vbr"); } return("???"); } static void m68_movec_r_x(void){ unsigned short int f=fetch(); sprintf(sdebug,"movec %s,%c%d", specialregister(f), (f&0x8000)?'a':'d',(f>>12)&7 ); } static void m68_movec_c_x(void){ unsigned short int f=fetch(); sprintf(sdebug,"movec %c%d,%s", (f&0x8000)?'a':'d',(f>>12)&7, specialregister(f) ); } /******************** SPECIAL INSTRUCTION TABLE ********************/ /* This table is used for 0100111001xxxxxx instructions (4E4x-4E7x) */ static void(*(debugspecialmap[64]))(void)={ /* 0000xx */ m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x, /* 0001xx */ m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x, /* 0010xx */ m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x, /* 0011xx */ m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x,m68_trap_nn_x, /* 0100xx */ m68_link_an_w,m68_link_an_w,m68_link_an_w,m68_link_an_w, /* 0101xx */ m68_link_an_w,m68_link_an_w,m68_link_an_w,m68_link_an_w, /* 0110xx */ m68_unlk_an_x,m68_unlk_an_x,m68_unlk_an_x,m68_unlk_an_x, /* 0111xx */ m68_unlk_an_x,m68_unlk_an_x,m68_unlk_an_x,m68_unlk_an_x, /* 1000xx */ m68_move_2u_l,m68_move_2u_l,m68_move_2u_l,m68_move_2u_l, /* 1001xx */ m68_move_2u_l,m68_move_2u_l,m68_move_2u_l,m68_move_2u_l, /* 1010xx */ m68_move_fu_l,m68_move_fu_l,m68_move_fu_l,m68_move_fu_l, /* 1011xx */ m68_move_fu_l,m68_move_fu_l,m68_move_fu_l,m68_move_fu_l, /* 1100xx */ m68_reset___x,m68_nop_____x,m68_stop____x,m68_rte_____x, /* 1101xx */ m68_rtd_____x,m68_rts_____x,m68_trapv___x,m68_rtr_____x, /* 1110xx */ m68_unrecog_x,m68_unrecog_x,m68_movec_r_x,m68_movec_c_x, /* 1111xx */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x}; static void m68_special_x(void){ debugspecialmap[inst&0x3F](); } /******************** INSTRUCTION TABLE ********************/ /* The big 1024-element jump table that handles all possible opcodes is in the following header file. Use this syntax to execute an instruction: cpumap[i>>6](); ("i" is the instruction word) */ static void(*(debugmap[1024]))(void)={ /* 00000000ss */ m68_ori_____b,m68_ori_____w,m68_ori_____l,m68_unrecog_x, /* 00000001ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00000010ss */ m68_andi____b,m68_andi____w,m68_andi____l,m68_unrecog_x, /* 00000011ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00000100ss */ m68_subi____b,m68_subi____w,m68_subi____l,m68_unrecog_x, /* 00000101ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00000110ss */ m68_addi____b,m68_addi____w,m68_addi____l,m68_unrecog_x, /* 00000111ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00001000ss */ m68_btst_st_x,m68_bchg_st_x,m68_bclr_st_x,m68_bset_st_x, /* 00001001ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00001010ss */ m68_eori____b,m68_eori____w,m68_eori____l,m68_unrecog_x, /* 00001011ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00001100ss */ m68_cmpi____b,m68_cmpi____w,m68_cmpi____l,m68_unrecog_x, /* 00001101ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00001110ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 00001111ss */ m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x,m68_bitopdn_x, /* 00010000ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010001ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010010ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010011ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010100ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010101ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010110ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00010111ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011000ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011001ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011010ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011011ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011100ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011101ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011110ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00011111ss */ m68_move____b,m68_move____b,m68_move____b,m68_move____b, /* 00100000ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100001ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100010ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100011ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100100ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100101ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100110ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00100111ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101000ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101001ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101010ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101011ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101100ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101101ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101110ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00101111ss */ m68_move____l,m68_move____l,m68_move____l,m68_move____l, /* 00110000ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110001ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110010ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110011ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110100ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110101ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110110ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00110111ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111000ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111001ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111010ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111011ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111100ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111101ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111110ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 00111111ss */ m68_move____w,m68_move____w,m68_move____w,m68_move____w, /* 01000000ss */ m68_negx____b,m68_negx____w,m68_negx____l,m68_movefsr_w, /* 01000001ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01000010ss */ m68_clr_____b,m68_clr_____w,m68_clr_____l,m68_movefcc_w, /* 01000011ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01000100ss */ m68_neg_____b,m68_neg_____w,m68_neg_____l,m68_move2cc_w, /* 01000101ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01000110ss */ m68_not_____b,m68_not_____w,m68_not_____l,m68_move2sr_w, /* 01000111ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01001000ss */ m68_nbcd____b,m68_pea_____l,m68_movem___w,m68_movem___l, /* 01001001ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01001010ss */ m68_tst_____b,m68_tst_____w,m68_tst_____l,m68_tas_____b, /* 01001011ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01001100ss */ m68_unrecog_x,m68_unrecog_x,m68_movem_r_w,m68_movem_r_l, /* 01001101ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01001110ss */ m68_unrecog_x,m68_special_x,m68_jsr_____x,m68_jmp_____x, /* 01001111ss */ m68_unrecog_x,m68_unrecog_x,m68_chk___n_w,m68_lea___n_l, /* 01010000ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_st______x, /* 01010001ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_sf______x, /* 01010010ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_shi_____x, /* 01010011ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_sls_____x, /* 01010100ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_scc_____x, /* 01010101ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_scs_____x, /* 01010110ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_sne_____x, /* 01010111ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_seq_____x, /* 01011000ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_svc_____x, /* 01011001ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_svs_____x, /* 01011010ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_spl_____x, /* 01011011ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_smi_____x, /* 01011100ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_sge_____x, /* 01011101ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_slt_____x, /* 01011110ss */ m68_addq__n_b,m68_addq__n_w,m68_addq__n_l,m68_sgt_____x, /* 01011111ss */ m68_subq__n_b,m68_subq__n_w,m68_subq__n_l,m68_sle_____x, /* 01100000ss */ m68_bra_____x,m68_bra_____x,m68_bra_____x,m68_bra_____x, /* 01100001ss */ m68_bsr_____x,m68_bsr_____x,m68_bsr_____x,m68_bsr_____x, /* 01100010ss */ m68_bhi_____x,m68_bhi_____x,m68_bhi_____x,m68_bhi_____x, /* 01100011ss */ m68_bls_____x,m68_bls_____x,m68_bls_____x,m68_bls_____x, /* 01100100ss */ m68_bcc_____x,m68_bcc_____x,m68_bcc_____x,m68_bcc_____x, /* 01100101ss */ m68_bcs_____x,m68_bcs_____x,m68_bcs_____x,m68_bcs_____x, /* 01100110ss */ m68_bne_____x,m68_bne_____x,m68_bne_____x,m68_bne_____x, /* 01100111ss */ m68_beq_____x,m68_beq_____x,m68_beq_____x,m68_beq_____x, /* 01101000ss */ m68_bvc_____x,m68_bvc_____x,m68_bvc_____x,m68_bvc_____x, /* 01101001ss */ m68_bvs_____x,m68_bvs_____x,m68_bvs_____x,m68_bvs_____x, /* 01101010ss */ m68_bpl_____x,m68_bpl_____x,m68_bpl_____x,m68_bpl_____x, /* 01101011ss */ m68_bmi_____x,m68_bmi_____x,m68_bmi_____x,m68_bmi_____x, /* 01101100ss */ m68_bge_____x,m68_bge_____x,m68_bge_____x,m68_bge_____x, /* 01101101ss */ m68_blt_____x,m68_blt_____x,m68_blt_____x,m68_blt_____x, /* 01101110ss */ m68_bgt_____x,m68_bgt_____x,m68_bgt_____x,m68_bgt_____x, /* 01101111ss */ m68_ble_____x,m68_ble_____x,m68_ble_____x,m68_ble_____x, /* 01110000ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01110001ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01110010ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01110011ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01110100ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01110101ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01110110ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01110111ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01111000ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01111001ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01111010ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01111011ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01111100ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01111101ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 01111110ss */ m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l,m68_moveq_n_l, /* 01111111ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10000000ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10000001ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10000010ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10000011ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10000100ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10000101ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10000110ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10000111ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10001000ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10001001ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10001010ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10001011ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10001100ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10001101ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10001110ss */ m68_or__d_n_b,m68_or__d_n_w,m68_or__d_n_l,m68_divu__n_w, /* 10001111ss */ m68_or__e_n_b,m68_or__e_n_w,m68_or__e_n_l,m68_divs__n_w, /* 10010000ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10010001ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10010010ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10010011ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10010100ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10010101ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10010110ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10010111ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10011000ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10011001ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10011010ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10011011ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10011100ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10011101ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10011110ss */ m68_sub_d_n_b,m68_sub_d_n_w,m68_sub_d_n_l,m68_suba__n_w, /* 10011111ss */ m68_sub_e_n_b,m68_sub_e_n_w,m68_sub_e_n_l,m68_suba__n_l, /* 10100000ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100001ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100010ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100011ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100100ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100101ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100110ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10100111ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101000ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101001ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101010ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101011ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101100ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101101ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101110ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10101111ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 10110000ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10110001ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10110010ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10110011ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10110100ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10110101ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10110110ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10110111ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10111000ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10111001ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10111010ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10111011ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10111100ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10111101ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 10111110ss */ m68_cmp_d_n_b,m68_cmp_d_n_w,m68_cmp_d_n_l,m68_cmpa__n_w, /* 10111111ss */ m68_eor_e_n_b,m68_eor_e_n_w,m68_eor_e_n_l,m68_cmpa__n_l, /* 11000000ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11000001ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11000010ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11000011ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11000100ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11000101ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11000110ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11000111ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11001000ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11001001ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11001010ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11001011ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11001100ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11001101ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11001110ss */ m68_and_d_n_b,m68_and_d_n_w,m68_and_d_n_l,m68_mulu__n_w, /* 11001111ss */ m68_and_e_n_b,m68_and_e_n_w,m68_and_e_n_l,m68_muls__n_w, /* 11010000ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11010001ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11010010ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11010011ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11010100ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11010101ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11010110ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11010111ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11011000ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11011001ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11011010ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11011011ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11011100ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11011101ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11011110ss */ m68_add_d_n_b,m68_add_d_n_w,m68_add_d_n_l,m68_adda__n_w, /* 11011111ss */ m68_add_e_n_b,m68_add_e_n_w,m68_add_e_n_l,m68_adda__n_l, /* 11100000ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_asr_m___w, /* 11100001ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_asl_m___w, /* 11100010ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_lsr_m___w, /* 11100011ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_lsl_m___w, /* 11100100ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_roxr_m__w, /* 11100101ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_roxl_m__w, /* 11100110ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_ror_m___w, /* 11100111ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_rol_m___w, /* 11101000ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_unrecog_x, /* 11101001ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_unrecog_x, /* 11101010ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_unrecog_x, /* 11101011ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_unrecog_x, /* 11101100ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_unrecog_x, /* 11101101ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_unrecog_x, /* 11101110ss */ m68_shr_r_n_b,m68_shr_r_n_w,m68_shr_r_n_l,m68_unrecog_x, /* 11101111ss */ m68_shl_r_n_b,m68_shl_r_n_w,m68_shl_r_n_l,m68_unrecog_x, /* 11110000ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110001ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110010ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110011ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110100ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110101ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110110ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11110111ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111000ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111001ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111010ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111011ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111100ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111101ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111110ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x, /* 11111111ss */ m68_unrecog_x,m68_unrecog_x,m68_unrecog_x,m68_unrecog_x}; static void cpudebug_disassemble(int n) { while(n--) { dword addr = debugpc; cpudebug_printf("%08X: ", addr); isize = 0; inst = fetch(); debugmap[inst >> 6](); while(addr < debugpc) { cpudebug_printf("%04X ", s68000fetch(addr) & 0xFFFF); addr += 2; } while(isize < 10) { cpudebug_printf(" "); isize += 2; } cpudebug_printf("%s\n", sdebug); } } static void cpudebug_hexdump(void) { byte c, tmpchar[16]; dword tmpaddr; int i, j, k; tmpaddr = hexaddr & 0xFFFFFFF0; for(i = 0; i < 8; i++) { cpudebug_printf("%08X: %c", tmpaddr, (hexaddr == tmpaddr) ? '>' : ' ' ); for(j = 0; j < 16; j += 2) { k = s68000fetch(tmpaddr) & 0xFFFF; tmpchar[j ] = k >> 8; tmpchar[j + 1] = k & 0xFF; tmpaddr += 2; cpudebug_printf("%02X%02X%c", tmpchar[j], tmpchar[j + 1], (( hexaddr == tmpaddr )&&(j!=14))?'>': (((hexaddr&0xFFFFFFFE)==(tmpaddr-2))?'<':' ') ); } cpudebug_printf(" "); for(j = 0; j < 16; j++) { c = tmpchar[j]; if((c<32)||(c>126))c='.'; cpudebug_printf("%c", c); } cpudebug_printf("\n"); } hexaddr += 0x80; } static void cpudebug_registerdump(void) { int i; cpudebug_printf( "d0=%08X d4=%08X a0=%08X a4=%08X %c%c%c%c%c\n", s68000context.dreg[0],s68000context.dreg[4], s68000context.areg[0],s68000context.areg[4], (s68000context.sr >> 4) & 1 ? 'X' : '-', (s68000context.sr >> 3) & 1 ? 'N' : '-', (s68000context.sr >> 2) & 1 ? 'Z' : '-', (s68000context.sr >> 1) & 1 ? 'V' : '-', (s68000context.sr ) & 1 ? 'C' : '-' ); cpudebug_printf( "d1=%08X d5=%08X a1=%08X a5=%08X intmask=%d\n", s68000context.dreg[1], s68000context.dreg[5], s68000context.areg[1], s68000context.areg[5], (s68000context.sr >> 8) & 7 ); cpudebug_printf( "d2=%08X d6=%08X a2=%08X a6=%08X ", s68000context.dreg[2], s68000context.dreg[6], s68000context.areg[2], s68000context.areg[6] ); for(i = 1; i <= 7; i++) { if(s68000context.interrupts[0] & (1 << i)) { cpudebug_printf("%02X", s68000context.interrupts[i]); } else { cpudebug_printf("--"); } } cpudebug_printf( "\nd3=%08X d7=%08X a3=%08X a7=%08X %csp=%08X\n", s68000context.dreg[3], s68000context.dreg[7], s68000context.areg[3], s68000context.areg[7], ((s68000context.sr)&0x2000)?'u':'s', s68000context.asp ); debugpc = s68000context.pc; cpudebug_disassemble(1); debugpc = s68000context.pc; } int cpudebug_interactive( int cpun, void (*put)(const char*), void (*get)(char*, int), void (*execstep)(void), void (*dump)(void) ) { char inputstr[80]; char *cmd, *args, *argsend; dword tmppc; hexaddr = 0; cpudebug_put = put; cpudebug_get = get; for(;;) { s68000flushInterrupts(); cpudebug_printf("cpu%d-", cpun); cpudebug_gets(inputstr, sizeof(inputstr)); cmd = inputstr; while((tolower(*cmd) < 'a') && (tolower(*cmd) > 'z')) { if(!(*cmd)) break; cmd++; } if(!(*cmd)) continue; *cmd = tolower(*cmd); args = cmd + 1; while((*args) && ((*args) < 32)) args++; switch(*cmd) { case '?': cpudebug_printf( "b [address] Run continuously, break at PC=[address]\n" "d [address] Dump memory, starting at [address]\n" "h Hardware dump\n" "i [number] Generate hardware interrupt [number]\n" "j [address] Jump directly to [address]\n" "q Quit\n" "r Show register dump and next instruction\n" "s [n] Switch to CPU [n]\n" "t [hex number] Trace through [hex number] instructions\n" "u [address] Unassemble code, starting at [address]\n" ); break; case 'b': if(*args) { tmppc = strtoul(args, &argsend, 16); if(argsend != args) { while(s68000context.pc != tmppc) if(execstep) execstep(); else s68000exec(1); cpudebug_registerdump(); } else { cpudebug_printf("Invalid address\n"); } } else { cpudebug_printf("Need an address\n"); } break; case 'u': if(*args) { tmppc = strtoul(args, &argsend, 16); if(argsend != args) debugpc = tmppc; } cpudebug_disassemble(16); break; case 'd': if(*args) { tmppc = strtoul(args,&argsend,16); if(argsend != args) hexaddr = tmppc; } cpudebug_hexdump(); break; case 'h': if(dump) dump(); break; case 'j': if(*args) { tmppc = strtoul(args, &argsend, 16); if(argsend != args) { s68000context.pc = tmppc; cpudebug_printf("PC set to %08X\n", s68000context.pc ); debugpc = s68000context.pc; cpudebug_disassemble(1); debugpc = s68000context.pc; } else { cpudebug_printf("Invalid address\n"); } } else { cpudebug_printf("Need an address\n"); } break; case 'i': if(*args) { tmppc = strtoul(args, &argsend, 10); if(argsend != args) { cpudebug_printf("Interrupt %d generated\n", tmppc); s68000interrupt(tmppc, -1); s68000flushInterrupts(); cpudebug_registerdump(); debugpc = s68000context.pc; } else { cpudebug_printf("Invalid interrupt number\n"); } } else { cpudebug_printf("Need an interrupt number\n"); } break; case 't': tmppc = 1; if(*args) { tmppc = strtoul(args, &argsend, 16); if(argsend == args) tmppc = 1; } if(tmppc > 0) { while(tmppc--) { if(execstep) execstep(); else s68000exec(1); } cpudebug_registerdump(); } break; case 'r': cpudebug_registerdump(); break; case 'q': return -1; case 's': if(*args) { tmppc = strtoul(args, &argsend, 10); if(tmppc > 0) return tmppc; else cpudebug_printf("Invalid CPU number\n"); } else return 0; break; default: /* cpudebug_printf("Unknown command\n");*/ break; } } return -1; }