kolibrios/programs/emulator/dgen-sdl-1.33/star/cpudebug.c
turbocat ea1a60faa3 Upload DGEN port source
git-svn-id: svn://kolibrios.org@9837 a494cfbc-eb01-0410-851d-a64ba20cac60
2022-06-15 18:25:17 +00:00

1389 lines
53 KiB
C

/*
** 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <stdint.h>
#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;
}