forked from KolibriOS/kolibrios
ea1a60faa3
git-svn-id: svn://kolibrios.org@9837 a494cfbc-eb01-0410-851d-a64ba20cac60
1389 lines
53 KiB
C
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;
|
|
}
|