mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-24 10:32:32 +00:00
- Merge with Basilisk II/JIT cpu core, interpretive part for now
- Clean use of USE_PREFETCH_BUFFER macro and dependent bits
This commit is contained in:
parent
4f8d06b671
commit
7972082c56
@ -65,7 +65,7 @@ bool Init680x0(void)
|
||||
ROMBaseMac = (uint32)ROMBaseHost;
|
||||
#elif DIRECT_ADDRESSING
|
||||
// Mac address space = host address space minus constant offset (MEMBaseDiff)
|
||||
// NOTE: MEMBaseDiff is set in main_unix.cpp/main()
|
||||
// NOTE: MEMBaseDiff is set up in main_unix.cpp/main()
|
||||
RAMBaseMac = 0;
|
||||
ROMBaseMac = Host2MacAddr(ROMBaseHost);
|
||||
#else
|
||||
@ -122,7 +122,7 @@ void InitFrameBufferMapping(void)
|
||||
void Start680x0(void)
|
||||
{
|
||||
m68k_reset();
|
||||
m68k_go(true);
|
||||
m68k_execute();
|
||||
}
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ void Start680x0(void)
|
||||
|
||||
void TriggerInterrupt(void)
|
||||
{
|
||||
regs.spcflags |= SPCFLAG_INT;
|
||||
SPCFLAGS_SET( SPCFLAG_INT );
|
||||
}
|
||||
|
||||
void TriggerNMI(void)
|
||||
@ -179,7 +179,7 @@ void Execute68kTrap(uint16 trap, struct M68kRegisters *r)
|
||||
m68k_setpc(m68k_areg(regs, 7));
|
||||
fill_prefetch_0();
|
||||
quit_program = 0;
|
||||
m68k_go(true);
|
||||
m68k_execute();
|
||||
|
||||
// Clean up stack
|
||||
m68k_areg(regs, 7) += 4;
|
||||
@ -226,7 +226,7 @@ void Execute68k(uint32 addr, struct M68kRegisters *r)
|
||||
m68k_setpc(addr);
|
||||
fill_prefetch_0();
|
||||
quit_program = 0;
|
||||
m68k_go(true);
|
||||
m68k_execute();
|
||||
|
||||
// Clean up stack
|
||||
m68k_areg(regs, 7) += 2;
|
||||
|
@ -58,8 +58,8 @@ int main(int argc, char **argv)
|
||||
printf ("#include \"sysdeps.h\"\n");
|
||||
printf ("#include \"readcpu.h\"\n");
|
||||
printf ("struct instr_def defs68k[] = {\n");
|
||||
#if 0
|
||||
tablef = fopen("table68k","r");
|
||||
#ifdef WIN32
|
||||
tablef = fopen(argc > 1 ? argv[1] : "table68k","r");
|
||||
if (tablef == NULL) {
|
||||
fprintf(stderr, "table68k not found\n");
|
||||
exit(1);
|
||||
@ -76,6 +76,7 @@ int main(int argc, char **argv)
|
||||
char opcstr[256];
|
||||
int bitpos[16];
|
||||
int flagset[5], flaguse[5];
|
||||
char cflow;
|
||||
|
||||
unsigned int bitmask,bitpattern;
|
||||
int n_variable;
|
||||
@ -107,6 +108,7 @@ int main(int argc, char **argv)
|
||||
case 'r': currbit = bitr; break;
|
||||
case 'R': currbit = bitR; break;
|
||||
case 'z': currbit = bitz; break;
|
||||
case 'E': currbit = bitE; break;
|
||||
case 'p': currbit = bitp; break;
|
||||
default: abort();
|
||||
}
|
||||
@ -156,7 +158,6 @@ int main(int argc, char **argv)
|
||||
getnextch();
|
||||
switch(nextch){
|
||||
case '-': flagset[i] = fa_unset; break;
|
||||
case '/': flagset[i] = fa_isjmp; break;
|
||||
case '0': flagset[i] = fa_zero; break;
|
||||
case '1': flagset[i] = fa_one; break;
|
||||
case 'x': flagset[i] = fa_dontcare; break;
|
||||
@ -176,13 +177,31 @@ int main(int argc, char **argv)
|
||||
getnextch();
|
||||
switch(nextch){
|
||||
case '-': flaguse[i] = fu_unused; break;
|
||||
case '/': flaguse[i] = fu_isjmp; break;
|
||||
case '+': flaguse[i] = fu_maybecc; break;
|
||||
case '?': flaguse[i] = fu_unknown; break;
|
||||
default: flaguse[i] = fu_used; break;
|
||||
}
|
||||
}
|
||||
|
||||
getnextch();
|
||||
while (isspace(nextch))
|
||||
getnextch();
|
||||
|
||||
if (nextch != ':') /* Get control flow information */
|
||||
abort();
|
||||
|
||||
cflow = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
getnextch();
|
||||
switch(nextch){
|
||||
case '-': break;
|
||||
case 'R': cflow |= fl_return; break;
|
||||
case 'B': cflow |= fl_branch; break;
|
||||
case 'J': cflow |= fl_jump; break;
|
||||
case 'T': cflow |= fl_trap; break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
getnextch();
|
||||
while (isspace(nextch))
|
||||
getnextch();
|
||||
@ -234,7 +253,7 @@ int main(int argc, char **argv)
|
||||
for(i = 0; i < 5; i++) {
|
||||
printf("{ %d, %d }%c ", flaguse[i], flagset[i], i == 4 ? ' ' : ',');
|
||||
}
|
||||
printf("}, %d, \"%s\"}", sduse, opstrp);
|
||||
printf("}, %d, %d, \"%s\"}", cflow, sduse, opstrp);
|
||||
}
|
||||
}
|
||||
printf("};\nint n_defs68k = %d;\n", no_insns);
|
||||
|
@ -725,7 +725,6 @@ static void genflags (flagtypes type, wordsizes size, char *value, char *src, ch
|
||||
start_brace ();
|
||||
printf ("\tuae_u32 %s;\n", value);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -746,6 +745,7 @@ static void genflags (flagtypes type, wordsizes size, char *value, char *src, ch
|
||||
}
|
||||
printf ("\t}\n");
|
||||
return;
|
||||
|
||||
case flag_logical:
|
||||
if (strcmp (value, "0") == 0) {
|
||||
printf ("\tSET_CZNV (FLAGVAL_Z);\n");
|
||||
@ -786,7 +786,6 @@ static void genflags (flagtypes type, wordsizes size, char *value, char *src, ch
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
genflags_normal (type, size, value, src, dst);
|
||||
}
|
||||
|
||||
@ -824,6 +823,25 @@ static int source_is_imm1_8 (struct instr *i)
|
||||
return i->stype == 3;
|
||||
}
|
||||
|
||||
static const char * cflow_string_of(uae_u32 opcode)
|
||||
{
|
||||
const char * cflow_type_str;
|
||||
|
||||
int cflow_type = table68k[opcode].cflow & ~fl_trap;
|
||||
switch (cflow_type) {
|
||||
case fl_branch: cflow_type_str = "CFLOW_BRANCH"; break;
|
||||
case fl_jump: cflow_type_str = "CFLOW_JUMP"; break;
|
||||
case fl_return: cflow_type_str = "CFLOW_RETURN"; break;
|
||||
default: cflow_type_str = "CFLOW_NORMAL";
|
||||
}
|
||||
|
||||
/* Patch M68K_EXEC_RETURN instruction */
|
||||
if (table68k[opcode].mnemo == i_EMULOP_RETURN)
|
||||
cflow_type_str = "CFLOW_EXEC_RETURN";
|
||||
|
||||
return cflow_type_str;
|
||||
}
|
||||
|
||||
static void gen_opcode (unsigned long int opcode)
|
||||
{
|
||||
struct instr *curi = table68k + opcode;
|
||||
@ -957,7 +975,7 @@ static void gen_opcode (unsigned long int opcode)
|
||||
printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
|
||||
printf ("\tuae_u16 newv, tmp_newv;\n");
|
||||
printf ("\tint cflg;\n");
|
||||
printf ("\tnewv = tmp_newv = newv_hi + newv_lo;");
|
||||
printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n");
|
||||
printf ("\tif (newv_lo > 9) { newv += 6; }\n");
|
||||
printf ("\tcflg = (newv & 0x3F0) > 0x90;\n");
|
||||
printf ("\tif (cflg) newv += 0x60;\n");
|
||||
@ -989,7 +1007,7 @@ static void gen_opcode (unsigned long int opcode)
|
||||
printf ("\tuae_u16 newv;\n");
|
||||
printf ("\tint cflg;\n");
|
||||
printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
|
||||
printf ("\tnewv = newv_hi + newv_lo;");
|
||||
printf ("\tnewv = newv_hi + newv_lo;\n");
|
||||
printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
|
||||
printf ("\tif (cflg) newv -= 0x60;\n");
|
||||
printf ("\tSET_CFLG (cflg);\n");
|
||||
@ -1201,6 +1219,7 @@ static void gen_opcode (unsigned long int opcode)
|
||||
printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n");
|
||||
/* gb-- the next two lines are deleted in Bernie's gencpu.c */
|
||||
printf ("\telse if ((format & 0xF000) == 0x3000) { m68k_areg(regs, 7) += 4; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x7000) { m68k_areg(regs, 7) += 52; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n");
|
||||
@ -1289,6 +1308,18 @@ static void gen_opcode (unsigned long int opcode)
|
||||
m68k_pc_offset = 0;
|
||||
break;
|
||||
case i_Bcc:
|
||||
if (0 && !using_prefetch && !using_exception_3 && (cpu_level >= 2)) {
|
||||
/* gb-- variant probably more favorable to compiler optimizations
|
||||
also assumes no prefetch buffer is used
|
||||
Hmm, that would make sense with processors capable of conditional moves */
|
||||
if (curi->size == sz_long && next_cpu_level < 1)
|
||||
next_cpu_level = 1;
|
||||
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
|
||||
printf ("\tm68k_incpc (cctrue(%d) ? ((uae_s32)src + 2) : %d);\n", curi->cc, m68k_pc_offset);
|
||||
m68k_pc_offset = 0;
|
||||
}
|
||||
else {
|
||||
/* original code for branch instructions */
|
||||
if (curi->size == sz_long) {
|
||||
if (cpu_level < 2) {
|
||||
printf ("\tm68k_incpc(2);\n");
|
||||
@ -1312,15 +1343,12 @@ static void gen_opcode (unsigned long int opcode)
|
||||
printf ("\t}\n");
|
||||
need_endlabel = 1;
|
||||
}
|
||||
#ifdef USE_COMPILER
|
||||
printf ("\tm68k_setpc_bcc(m68k_getpc() + 2 + (uae_s32)src);\n");
|
||||
#else
|
||||
printf ("\tm68k_incpc ((uae_s32)src + 2);\n");
|
||||
#endif
|
||||
fill_prefetch_0 ();
|
||||
printf ("\tgoto %s;\n", endlabelstr);
|
||||
printf ("cpuop_return(%s);\n", cflow_string_of(opcode));
|
||||
printf ("didnt_jump:;\n");
|
||||
need_endlabel = 1;
|
||||
}
|
||||
break;
|
||||
case i_LEA:
|
||||
genamode (curi->smode, "srcreg", curi->size, "src", 0, 0);
|
||||
@ -1348,13 +1376,9 @@ static void gen_opcode (unsigned long int opcode)
|
||||
printf ("\t\t}\n");
|
||||
need_endlabel = 1;
|
||||
}
|
||||
#ifdef USE_COMPILER
|
||||
printf ("\t\t\tm68k_setpc_bcc(m68k_getpc() + (uae_s32)offs + 2);\n");
|
||||
#else
|
||||
printf ("\t\t\tm68k_incpc((uae_s32)offs + 2);\n");
|
||||
#endif
|
||||
fill_prefetch_0 ();
|
||||
printf ("\t\tgoto %s;\n", endlabelstr);
|
||||
printf ("cpuop_return(%s);\n", cflow_string_of(opcode));
|
||||
printf ("\t\t}\n");
|
||||
printf ("\t}\n");
|
||||
need_endlabel = 1;
|
||||
@ -1452,7 +1476,7 @@ static void gen_opcode (unsigned long int opcode)
|
||||
abort ();
|
||||
}
|
||||
printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
|
||||
printf ("\tSET_CFLG (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
|
||||
printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
|
||||
printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc); goto %s; }\n}\n", endlabelstr);
|
||||
need_endlabel = 1;
|
||||
break;
|
||||
@ -1989,7 +2013,7 @@ static void gen_opcode (unsigned long int opcode)
|
||||
printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n");
|
||||
}
|
||||
printf ("\ttmp >>= (32 - width);\n");
|
||||
printf ("\tSET_NFLG (tmp & (1 << (width-1)) ? 1 : 0);\n");
|
||||
printf ("\tSET_NFLG_ALWAYS (tmp & (1 << (width-1)) ? 1 : 0);\n");
|
||||
printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n");
|
||||
switch (curi->mnemo) {
|
||||
case i_BFTST:
|
||||
@ -2017,7 +2041,7 @@ static void gen_opcode (unsigned long int opcode)
|
||||
break;
|
||||
case i_BFINS:
|
||||
printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n");
|
||||
printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n");
|
||||
printf ("\tSET_NFLG_ALWAYS (tmp & (1 << (width - 1)) ? 1 : 0);\n");
|
||||
printf ("\tSET_ZFLG (tmp == 0);\n");
|
||||
break;
|
||||
default:
|
||||
@ -2175,6 +2199,18 @@ static void gen_opcode (unsigned long int opcode)
|
||||
swap_opcode ();
|
||||
printf ("\tmmu_op(opcode,extra);\n");
|
||||
break;
|
||||
|
||||
case i_EMULOP_RETURN:
|
||||
printf ("\tm68k_emulop_return();\n");
|
||||
m68k_pc_offset = 0;
|
||||
break;
|
||||
|
||||
case i_EMULOP:
|
||||
printf ("\n");
|
||||
swap_opcode ();
|
||||
printf ("\tm68k_emulop(opcode);\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
@ -2186,11 +2222,22 @@ static void gen_opcode (unsigned long int opcode)
|
||||
static void generate_includes (FILE * f)
|
||||
{
|
||||
fprintf (f, "#include \"sysdeps.h\"\n");
|
||||
|
||||
fprintf (f, "#include \"m68k.h\"\n");
|
||||
fprintf (f, "#include \"memory.h\"\n");
|
||||
fprintf (f, "#include \"readcpu.h\"\n");
|
||||
fprintf (f, "#include \"newcpu.h\"\n");
|
||||
fprintf (f, "#include \"cputbl.h\"\n");
|
||||
|
||||
fprintf (f, "#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n");
|
||||
fprintf (f, "#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n");
|
||||
fprintf (f, "#define CPUFUNC_FF(x) x##_ff\n");
|
||||
fprintf (f, "#define CPUFUNC_NF(x) x##_nf\n");
|
||||
fprintf (f, "#define CPUFUNC(x) CPUFUNC_FF(x)\n");
|
||||
|
||||
fprintf (f, "#ifdef NOFLAGS\n");
|
||||
fprintf (f, "# include \"noflags.h\"\n");
|
||||
fprintf (f, "#endif\n");
|
||||
}
|
||||
|
||||
static int postfix;
|
||||
@ -2214,13 +2261,28 @@ static void generate_one_opcode (int rp)
|
||||
return;
|
||||
|
||||
if (opcode_next_clev[rp] != cpu_level) {
|
||||
fprintf (stblfile, "{ op_%lx_%d, 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
|
||||
fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
|
||||
opcode, lookuptab[i].name);
|
||||
return;
|
||||
}
|
||||
fprintf (stblfile, "{ op_%lx_%d, 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
|
||||
fprintf (headerfile, "extern cpuop_func op_%lx_%d;\n", opcode, postfix);
|
||||
printf ("void REGPARAM2 op_%lx_%d(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
|
||||
|
||||
if (table68k[opcode].flagdead == 0)
|
||||
/* force to the "ff" variant since the instruction doesn't set at all the condition codes */
|
||||
fprintf (stblfile, "{ CPUFUNC_FF(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
|
||||
else
|
||||
fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
|
||||
|
||||
fprintf (headerfile, "extern cpuop_func op_%lx_%d_nf;\n", opcode, postfix);
|
||||
fprintf (headerfile, "extern cpuop_func op_%lx_%d_ff;\n", opcode, postfix);
|
||||
printf ("cpuop_rettype REGPARAM2 CPUFUNC(op_%lx_%d)(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
|
||||
printf ("\tcpuop_begin();\n");
|
||||
|
||||
/* gb-- The "nf" variant for an instruction that doesn't set the condition
|
||||
codes at all is the same as the "ff" variant, so we don't need the "nf"
|
||||
variant to be compiled since it is mapped to the "ff" variant in the
|
||||
smalltbl. */
|
||||
if (table68k[opcode].flagdead == 0)
|
||||
printf ("#ifndef NOFLAGS\n");
|
||||
|
||||
switch (table68k[opcode].stype) {
|
||||
case 0: smsk = 7; break;
|
||||
@ -2229,6 +2291,7 @@ static void generate_one_opcode (int rp)
|
||||
case 3: smsk = 7; break;
|
||||
case 4: smsk = 7; break;
|
||||
case 5: smsk = 63; break;
|
||||
case 6: smsk = 255; break;
|
||||
case 7: smsk = 3; break;
|
||||
default: abort ();
|
||||
}
|
||||
@ -2239,7 +2302,12 @@ static void generate_one_opcode (int rp)
|
||||
&& table68k[opcode].smode != imm && table68k[opcode].smode != imm0
|
||||
&& table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
|
||||
&& table68k[opcode].smode != absw && table68k[opcode].smode != absl
|
||||
&& table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
|
||||
&& table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16
|
||||
/* gb-- We don't want to fetch the EmulOp code since the EmulOp()
|
||||
routine uses the whole opcode value. Maybe all the EmulOps
|
||||
could be expanded out but I don't think it is an improvement */
|
||||
&& table68k[opcode].stype != 6
|
||||
)
|
||||
{
|
||||
if (table68k[opcode].spos == -1) {
|
||||
if (((int) table68k[opcode].sreg) >= 128)
|
||||
@ -2335,6 +2403,9 @@ static void generate_one_opcode (int rp)
|
||||
gen_opcode (opcode);
|
||||
if (need_endlabel)
|
||||
printf ("%s: ;\n", endlabelstr);
|
||||
if (table68k[opcode].flagdead == 0)
|
||||
printf ("\n#endif\n");
|
||||
printf ("\tcpuop_end(%s);\n", cflow_string_of(opcode));
|
||||
printf ("}\n");
|
||||
opcode_next_clev[rp] = next_cpu_level;
|
||||
opcode_last_postfix[rp] = postfix;
|
||||
@ -2362,7 +2433,7 @@ static void generate_func (void)
|
||||
opcode_next_clev[rp] = 0;
|
||||
}
|
||||
postfix = i;
|
||||
fprintf (stblfile, "struct cputbl op_smalltbl_%d[] = {\n", postfix);
|
||||
fprintf (stblfile, "struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix);
|
||||
|
||||
/* sam: this is for people with low memory (eg. me :)) */
|
||||
printf ("\n"
|
||||
|
@ -23,13 +23,18 @@ extern int intlev(void); // From baisilisk_glue.cpp
|
||||
#include "readcpu.h"
|
||||
#include "newcpu.h"
|
||||
|
||||
#if defined(ENABLE_EXCLUSIVE_SPCFLAGS) && !defined(HAVE_HARDWARE_LOCKS) && defined(HAVE_PTHREADS)
|
||||
#include <pthread.h>
|
||||
pthread_mutex_t spcflags_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
#if ENABLE_MON
|
||||
#include "mon.h"
|
||||
#include "mon_disass.h"
|
||||
#endif
|
||||
|
||||
int quit_program = 0;
|
||||
int debugging = 0;
|
||||
const int debugging = 0;
|
||||
struct flag_struct regflags;
|
||||
|
||||
/* Opcode of faulting instruction */
|
||||
@ -164,11 +169,11 @@ static __inline__ unsigned int cft_map (unsigned int f)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM;
|
||||
cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode) REGPARAM;
|
||||
|
||||
static void REGPARAM2 op_illg_1 (uae_u32 opcode)
|
||||
cpuop_rettype REGPARAM2 op_illg_1 (uae_u32 opcode)
|
||||
{
|
||||
op_illg (cft_map (opcode));
|
||||
cpuop_return( op_illg (cft_map (opcode)) );
|
||||
}
|
||||
|
||||
static void build_cpufunctbl (void)
|
||||
@ -187,11 +192,11 @@ static void build_cpufunctbl (void)
|
||||
cpu_level = 1;
|
||||
}
|
||||
struct cputbl *tbl = (
|
||||
cpu_level == 4 ? op_smalltbl_0
|
||||
: cpu_level == 3 ? op_smalltbl_1
|
||||
: cpu_level == 2 ? op_smalltbl_2
|
||||
: cpu_level == 1 ? op_smalltbl_3
|
||||
: op_smalltbl_4);
|
||||
cpu_level == 4 ? op_smalltbl_0_ff
|
||||
: cpu_level == 3 ? op_smalltbl_1_ff
|
||||
: cpu_level == 2 ? op_smalltbl_2_ff
|
||||
: cpu_level == 1 ? op_smalltbl_3_ff
|
||||
: op_smalltbl_4_ff);
|
||||
|
||||
for (opcode = 0; opcode < 65536; opcode++)
|
||||
cpufunctbl[cft_map (opcode)] = op_illg_1;
|
||||
@ -703,13 +708,13 @@ void MakeFromSR (void)
|
||||
}
|
||||
}
|
||||
|
||||
regs.spcflags |= SPCFLAG_INT;
|
||||
SPCFLAGS_SET( SPCFLAG_INT );
|
||||
if (regs.t1 || regs.t0)
|
||||
regs.spcflags |= SPCFLAG_TRACE;
|
||||
SPCFLAGS_SET( SPCFLAG_TRACE );
|
||||
else
|
||||
/* Keep SPCFLAG_DOTRACE, we still want a trace exception for
|
||||
SR-modifying instructions (including STOP). */
|
||||
regs.spcflags &= ~SPCFLAG_TRACE;
|
||||
SPCFLAGS_CLEAR( SPCFLAG_TRACE );
|
||||
}
|
||||
|
||||
void Exception(int nr, uaecptr oldpc)
|
||||
@ -774,9 +779,10 @@ kludge_me_do:
|
||||
m68k_areg(regs, 7) -= 2;
|
||||
put_word (m68k_areg(regs, 7), regs.sr);
|
||||
m68k_setpc (get_long (regs.vbr + 4*nr));
|
||||
SPCFLAGS_SET( SPCFLAG_JIT_END_COMPILE );
|
||||
fill_prefetch_0 ();
|
||||
regs.t1 = regs.t0 = regs.m = 0;
|
||||
regs.spcflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
|
||||
SPCFLAGS_CLEAR( SPCFLAG_TRACE | SPCFLAG_DOTRACE );
|
||||
}
|
||||
|
||||
static void Interrupt(int nr)
|
||||
@ -787,7 +793,7 @@ static void Interrupt(int nr)
|
||||
Exception(nr+24, 0);
|
||||
|
||||
regs.intmask = nr;
|
||||
regs.spcflags |= SPCFLAG_INT;
|
||||
SPCFLAGS_SET( SPCFLAG_INT );
|
||||
}
|
||||
|
||||
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1, mmusr, urp, srp;
|
||||
@ -1115,12 +1121,16 @@ static char* ccnames[] =
|
||||
{ "T ","F ","HI","LS","CC","CS","NE","EQ",
|
||||
"VC","VS","PL","MI","GE","LT","GT","LE" };
|
||||
|
||||
// If value is greater than zero, this means we are still processing an EmulOp
|
||||
// because the counter is incremented only in m68k_execute(), i.e. interpretive
|
||||
// execution only
|
||||
static int m68k_execute_depth = 0;
|
||||
|
||||
void m68k_reset (void)
|
||||
{
|
||||
m68k_areg (regs, 7) = 0x2000;
|
||||
m68k_setpc (ROMBaseMac + 0x2a);
|
||||
fill_prefetch_0 ();
|
||||
regs.kick_mask = 0xF80000;
|
||||
regs.s = 1;
|
||||
regs.m = 0;
|
||||
regs.stopped = 0;
|
||||
@ -1131,11 +1141,9 @@ void m68k_reset (void)
|
||||
SET_CFLG (0);
|
||||
SET_VFLG (0);
|
||||
SET_NFLG (0);
|
||||
regs.spcflags = 0;
|
||||
SPCFLAGS_INIT( 0 );
|
||||
regs.intmask = 7;
|
||||
regs.vbr = regs.sfc = regs.dfc = 0;
|
||||
/* gb-- moved into {fpp,fpu_x86}.cpp::fpu_init()
|
||||
regs.fpcr = regs.fpsr = regs.fpiar = 0; */
|
||||
fpu_reset();
|
||||
|
||||
#if FLIGHT_RECORDER
|
||||
@ -1150,22 +1158,17 @@ void m68k_reset (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void REGPARAM2 op_illg (uae_u32 opcode)
|
||||
void m68k_emulop_return(void)
|
||||
{
|
||||
uaecptr pc = m68k_getpc ();
|
||||
SPCFLAGS_SET( SPCFLAG_BRK );
|
||||
quit_program = 1;
|
||||
}
|
||||
|
||||
if ((opcode & 0xFF00) == 0x7100) {
|
||||
void m68k_emulop(uae_u32 opcode)
|
||||
{
|
||||
struct M68kRegisters r;
|
||||
int i;
|
||||
|
||||
// Return from Exectue68k()?
|
||||
if (opcode == M68K_EXEC_RETURN) {
|
||||
regs.spcflags |= SPCFLAG_BRK;
|
||||
quit_program = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Call EMUL_OP opcode
|
||||
for (i=0; i<8; i++) {
|
||||
r.d[i] = m68k_dreg(regs, i);
|
||||
r.a[i] = m68k_areg(regs, i);
|
||||
@ -1179,26 +1182,26 @@ void REGPARAM2 op_illg (uae_u32 opcode)
|
||||
}
|
||||
regs.sr = r.sr;
|
||||
MakeFromSR();
|
||||
m68k_incpc(2);
|
||||
fill_prefetch_0 ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cpuop_rettype REGPARAM2 op_illg (uae_u32 opcode)
|
||||
{
|
||||
uaecptr pc = m68k_getpc ();
|
||||
|
||||
if ((opcode & 0xF000) == 0xA000) {
|
||||
Exception(0xA,0);
|
||||
return;
|
||||
cpuop_return(CFLOW_TRAP);
|
||||
}
|
||||
|
||||
// write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc);
|
||||
|
||||
if ((opcode & 0xF000) == 0xF000) {
|
||||
Exception(0xB,0);
|
||||
return;
|
||||
cpuop_return(CFLOW_TRAP);
|
||||
}
|
||||
|
||||
write_log ("Illegal instruction: %04x at %08lx\n", opcode, pc);
|
||||
|
||||
Exception (4,0);
|
||||
cpuop_return(CFLOW_TRAP);
|
||||
}
|
||||
|
||||
void mmu_op(uae_u32 opcode, uae_u16 extra)
|
||||
@ -1225,7 +1228,7 @@ static void do_trace (void)
|
||||
/* We can afford this to be inefficient... */
|
||||
m68k_setpc (m68k_getpc ());
|
||||
fill_prefetch_0 ();
|
||||
opcode = get_word (regs.pc);
|
||||
opcode = get_word(m68k_getpc());
|
||||
if (opcode == 0x4e72 /* RTE */
|
||||
|| opcode == 0x4e74 /* RTD */
|
||||
|| opcode == 0x4e75 /* RTS */
|
||||
@ -1241,57 +1244,55 @@ static void do_trace (void)
|
||||
&& (uae_s16)m68k_dreg(regs, opcode & 7) != 0))
|
||||
{
|
||||
last_trace_ad = m68k_getpc ();
|
||||
regs.spcflags &= ~SPCFLAG_TRACE;
|
||||
regs.spcflags |= SPCFLAG_DOTRACE;
|
||||
SPCFLAGS_CLEAR( SPCFLAG_TRACE );
|
||||
SPCFLAGS_SET( SPCFLAG_DOTRACE );
|
||||
}
|
||||
} else if (regs.t1) {
|
||||
last_trace_ad = m68k_getpc ();
|
||||
regs.spcflags &= ~SPCFLAG_TRACE;
|
||||
regs.spcflags |= SPCFLAG_DOTRACE;
|
||||
SPCFLAGS_CLEAR( SPCFLAG_TRACE );
|
||||
SPCFLAGS_SET( SPCFLAG_DOTRACE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int do_specialties (void)
|
||||
int m68k_do_specialties (void)
|
||||
{
|
||||
/*n_spcinsns++;*/
|
||||
if (regs.spcflags & SPCFLAG_DOTRACE) {
|
||||
if (SPCFLAGS_TEST( SPCFLAG_DOTRACE )) {
|
||||
Exception (9,last_trace_ad);
|
||||
}
|
||||
while (regs.spcflags & SPCFLAG_STOP) {
|
||||
if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
|
||||
while (SPCFLAGS_TEST( SPCFLAG_STOP )) {
|
||||
if (SPCFLAGS_TEST( SPCFLAG_INT | SPCFLAG_DOINT )){
|
||||
SPCFLAGS_CLEAR( SPCFLAG_INT | SPCFLAG_DOINT );
|
||||
int intr = intlev ();
|
||||
regs.spcflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
|
||||
if (intr != -1 && intr > regs.intmask) {
|
||||
Interrupt (intr);
|
||||
regs.stopped = 0;
|
||||
regs.spcflags &= ~SPCFLAG_STOP;
|
||||
SPCFLAGS_CLEAR( SPCFLAG_STOP );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (regs.spcflags & SPCFLAG_TRACE)
|
||||
if (SPCFLAGS_TEST( SPCFLAG_TRACE ))
|
||||
do_trace ();
|
||||
|
||||
if (regs.spcflags & SPCFLAG_DOINT) {
|
||||
if (SPCFLAGS_TEST( SPCFLAG_DOINT )) {
|
||||
SPCFLAGS_CLEAR( SPCFLAG_DOINT );
|
||||
int intr = intlev ();
|
||||
regs.spcflags &= ~SPCFLAG_DOINT;
|
||||
if (intr != -1 && intr > regs.intmask) {
|
||||
Interrupt (intr);
|
||||
regs.stopped = 0;
|
||||
}
|
||||
}
|
||||
if (regs.spcflags & SPCFLAG_INT) {
|
||||
regs.spcflags &= ~SPCFLAG_INT;
|
||||
regs.spcflags |= SPCFLAG_DOINT;
|
||||
if (SPCFLAGS_TEST( SPCFLAG_INT )) {
|
||||
SPCFLAGS_CLEAR( SPCFLAG_INT );
|
||||
SPCFLAGS_SET( SPCFLAG_DOINT );
|
||||
}
|
||||
if (regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)) {
|
||||
regs.spcflags &= ~(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
|
||||
return 1;
|
||||
if (SPCFLAGS_TEST( SPCFLAG_BRK )) {
|
||||
SPCFLAGS_CLEAR( SPCFLAG_BRK );
|
||||
return CFLOW_EXEC_RETURN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void m68k_run_1 (void)
|
||||
void m68k_do_execute (void)
|
||||
{
|
||||
for (;;) {
|
||||
uae_u32 opcode = GET_OPCODE;
|
||||
@ -1305,27 +1306,15 @@ static void m68k_run_1 (void)
|
||||
#else
|
||||
(*cpufunctbl[opcode])(opcode);
|
||||
#endif
|
||||
if (regs.spcflags) {
|
||||
if (do_specialties())
|
||||
if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) {
|
||||
if (m68k_do_specialties())
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define m68k_run1 m68k_run_1
|
||||
|
||||
int in_m68k_go = 0;
|
||||
|
||||
void m68k_go (int may_quit)
|
||||
void m68k_execute (void)
|
||||
{
|
||||
// m68k_go() must be reentrant for Execute68k() and Execute68kTrap() to work
|
||||
/*
|
||||
if (in_m68k_go || !may_quit) {
|
||||
write_log("Bug! m68k_go is not reentrant.\n");
|
||||
abort();
|
||||
}
|
||||
*/
|
||||
in_m68k_go++;
|
||||
for (;;) {
|
||||
if (quit_program > 0) {
|
||||
if (quit_program == 1)
|
||||
@ -1333,14 +1322,13 @@ void m68k_go (int may_quit)
|
||||
quit_program = 0;
|
||||
m68k_reset ();
|
||||
}
|
||||
m68k_run1();
|
||||
m68k_do_execute();
|
||||
}
|
||||
if (debugging) {
|
||||
uaecptr nextpc;
|
||||
m68k_dumpstate(&nextpc);
|
||||
exit(1);
|
||||
}
|
||||
in_m68k_go--;
|
||||
}
|
||||
|
||||
static void m68k_verify (uaecptr addr, uaecptr *nextpc)
|
||||
|
@ -9,18 +9,10 @@
|
||||
#ifndef NEWCPU_H
|
||||
#define NEWCPU_H
|
||||
|
||||
#define SPCFLAG_STOP 2
|
||||
#define SPCFLAG_DISK 4
|
||||
#define SPCFLAG_INT 8
|
||||
#define SPCFLAG_BRK 16
|
||||
#define SPCFLAG_EXTRA_CYCLES 32
|
||||
#define SPCFLAG_TRACE 64
|
||||
#define SPCFLAG_DOTRACE 128
|
||||
#define SPCFLAG_DOINT 256
|
||||
#define SPCFLAG_BLTNASTY 512
|
||||
#define SPCFLAG_EXEC 1024
|
||||
#define SPCFLAG_MODE_CHANGE 8192
|
||||
|
||||
#include "m68k.h"
|
||||
#include "readcpu.h"
|
||||
#include "spcflags.h"
|
||||
|
||||
extern int areg_byteinc[];
|
||||
extern int imm8_table[];
|
||||
|
||||
@ -34,50 +26,77 @@ extern int fpp_movem_next[256];
|
||||
|
||||
extern int broken_in;
|
||||
|
||||
typedef void REGPARAM2 cpuop_func (uae_u32) REGPARAM;
|
||||
/* Control flow information */
|
||||
#define CFLOW_NORMAL 0
|
||||
#define CFLOW_BRANCH 1
|
||||
#define CFLOW_JUMP 2
|
||||
#define CFLOW_TRAP CFLOW_JUMP
|
||||
#define CFLOW_RETURN 3
|
||||
#define CFLOW_SPCFLAGS 32 /* some spcflags are set */
|
||||
#define CFLOW_EXEC_RETURN 64 /* must exit from the execution loop */
|
||||
|
||||
#define cpuop_rettype void
|
||||
#define cpuop_return(v) do { (v); return; } while (0)
|
||||
|
||||
#ifdef X86_ASSEMBLY
|
||||
/* This hack seems to force all register saves (pushl %reg) to be moved to the
|
||||
begining of the function, thus making it possible to cpuopti to remove them
|
||||
since m68k_run_1 will save those registers before calling the instruction
|
||||
handler */
|
||||
# define cpuop_tag(tag) __asm__ __volatile__ ( "#cpuop_" tag )
|
||||
#else
|
||||
# define cpuop_tag(tag) ;
|
||||
#endif
|
||||
|
||||
#define cpuop_begin() do { cpuop_tag("begin"); } while (0)
|
||||
#define cpuop_end(cflow) do { cpuop_tag("end"); cpuop_return(cflow); } while (0)
|
||||
|
||||
typedef cpuop_rettype REGPARAM2 cpuop_func (uae_u32) REGPARAM;
|
||||
|
||||
struct cputbl {
|
||||
cpuop_func *handler;
|
||||
int specific;
|
||||
uae_u16 specific;
|
||||
uae_u16 opcode;
|
||||
};
|
||||
|
||||
extern void REGPARAM2 op_illg (uae_u32) REGPARAM;
|
||||
extern cpuop_rettype REGPARAM2 op_illg (uae_u32) REGPARAM;
|
||||
|
||||
typedef char flagtype;
|
||||
|
||||
extern struct regstruct
|
||||
{
|
||||
uae_u32 regs[16];
|
||||
uaecptr usp,isp,msp;
|
||||
uae_u16 sr;
|
||||
flagtype t1;
|
||||
flagtype t0;
|
||||
flagtype s;
|
||||
flagtype m;
|
||||
flagtype x;
|
||||
flagtype stopped;
|
||||
int intmask;
|
||||
struct regstruct {
|
||||
uae_u32 regs[16];
|
||||
|
||||
uae_u32 pc;
|
||||
uae_u8 *pc_p;
|
||||
uae_u8 *pc_oldp;
|
||||
uae_u32 pc;
|
||||
uae_u8 * pc_p;
|
||||
uae_u8 * pc_oldp;
|
||||
|
||||
uae_u32 vbr,sfc,dfc;
|
||||
spcflags_t spcflags;
|
||||
int intmask;
|
||||
|
||||
double fp[8];
|
||||
uae_u32 fpcr,fpsr,fpiar;
|
||||
uae_u32 vbr, sfc, dfc;
|
||||
uaecptr usp, isp, msp;
|
||||
uae_u16 sr;
|
||||
flagtype t1;
|
||||
flagtype t0;
|
||||
flagtype s;
|
||||
flagtype m;
|
||||
flagtype x;
|
||||
flagtype stopped;
|
||||
|
||||
uae_u32 spcflags;
|
||||
uae_u32 kick_mask;
|
||||
double fp[8];
|
||||
uae_u32 fpcr,fpsr,fpiar;
|
||||
|
||||
#if USE_PREFETCH_BUFFER
|
||||
/* Fellow sources say this is 4 longwords. That's impossible. It needs
|
||||
* to be at least a longword. The HRM has some cryptic comment about two
|
||||
* instructions being on the same longword boundary.
|
||||
* The way this is implemented now seems like a good compromise.
|
||||
*/
|
||||
uae_u32 prefetch;
|
||||
} regs, lastint_regs;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern regstruct regs, lastint_regs;
|
||||
|
||||
#define m68k_dreg(r,num) ((r).regs[(num)])
|
||||
#define m68k_areg(r,num) (((r).regs + 8)[(num)])
|
||||
@ -92,6 +111,7 @@ extern struct regstruct
|
||||
#define GET_OPCODE (get_iword (0))
|
||||
#endif
|
||||
|
||||
#if USE_PREFETCH_BUFFER
|
||||
static __inline__ uae_u32 get_ibyte_prefetch (uae_s32 o)
|
||||
{
|
||||
if (o > 3 || o < 0)
|
||||
@ -114,6 +134,7 @@ static __inline__ uae_u32 get_ilong_prefetch (uae_s32 o)
|
||||
return do_get_mem_long(®s.prefetch);
|
||||
return (do_get_mem_word (((uae_u16 *)®s.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define m68k_incpc(o) (regs.pc_p += (o))
|
||||
|
||||
@ -166,7 +187,6 @@ static __inline__ uae_u32 next_ilong (void)
|
||||
return r;
|
||||
}
|
||||
|
||||
#if !defined USE_COMPILER
|
||||
static __inline__ void m68k_setpc (uaecptr newpc)
|
||||
{
|
||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||
@ -176,9 +196,6 @@ static __inline__ void m68k_setpc (uaecptr newpc)
|
||||
regs.pc = newpc;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
extern void m68k_setpc (uaecptr newpc);
|
||||
#endif
|
||||
|
||||
static __inline__ uaecptr m68k_getpc (void)
|
||||
{
|
||||
@ -189,15 +206,9 @@ static __inline__ uaecptr m68k_getpc (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_COMPILER
|
||||
extern void m68k_setpc_fast (uaecptr newpc);
|
||||
extern void m68k_setpc_bcc (uaecptr newpc);
|
||||
extern void m68k_setpc_rte (uaecptr newpc);
|
||||
#else
|
||||
#define m68k_setpc_fast m68k_setpc
|
||||
#define m68k_setpc_bcc m68k_setpc
|
||||
#define m68k_setpc_rte m68k_setpc
|
||||
#endif
|
||||
|
||||
static __inline__ void m68k_do_rts(void)
|
||||
{
|
||||
@ -225,7 +236,7 @@ static __inline__ void m68k_setstopped (int stop)
|
||||
/* A traced STOP instruction drops through immediately without
|
||||
actually stopping. */
|
||||
if (stop && (regs.spcflags & SPCFLAG_DOTRACE) == 0)
|
||||
regs.spcflags |= SPCFLAG_STOP;
|
||||
SPCFLAGS_SET( SPCFLAG_STOP );
|
||||
}
|
||||
|
||||
extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp);
|
||||
@ -241,13 +252,15 @@ extern int m68k_move2c (int, uae_u32 *);
|
||||
extern int m68k_movec2 (int, uae_u32 *);
|
||||
extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
|
||||
extern void m68k_mull (uae_u32, uae_u32, uae_u16);
|
||||
extern void m68k_emulop (uae_u32);
|
||||
extern void m68k_emulop_return (void);
|
||||
extern void init_m68k (void);
|
||||
extern void exit_m68k (void);
|
||||
extern void m68k_go (int);
|
||||
extern void m68k_dumpstate (uaecptr *);
|
||||
extern void m68k_disasm (uaecptr, uaecptr *, int);
|
||||
extern void m68k_reset (void);
|
||||
extern void m68k_enter_debugger(void);
|
||||
extern int m68k_do_specialties(void);
|
||||
|
||||
extern void mmu_op (uae_u32, uae_u16);
|
||||
|
||||
@ -274,16 +287,17 @@ extern uaecptr last_fault_for_exception_3;
|
||||
#define CPU_OP_NAME(a) op ## a
|
||||
|
||||
/* 68020 + 68881 */
|
||||
extern struct cputbl op_smalltbl_0[];
|
||||
extern struct cputbl op_smalltbl_0_ff[];
|
||||
/* 68020 */
|
||||
extern struct cputbl op_smalltbl_1[];
|
||||
extern struct cputbl op_smalltbl_1_ff[];
|
||||
/* 68010 */
|
||||
extern struct cputbl op_smalltbl_2[];
|
||||
extern struct cputbl op_smalltbl_2_ff[];
|
||||
/* 68000 */
|
||||
extern struct cputbl op_smalltbl_3[];
|
||||
extern struct cputbl op_smalltbl_3_ff[];
|
||||
/* 68000 slow but compatible. */
|
||||
extern struct cputbl op_smalltbl_4[];
|
||||
|
||||
extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl");
|
||||
extern struct cputbl op_smalltbl_4_ff[];
|
||||
|
||||
extern void m68k_do_execute(void);
|
||||
extern void m68k_execute(void);
|
||||
|
||||
#endif /* NEWCPU_H */
|
||||
|
142
BasiliskII/src/uae_cpu/noflags.h
Normal file
142
BasiliskII/src/uae_cpu/noflags.h
Normal file
@ -0,0 +1,142 @@
|
||||
#ifndef NOFLAGS_H
|
||||
#define NOFLAGS_H
|
||||
|
||||
/* Undefine everything that will *set* flags. Note: Leave *reading*
|
||||
flags alone ;-). We assume that nobody does something like
|
||||
SET_ZFLG(a=b+c), i.e. expect side effects of the macros. That would
|
||||
be a stupid thing to do when using macros.
|
||||
*/
|
||||
|
||||
/* Gwenole Beauchesne pointed out that CAS and CAS2 use flag_cmp to set
|
||||
flags that are then used internally, and that thus the noflags versions
|
||||
of those instructions were broken. Oops!
|
||||
Easy fix: Leave flag_cmp alone. It is only used by CMP* and CAS*
|
||||
instructions. For CAS*, noflags is a bad idea. For CMP*, which has
|
||||
setting flags as its only function, the noflags version is kinda pointless,
|
||||
anyway.
|
||||
Note that this will only work while using the optflag_* routines ---
|
||||
as we do on all (one ;-) platforms that will ever use the noflags
|
||||
versions, anyway.
|
||||
However, if you try to compile without optimized flags, the "SET_ZFLAG"
|
||||
macro will be left unchanged, to make CAS and CAS2 work right. Of course,
|
||||
this is contrary to the whole idea of noflags, but better be right than
|
||||
be fast.
|
||||
|
||||
Another problem exists with one of the bitfield operations. Once again,
|
||||
one of the operations sets a flag, and looks at it later. And the CHK2
|
||||
instruction does so as well. For those, a different solution is possible.
|
||||
the *_ALWAYS versions of the SET_?FLG macros shall remain untouched by
|
||||
the redefinitions in this file.
|
||||
Unfortunately, they are defined in terms of the macros we *do* redefine.
|
||||
So here comes a bit of trickery....
|
||||
*/
|
||||
#define NOFLAGS_CMP 0
|
||||
|
||||
#undef SET_NFLG_ALWAYS
|
||||
static __inline__ void SET_NFLG_ALWAYS(uae_u32 x)
|
||||
{
|
||||
SET_NFLG(x); /* This has not yet been redefined */
|
||||
}
|
||||
|
||||
#undef SET_CFLG_ALWAYS
|
||||
static __inline__ void SET_CFLG_ALWAYS(uae_u32 x)
|
||||
{
|
||||
SET_CFLG(x); /* This has not yet been redefined */
|
||||
}
|
||||
|
||||
#undef CPUFUNC
|
||||
#define CPUFUNC(x) x##_nf
|
||||
|
||||
#ifndef OPTIMIZED_FLAGS
|
||||
#undef SET_ZFLG
|
||||
#define SET_ZFLG(y) do {uae_u32 dummy=(y); } while (0)
|
||||
#endif
|
||||
|
||||
#undef SET_CFLG
|
||||
#define SET_CFLG(y) do {uae_u32 dummy=(y); } while (0)
|
||||
#undef SET_VFLG
|
||||
#define SET_VFLG(y) do {uae_u32 dummy=(y); } while (0)
|
||||
#undef SET_NFLG
|
||||
#define SET_NFLG(y) do {uae_u32 dummy=(y); } while (0)
|
||||
#undef SET_XFLG
|
||||
#define SET_XFLG(y) do {uae_u32 dummy=(y); } while (0)
|
||||
|
||||
#undef CLEAR_CZNV
|
||||
#define CLEAR_CZNV
|
||||
#undef IOR_CZNV
|
||||
#define IOR_CZNV(y) do {uae_u32 dummy=(y); } while (0)
|
||||
#undef SET_CZNV
|
||||
#define SET_CZNV(y) do {uae_u32 dummy=(y); } while (0)
|
||||
#undef COPY_CARRY
|
||||
#define COPY_CARRY
|
||||
|
||||
#ifdef optflag_testl
|
||||
#undef optflag_testl
|
||||
#endif
|
||||
|
||||
#ifdef optflag_testw
|
||||
#undef optflag_testw
|
||||
#endif
|
||||
|
||||
#ifdef optflag_testb
|
||||
#undef optflag_testb
|
||||
#endif
|
||||
|
||||
#ifdef optflag_addl
|
||||
#undef optflag_addl
|
||||
#endif
|
||||
|
||||
#ifdef optflag_addw
|
||||
#undef optflag_addw
|
||||
#endif
|
||||
|
||||
#ifdef optflag_addb
|
||||
#undef optflag_addb
|
||||
#endif
|
||||
|
||||
#ifdef optflag_subl
|
||||
#undef optflag_subl
|
||||
#endif
|
||||
|
||||
#ifdef optflag_subw
|
||||
#undef optflag_subw
|
||||
#endif
|
||||
|
||||
#ifdef optflag_subb
|
||||
#undef optflag_subb
|
||||
#endif
|
||||
|
||||
#if NOFLAGS_CMP
|
||||
#ifdef optflag_cmpl
|
||||
#undef optflag_cmpl
|
||||
#endif
|
||||
|
||||
#ifdef optflag_cmpw
|
||||
#undef optflag_cmpw
|
||||
#endif
|
||||
|
||||
#ifdef optflag_cmpb
|
||||
#undef optflag_cmpb
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define optflag_testl(v) do { } while (0)
|
||||
#define optflag_testw(v) do { } while (0)
|
||||
#define optflag_testb(v) do { } while (0)
|
||||
|
||||
#define optflag_addl(v, s, d) (v = (uae_s32)(d) + (uae_s32)(s))
|
||||
#define optflag_addw(v, s, d) (v = (uae_s16)(d) + (uae_s16)(s))
|
||||
#define optflag_addb(v, s, d) (v = (uae_s8)(d) + (uae_s8)(s))
|
||||
|
||||
#define optflag_subl(v, s, d) (v = (uae_s32)(d) - (uae_s32)(s))
|
||||
#define optflag_subw(v, s, d) (v = (uae_s16)(d) - (uae_s16)(s))
|
||||
#define optflag_subb(v, s, d) (v = (uae_s8)(d) - (uae_s8)(s))
|
||||
|
||||
#if NOFLAGS_CMP
|
||||
/* These are just for completeness sake */
|
||||
#define optflag_cmpl(s, d) do { } while (0)
|
||||
#define optflag_cmpw(s, d) do { } while (0)
|
||||
#define optflag_cmpb(s, d) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
@ -139,6 +139,9 @@ struct mnemolookup lookuptab[] = {
|
||||
{ i_CPUSHA, "CPUSHA" },
|
||||
{ i_MOVE16, "MOVE16" },
|
||||
|
||||
{ i_EMULOP_RETURN, "EMULOP_RETURN" },
|
||||
{ i_EMULOP, "EMULOP" },
|
||||
|
||||
{ i_MMUOP, "MMUOP" },
|
||||
{ i_ILLG, "" },
|
||||
};
|
||||
@ -195,16 +198,34 @@ static void build_insn (int insn)
|
||||
int variants;
|
||||
struct instr_def id;
|
||||
const char *opcstr;
|
||||
int i;
|
||||
int i, n;
|
||||
|
||||
int flaglive = 0, flagdead = 0;
|
||||
int cflow = 0;
|
||||
|
||||
id = defs68k[insn];
|
||||
|
||||
// Control flow information
|
||||
cflow = id.cflow;
|
||||
|
||||
// Mask of flags set/used
|
||||
unsigned char flags_set(0), flags_used(0);
|
||||
|
||||
for (i = 0, n = 4; i < 5; i++, n--) {
|
||||
switch (id.flaginfo[i].flagset) {
|
||||
case fa_unset: case fa_isjmp: break;
|
||||
default: flags_set |= (1 << n);
|
||||
}
|
||||
|
||||
switch (id.flaginfo[i].flaguse) {
|
||||
case fu_unused: case fu_isjmp: break;
|
||||
default: flags_used |= (1 << n);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
switch (id.flaginfo[i].flagset){
|
||||
case fa_unset: break;
|
||||
case fa_isjmp: break;
|
||||
case fa_zero: flagdead |= 1 << i; break;
|
||||
case fa_one: flagdead |= 1 << i; break;
|
||||
case fa_dontcare: flagdead |= 1 << i; break;
|
||||
@ -217,8 +238,6 @@ static void build_insn (int insn)
|
||||
for (i = 0; i < 5; i++) {
|
||||
switch (id.flaginfo[i].flaguse) {
|
||||
case fu_unused: break;
|
||||
case fu_isjmp: flaglive |= 1 << i; break;
|
||||
case fu_maybecc: flaglive |= 1 << i; break;
|
||||
case fu_unknown: flaglive = -1; goto out2;
|
||||
case fu_used: flaglive |= 1 << i; break;
|
||||
}
|
||||
@ -273,6 +292,8 @@ static void build_insn (int insn)
|
||||
continue;
|
||||
if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
|
||||
continue;
|
||||
if (bitcnt[bitE] && (bitval[bitE] == 0x00))
|
||||
continue;
|
||||
|
||||
/* bitI and bitC get copied to biti and bitc */
|
||||
if (bitcnt[bitI]) {
|
||||
@ -395,6 +416,14 @@ static void build_insn (int insn)
|
||||
srctype = 5;
|
||||
srcpos = bitpos[bitK];
|
||||
}
|
||||
break;
|
||||
case 'E': srcmode = immi; srcreg = bitval[bitE];
|
||||
if (CPU_EMU_SIZE < 5) { // gb-- what is CPU_EMU_SIZE used for ??
|
||||
/* 1..255 */
|
||||
srcgather = 1;
|
||||
srctype = 6;
|
||||
srcpos = bitpos[bitE];
|
||||
}
|
||||
break;
|
||||
case 'p': srcmode = immi; srcreg = bitval[bitp];
|
||||
if (CPU_EMU_SIZE < 5) {
|
||||
@ -719,8 +748,16 @@ static void build_insn (int insn)
|
||||
table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/* gb-- flagdead and flaglive would not have correct information */
|
||||
table68k[opc].flagdead = flags_set;
|
||||
table68k[opc].flaglive = flags_used;
|
||||
#else
|
||||
table68k[opc].flagdead = flagdead;
|
||||
table68k[opc].flaglive = flaglive;
|
||||
#endif
|
||||
table68k[opc].cflow = cflow;
|
||||
nomatch:
|
||||
/* FOO! */;
|
||||
}
|
||||
@ -739,6 +776,66 @@ void read_table68k (void)
|
||||
for (i = 0; i < n_defs68k; i++) {
|
||||
build_insn (i);
|
||||
}
|
||||
|
||||
/* Extra fixes in table68k for control flow information and flag usage */
|
||||
for (i = 0; i < 65536; i++) {
|
||||
instrmnem mnemo = (instrmnem)(table68k[i].mnemo);
|
||||
|
||||
#define IS_CONST_JUMP(opc) \
|
||||
( ((table68k[opc].mnemo == i_Bcc) && (table68k[opc].cc < 2)) \
|
||||
|| (table68k[opc].mnemo == i_BSR) \
|
||||
)
|
||||
|
||||
#if 0
|
||||
// gb-- Don't follow false and true branches as we may not be
|
||||
// able to determine the whole block length in bytes in order
|
||||
// to compute the block checksum
|
||||
|
||||
// We can follow unconditional jumps if neither Lazy Flusher
|
||||
// nor Dynamic Code Patches feature is enabled
|
||||
|
||||
// UPDATE: this is no longer permitted since we can decide
|
||||
// at runtime whether the JIT compiler is used or not
|
||||
if (IS_CONST_JUMP(i))
|
||||
table68k[i].cflow = fl_normal;
|
||||
#endif
|
||||
|
||||
// Fix flags used information for Scc, Bcc, TRAPcc, DBcc instructions
|
||||
int flags_used = table68k[i].flaglive;
|
||||
if ( (mnemo == i_Scc)
|
||||
|| (mnemo == i_Bcc)
|
||||
|| (mnemo == i_DBcc)
|
||||
|| (mnemo == i_TRAPcc)
|
||||
) {
|
||||
switch (table68k[i].cc) {
|
||||
// CC mask: XNZVC
|
||||
// 8421
|
||||
case 0: flags_used = 0x00; break; /* T */
|
||||
case 1: flags_used = 0x00; break; /* F */
|
||||
case 2: flags_used = 0x05; break; /* HI */
|
||||
case 3: flags_used = 0x05; break; /* LS */
|
||||
case 4: flags_used = 0x01; break; /* CC */
|
||||
case 5: flags_used = 0x01; break; /* CS */
|
||||
case 6: flags_used = 0x04; break; /* NE */
|
||||
case 7: flags_used = 0x04; break; /* EQ */
|
||||
case 8: flags_used = 0x02; break; /* VC */
|
||||
case 9: flags_used = 0x02; break; /* VS */
|
||||
case 10:flags_used = 0x08; break; /* PL */
|
||||
case 11:flags_used = 0x08; break; /* MI */
|
||||
case 12:flags_used = 0x0A; break; /* GE */
|
||||
case 13:flags_used = 0x0A; break; /* LT */
|
||||
case 14:flags_used = 0x0E; break; /* GT */
|
||||
case 15:flags_used = 0x0E; break; /* LE */
|
||||
}
|
||||
}
|
||||
|
||||
/* Unconditional jumps don't evaluate condition codes, so they
|
||||
don't actually use any flags themselves */
|
||||
if (IS_CONST_JUMP(i))
|
||||
flags_used = 0;
|
||||
|
||||
table68k[i].flaglive = flags_used;
|
||||
}
|
||||
}
|
||||
|
||||
static int mismatch;
|
||||
@ -766,6 +863,8 @@ static void handle_merges (long int opcode)
|
||||
smsk = 7; sbitdst = 8; break;
|
||||
case 5:
|
||||
smsk = 63; sbitdst = 64; break;
|
||||
case 6:
|
||||
smsk = 255; sbitdst = 256; break;
|
||||
case 7:
|
||||
smsk = 3; sbitdst = 4; break;
|
||||
default:
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifndef READCPU_H
|
||||
#define READCPU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -32,7 +35,8 @@ ENUMDECL {
|
||||
i_PACK, i_UNPK, i_TAS, i_BKPT, i_CALLM, i_RTM, i_TRAPcc, i_MOVES,
|
||||
i_FPP, i_FDBcc, i_FScc, i_FTRAPcc, i_FBcc, i_FSAVE, i_FRESTORE,
|
||||
i_CINVL, i_CINVP, i_CINVA, i_CPUSHL, i_CPUSHP, i_CPUSHA, i_MOVE16,
|
||||
i_MMUOP
|
||||
i_MMUOP,
|
||||
i_EMULOP_RETURN, i_EMULOP
|
||||
} ENUMNAME (instrmnem);
|
||||
|
||||
extern struct mnemolookup {
|
||||
@ -52,9 +56,21 @@ ENUMDECL {
|
||||
fu_used, fu_unused, fu_maybecc, fu_unknown, fu_isjmp
|
||||
} ENUMNAME (flaguse);
|
||||
|
||||
ENUMDECL {
|
||||
fl_normal = 0,
|
||||
fl_branch = 1,
|
||||
fl_jump = 2,
|
||||
fl_return = 3,
|
||||
fl_trap = 4,
|
||||
fl_compiled = 8,
|
||||
|
||||
/* Instructions that can trap don't mark the end of a block */
|
||||
fl_end_block = 3
|
||||
} ENUMNAME (cflow_t);
|
||||
|
||||
ENUMDECL {
|
||||
bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bitk, bitK,
|
||||
bits, bitS, bitd, bitD, bitr, bitR, bitz, bitp, lastbit
|
||||
bits, bitS, bitd, bitD, bitr, bitR, bitz, bitE, bitp, lastbit
|
||||
} ENUMNAME (bitvals);
|
||||
|
||||
struct instr_def {
|
||||
@ -68,6 +84,7 @@ struct instr_def {
|
||||
unsigned int flaguse:3;
|
||||
unsigned int flagset:3;
|
||||
} flaginfo[5];
|
||||
unsigned char cflow;
|
||||
unsigned char sduse;
|
||||
const char *opcstr;
|
||||
};
|
||||
@ -101,7 +118,8 @@ extern struct instr {
|
||||
unsigned int duse:1;
|
||||
unsigned int unused1:1;
|
||||
unsigned int clev:3;
|
||||
unsigned int unused2:5;
|
||||
unsigned int cflow:3;
|
||||
unsigned int unused2:2;
|
||||
} *table68k;
|
||||
|
||||
extern void read_table68k (void);
|
||||
@ -112,3 +130,5 @@ extern int nr_cpuop_funcs;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* READCPU_H */
|
||||
|
89
BasiliskII/src/uae_cpu/spcflags.h
Normal file
89
BasiliskII/src/uae_cpu/spcflags.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* UAE - The Un*x Amiga Emulator
|
||||
*
|
||||
* MC68000 emulation
|
||||
*
|
||||
* Copyright 1995 Bernd Schmidt
|
||||
*/
|
||||
|
||||
#ifndef SPCFLAGS_H
|
||||
#define SPCFLAGS_H
|
||||
|
||||
typedef uae_u32 spcflags_t;
|
||||
|
||||
enum {
|
||||
SPCFLAG_STOP = 0x01,
|
||||
SPCFLAG_INT = 0x02,
|
||||
SPCFLAG_BRK = 0x04,
|
||||
SPCFLAG_TRACE = 0x08,
|
||||
SPCFLAG_DOTRACE = 0x10,
|
||||
SPCFLAG_DOINT = 0x20,
|
||||
SPCFLAG_JIT_END_COMPILE = 0,
|
||||
SPCFLAG_JIT_EXEC_RETURN = 0,
|
||||
SPCFLAG_ALL = SPCFLAG_STOP
|
||||
| SPCFLAG_INT
|
||||
| SPCFLAG_BRK
|
||||
| SPCFLAG_TRACE
|
||||
| SPCFLAG_DOTRACE
|
||||
| SPCFLAG_DOINT
|
||||
| SPCFLAG_JIT_END_COMPILE
|
||||
| SPCFLAG_JIT_EXEC_RETURN,
|
||||
SPCFLAG_ALL_BUT_EXEC_RETURN = SPCFLAG_ALL & ~SPCFLAG_JIT_EXEC_RETURN
|
||||
};
|
||||
|
||||
#define SPCFLAGS_TEST(m) \
|
||||
((regs.spcflags & (m)) != 0)
|
||||
|
||||
/* Macro only used in m68k_reset() */
|
||||
#define SPCFLAGS_INIT(m) do { \
|
||||
regs.spcflags = (m); \
|
||||
} while (0)
|
||||
|
||||
#if !(ENABLE_EXCLUSIVE_SPCFLAGS)
|
||||
|
||||
#define SPCFLAGS_SET(m) do { \
|
||||
regs.spcflags |= (m); \
|
||||
} while (0)
|
||||
|
||||
#define SPCFLAGS_CLEAR(m) do { \
|
||||
regs.spcflags &= ~(m); \
|
||||
} while (0)
|
||||
|
||||
#elif defined(__i386__) && defined(X86_ASSEMBLY)
|
||||
|
||||
#define HAVE_HARDWARE_LOCKS
|
||||
|
||||
#define SPCFLAGS_SET(m) do { \
|
||||
__asm__ __volatile__("lock\n\torl %1,%0" : "=m" (regs.spcflags) : "i" ((m))); \
|
||||
} while (0)
|
||||
|
||||
#define SPCFLAGS_CLEAR(m) do { \
|
||||
__asm__ __volatile__("lock\n\tandl %1,%0" : "=m" (regs.spcflags) : "i" (~(m))); \
|
||||
} while (0)
|
||||
|
||||
#elif defined(HAVE_PTHREADS)
|
||||
|
||||
#undef HAVE_HARDWARE_LOCKS
|
||||
|
||||
#include <pthread.h>
|
||||
extern pthread_mutex_t spcflags_lock;
|
||||
|
||||
#define SPCFLAGS_SET(m) do { \
|
||||
pthread_mutex_lock(&spcflags_lock); \
|
||||
regs.spcflags |= (m); \
|
||||
pthread_mutex_unlock(&spcflags_lock); \
|
||||
} while (0)
|
||||
|
||||
#define SPCFLAGS_CLEAR(m) do { \
|
||||
pthread_mutex_lock(&spcflags_lock); \
|
||||
regs.spcflags &= ~(m); \
|
||||
pthread_mutex_unlock(&spcflags_lock); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#error "Can't handle spcflags atomically!"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SPCFLAGS_H */
|
@ -4,12 +4,13 @@
|
||||
% C: condition codes, except F
|
||||
% f: direction
|
||||
% i: immediate
|
||||
% E: immediate, except 00 (for EmulOp instructions)
|
||||
% I: immediate, except 00 and ff
|
||||
% j: immediate 1..8
|
||||
% J: immediate 0..15
|
||||
% k: immediate 0..7
|
||||
% K: immediate 0..63
|
||||
% p: immediate 0..3 (CINV and CPUSH: cache field)
|
||||
% p: immediate 0..3 (CINV and CPUSH instructions: Cache Field)
|
||||
% s: source mode
|
||||
% S: source reg
|
||||
% d: dest mode
|
||||
@ -25,7 +26,7 @@
|
||||
%
|
||||
% Arp: --> -(Ar)
|
||||
% ArP: --> (Ar)+
|
||||
% L: (xxx.L)
|
||||
% L: --> (xxx.L)
|
||||
%
|
||||
% Fields on a line:
|
||||
% 16 chars bitpattern :
|
||||
@ -45,10 +46,17 @@
|
||||
% 0 means flag reset
|
||||
% 1 means flag set
|
||||
% ? means programmer was too lazy to check or instruction may trap
|
||||
% + means instruction is conditional branch
|
||||
% everything else means flag set/used
|
||||
% / means instruction is unconditional branch/call
|
||||
% x means flag is unknown and well-behaved programs shouldn't check it
|
||||
%
|
||||
% Control flow
|
||||
% two letters, combination of
|
||||
% - nothing
|
||||
% T the instruction may trap or cause an exception
|
||||
% B branch instruction
|
||||
% J jump instruction
|
||||
% R return instruction
|
||||
%
|
||||
% srcaddr status destaddr status :
|
||||
% bitmasks of
|
||||
% 1 means fetched
|
||||
@ -58,204 +66,209 @@
|
||||
% instruction
|
||||
%
|
||||
|
||||
0000 0000 0011 1100:00:XNZVC:XNZVC:10: ORSR.B #1
|
||||
0000 0000 0111 1100:02:?????:?????:10: ORSR.W #1
|
||||
0000 0zz0 11ss sSSS:20:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0000 0000 zzdd dDDD:00:-NZ00:-----:13: OR.z #z,d[!Areg]
|
||||
0000 0010 0011 1100:00:XNZVC:XNZVC:10: ANDSR.B #1
|
||||
0000 0010 0111 1100:02:?????:?????:10: ANDSR.W #1
|
||||
0000 0010 zzdd dDDD:00:-NZ00:-----:13: AND.z #z,d[!Areg]
|
||||
0000 0100 zzdd dDDD:00:XNZVC:-----:13: SUB.z #z,d[!Areg]
|
||||
0000 0110 zzdd dDDD:00:XNZVC:-----:13: ADD.z #z,d[!Areg]
|
||||
0000 0110 11ss sSSS:20:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0000 0110 11ss sSSS:20:?????:?????:10: RTM s[Dreg,Areg]
|
||||
0000 1000 00ss sSSS:00:--Z--:-----:11: BTST #1,s[!Areg]
|
||||
0000 1000 01ss sSSS:00:--Z--:-----:13: BCHG #1,s[!Areg,Immd]
|
||||
0000 1000 10ss sSSS:00:--Z--:-----:13: BCLR #1,s[!Areg,Immd]
|
||||
0000 1000 11ss sSSS:00:--Z--:-----:13: BSET #1,s[!Areg,Immd]
|
||||
0000 1010 0011 1100:00:XNZVC:XNZVC:10: EORSR.B #1
|
||||
0000 1010 0111 1100:02:?????:?????:10: EORSR.W #1
|
||||
0000 1010 zzdd dDDD:00:-NZ00:-----:13: EOR.z #z,d[!Areg]
|
||||
0000 1100 zzss sSSS:00:-NZVC:-----:11: CMP.z #z,s[!Areg,Immd]
|
||||
0000 0000 0011 1100:00:XNZVC:XNZVC:--:10: ORSR.B #1
|
||||
0000 0000 0111 1100:02:XNZVC:XNZVC:T-:10: ORSR.W #1
|
||||
0000 0zz0 11ss sSSS:20:-?Z?C:-----:T-:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0000 0000 zzdd dDDD:00:-NZ00:-----:--:13: OR.z #z,d[!Areg]
|
||||
0000 0010 0011 1100:00:XNZVC:XNZVC:--:10: ANDSR.B #1
|
||||
0000 0010 0111 1100:02:XNZVC:XNZVC:T-:10: ANDSR.W #1
|
||||
0000 0010 zzdd dDDD:00:-NZ00:-----:--:13: AND.z #z,d[!Areg]
|
||||
0000 0100 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z #z,d[!Areg]
|
||||
0000 0110 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z #z,d[!Areg]
|
||||
0000 0110 11ss sSSS:20:-----:XNZVC:--:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0000 0110 11ss sSSS:20:XNZVC:-----:-R:10: RTM s[Dreg,Areg]
|
||||
0000 1000 00ss sSSS:00:--Z--:-----:--:11: BTST #1,s[!Areg]
|
||||
0000 1000 01ss sSSS:00:--Z--:-----:--:13: BCHG #1,s[!Areg,Immd]
|
||||
0000 1000 10ss sSSS:00:--Z--:-----:--:13: BCLR #1,s[!Areg,Immd]
|
||||
0000 1000 11ss sSSS:00:--Z--:-----:--:13: BSET #1,s[!Areg,Immd]
|
||||
0000 1010 0011 1100:00:XNZVC:XNZVC:--:10: EORSR.B #1
|
||||
0000 1010 0111 1100:02:XNZVC:XNZVC:T-:10: EORSR.W #1
|
||||
0000 1010 zzdd dDDD:00:-NZ00:-----:--:13: EOR.z #z,d[!Areg]
|
||||
0000 1100 zzss sSSS:00:-NZVC:-----:--:11: CMP.z #z,s[!Areg,Immd]
|
||||
|
||||
0000 1010 11ss sSSS:20:?????:?????:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1100 11ss sSSS:20:?????:?????:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1100 1111 1100:20:?????:?????:10: CAS2.W #2
|
||||
0000 1110 zzss sSSS:22:?????:?????:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1110 11ss sSSS:20:?????:?????:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1110 1111 1100:20:?????:?????:10: CAS2.L #2
|
||||
0000 1010 11ss sSSS:20:-NZVC:-----:--:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1100 11ss sSSS:20:-NZVC:-----:--:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1100 1111 1100:20:-NZVC:-----:--:10: CAS2.W #2
|
||||
0000 1110 zzss sSSS:22:-----:-----:T-:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1110 11ss sSSS:20:-NZVC:-----:--:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16]
|
||||
0000 1110 1111 1100:20:-NZVC:-----:--:10: CAS2.L #2
|
||||
|
||||
0000 rrr1 00dd dDDD:00:-----:-----:12: MVPMR.W d[Areg-Ad16],Dr
|
||||
0000 rrr1 01dd dDDD:00:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr
|
||||
0000 rrr1 10dd dDDD:00:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16]
|
||||
0000 rrr1 11dd dDDD:00:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16]
|
||||
0000 rrr1 00ss sSSS:00:--Z--:-----:11: BTST Dr,s[!Areg]
|
||||
0000 rrr1 01ss sSSS:00:--Z--:-----:13: BCHG Dr,s[!Areg,Immd]
|
||||
0000 rrr1 10ss sSSS:00:--Z--:-----:13: BCLR Dr,s[!Areg,Immd]
|
||||
0000 rrr1 11ss sSSS:00:--Z--:-----:13: BSET Dr,s[!Areg,Immd]
|
||||
0000 rrr1 00dd dDDD:00:-----:-----:--:12: MVPMR.W d[Areg-Ad16],Dr
|
||||
0000 rrr1 01dd dDDD:00:-----:-----:--:12: MVPMR.L d[Areg-Ad16],Dr
|
||||
0000 rrr1 10dd dDDD:00:-----:-----:--:12: MVPRM.W Dr,d[Areg-Ad16]
|
||||
0000 rrr1 11dd dDDD:00:-----:-----:--:12: MVPRM.L Dr,d[Areg-Ad16]
|
||||
0000 rrr1 00ss sSSS:00:--Z--:-----:--:11: BTST Dr,s[!Areg]
|
||||
0000 rrr1 01ss sSSS:00:--Z--:-----:--:13: BCHG Dr,s[!Areg,Immd]
|
||||
0000 rrr1 10ss sSSS:00:--Z--:-----:--:13: BCLR Dr,s[!Areg,Immd]
|
||||
0000 rrr1 11ss sSSS:00:--Z--:-----:--:13: BSET Dr,s[!Areg,Immd]
|
||||
|
||||
0001 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.B s,d[!Areg]
|
||||
0010 DDDd ddss sSSS:00:-----:-----:12: MOVEA.L s,d[Areg]
|
||||
0010 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.L s,d[!Areg]
|
||||
0011 DDDd ddss sSSS:00:-----:-----:12: MOVEA.W s,d[Areg]
|
||||
0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W s,d[!Areg]
|
||||
0001 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.B s,d[!Areg]
|
||||
0010 DDDd ddss sSSS:00:-----:-----:--:12: MOVEA.L s,d[Areg]
|
||||
0010 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.L s,d[!Areg]
|
||||
0011 DDDd ddss sSSS:00:-----:-----:--:12: MOVEA.W s,d[Areg]
|
||||
0011 DDDd ddss sSSS:00:-NZ00:-----:--:12: MOVE.W s,d[!Areg]
|
||||
|
||||
0100 0000 zzdd dDDD:00:XxZxC:X-Z--:30: NEGX.z d[!Areg]
|
||||
0100 0000 11dd dDDD:01:?????:?????:10: MVSR2.W d[!Areg]
|
||||
0100 0010 zzdd dDDD:00:-0100:-----:20: CLR.z d[!Areg]
|
||||
0100 0010 11dd dDDD:10:?????:?????:10: MVSR2.B d[!Areg]
|
||||
0100 0100 zzdd dDDD:00:XNZVC:-----:30: NEG.z d[!Areg]
|
||||
0100 0100 11ss sSSS:00:XNZVC:-----:10: MV2SR.B s[!Areg]
|
||||
0100 0110 zzdd dDDD:00:-NZ00:-----:30: NOT.z d[!Areg]
|
||||
0100 0110 11ss sSSS:02:?????:?????:10: MV2SR.W s[!Areg]
|
||||
0100 1000 0000 1rrr:20:-----:-----:31: LINK.L Ar,#2
|
||||
0100 1000 00dd dDDD:00:X?Z?C:X-Z--:30: NBCD.B d[!Areg]
|
||||
0100 1000 0100 1kkk:20:?????:?????:10: BKPT #k
|
||||
0100 1000 01ss sSSS:00:-NZ00:-----:30: SWAP.W s[Dreg]
|
||||
0100 1000 01ss sSSS:00:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0100 1000 10dd dDDD:00:-NZ00:-----:30: EXT.W d[Dreg]
|
||||
0100 1000 10dd dDDD:00:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
|
||||
0100 1000 11dd dDDD:00:-NZ00:-----:30: EXT.L d[Dreg]
|
||||
0100 1000 11dd dDDD:00:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
|
||||
0100 1001 11dd dDDD:00:-NZ00:-----:30: EXT.B d[Dreg]
|
||||
0100 1010 zzss sSSS:00:-NZ00:-----:10: TST.z s
|
||||
0100 1010 11dd dDDD:00:?????:?????:30: TAS.B d[!Areg]
|
||||
0100 1010 1111 1100:00:?????:?????:00: ILLEGAL
|
||||
0100 1100 00ss sSSS:20:-NZVC:-----:13: MULL.L #1,s[!Areg]
|
||||
0100 1100 01ss sSSS:20:?????:?????:13: DIVL.L #1,s[!Areg]
|
||||
0100 1100 10ss sSSS:00:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd]
|
||||
0100 1100 11ss sSSS:00:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
|
||||
0100 1110 0100 JJJJ:00:-----:XNZVC:10: TRAP #J
|
||||
0100 1110 0101 0rrr:00:-----:-----:31: LINK.W Ar,#1
|
||||
0100 1110 0101 1rrr:00:-----:-----:30: UNLK.L Ar
|
||||
0100 1110 0110 0rrr:02:-----:-----:10: MVR2USP.L Ar
|
||||
0100 1110 0110 1rrr:02:-----:-----:20: MVUSP2R.L Ar
|
||||
0100 1110 0111 0000:02:-----:-----:00: RESET
|
||||
0100 1110 0111 0001:00:-----:-----:00: NOP
|
||||
0100 1110 0111 0010:02:XNZVC:-----:10: STOP #1
|
||||
0100 1110 0111 0011:02:XNZVC:-----:00: RTE
|
||||
0100 1110 0111 0100:00:?????:?????:10: RTD #1
|
||||
0100 1110 0111 0101:00:-----:-----:00: RTS
|
||||
0100 1110 0111 0110:00:-----:XNZVC:00: TRAPV
|
||||
0100 1110 0111 0111:00:XNZVC:-----:00: RTR
|
||||
0100 1110 0111 1010:12:?????:?????:10: MOVEC2 #1
|
||||
0100 1110 0111 1011:12:?????:?????:10: MOVE2C #1
|
||||
0100 1110 10ss sSSS:00://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0100 rrr1 00ss sSSS:00:?????:?????:11: CHK.L s[!Areg],Dr
|
||||
0100 rrr1 10ss sSSS:00:?????:?????:11: CHK.W s[!Areg],Dr
|
||||
0100 1110 11ss sSSS:00://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0100 rrr1 11ss sSSS:00:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
|
||||
0100 0000 zzdd dDDD:00:XxZxC:X-Z--:--:30: NEGX.z d[!Areg]
|
||||
0100 0000 11dd dDDD:01:-----:XNZVC:T-:10: MVSR2.W d[!Areg]
|
||||
0100 0010 zzdd dDDD:00:-0100:-----:--:20: CLR.z d[!Areg]
|
||||
0100 0010 11dd dDDD:10:-----:XNZVC:--:10: MVSR2.B d[!Areg]
|
||||
0100 0100 zzdd dDDD:00:XNZVC:-----:--:30: NEG.z d[!Areg]
|
||||
0100 0100 11ss sSSS:00:XNZVC:-----:--:10: MV2SR.B s[!Areg]
|
||||
0100 0110 zzdd dDDD:00:-NZ00:-----:--:30: NOT.z d[!Areg]
|
||||
0100 0110 11ss sSSS:02:XNZVC:XNZVC:T-:10: MV2SR.W s[!Areg]
|
||||
0100 1000 0000 1rrr:20:-----:-----:--:31: LINK.L Ar,#2
|
||||
0100 1000 00dd dDDD:00:X?Z?C:X-Z--:--:30: NBCD.B d[!Areg]
|
||||
0100 1000 0100 1kkk:20:-----:-----:T-:10: BKPT #k
|
||||
0100 1000 01ss sSSS:00:-NZ00:-----:--:30: SWAP.W s[Dreg]
|
||||
0100 1000 01ss sSSS:00:-----:-----:--:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0100 1000 10dd dDDD:00:-NZ00:-----:--:30: EXT.W d[Dreg]
|
||||
0100 1000 10dd dDDD:00:-----:-----:--:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
|
||||
0100 1000 11dd dDDD:00:-NZ00:-----:--:30: EXT.L d[Dreg]
|
||||
0100 1000 11dd dDDD:00:-----:-----:--:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
|
||||
0100 1001 11dd dDDD:00:-NZ00:-----:--:30: EXT.B d[Dreg]
|
||||
0100 1010 zzss sSSS:00:-NZ00:-----:--:10: TST.z s
|
||||
0100 1010 11dd dDDD:00:-NZ00:-----:--:30: TAS.B d[!Areg]
|
||||
0100 1010 1111 1100:00:-----:-----:T-:00: ILLEGAL
|
||||
0100 1100 00ss sSSS:20:-NZVC:-----:--:13: MULL.L #1,s[!Areg]
|
||||
0100 1100 01ss sSSS:20:-NZV0:-----:T-:13: DIVL.L #1,s[!Areg]
|
||||
0100 1100 10ss sSSS:00:-----:-----:--:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd]
|
||||
0100 1100 11ss sSSS:00:-----:-----:--:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
|
||||
0100 1110 0100 JJJJ:00:-----:XNZVC:--:10: TRAP #J
|
||||
0100 1110 0101 0rrr:00:-----:-----:--:31: LINK.W Ar,#1
|
||||
0100 1110 0101 1rrr:00:-----:-----:--:30: UNLK.L Ar
|
||||
0100 1110 0110 0rrr:02:-----:-----:T-:10: MVR2USP.L Ar
|
||||
0100 1110 0110 1rrr:02:-----:-----:T-:20: MVUSP2R.L Ar
|
||||
0100 1110 0111 0000:02:-----:-----:T-:00: RESET
|
||||
0100 1110 0111 0001:00:-----:-----:--:00: NOP
|
||||
0100 1110 0111 0010:02:XNZVC:-----:T-:10: STOP #1
|
||||
0100 1110 0111 0011:02:XNZVC:-----:TR:00: RTE
|
||||
0100 1110 0111 0100:00:-----:-----:-R:10: RTD #1
|
||||
0100 1110 0111 0101:00:-----:-----:-R:00: RTS
|
||||
0100 1110 0111 0110:00:-----:XNZVC:T-:00: TRAPV
|
||||
0100 1110 0111 0111:00:XNZVC:-----:-R:00: RTR
|
||||
0100 1110 0111 1010:12:-----:-----:T-:10: MOVEC2 #1
|
||||
0100 1110 0111 1011:12:-----:-----:T-:10: MOVE2C #1
|
||||
0100 1110 10ss sSSS:00:-----:-----:-J:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0100 rrr1 00ss sSSS:00:-N???:-----:T-:11: CHK.L s[!Areg],Dr
|
||||
0100 rrr1 10ss sSSS:00:-N???:-----:T-:11: CHK.W s[!Areg],Dr
|
||||
0100 1110 11ss sSSS:00:-----:-----:-J:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd]
|
||||
0100 rrr1 11ss sSSS:00:-----:-----:--:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
|
||||
|
||||
0101 jjj0 01dd dDDD:00:-----:-----:13: ADDA.W #j,d[Areg]
|
||||
0101 jjj0 10dd dDDD:00:-----:-----:13: ADDA.L #j,d[Areg]
|
||||
0101 jjj0 zzdd dDDD:00:XNZVC:-----:13: ADD.z #j,d[!Areg]
|
||||
0101 jjj1 01dd dDDD:00:-----:-----:13: SUBA.W #j,d[Areg]
|
||||
0101 jjj1 10dd dDDD:00:-----:-----:13: SUBA.L #j,d[Areg]
|
||||
0101 jjj1 zzdd dDDD:00:XNZVC:-----:13: SUB.z #j,d[!Areg]
|
||||
0101 cccc 1100 1rrr:00:-----:-++++:31: DBcc.W Dr,#1
|
||||
0101 cccc 11dd dDDD:00:-----:-++++:20: Scc.B d[!Areg]
|
||||
0101 cccc 1111 1010:20:?????:?????:10: TRAPcc #1
|
||||
0101 cccc 1111 1011:20:?????:?????:10: TRAPcc #2
|
||||
0101 cccc 1111 1100:20:?????:?????:00: TRAPcc
|
||||
0101 jjj0 01dd dDDD:00:-----:-----:--:13: ADDA.W #j,d[Areg]
|
||||
0101 jjj0 10dd dDDD:00:-----:-----:--:13: ADDA.L #j,d[Areg]
|
||||
0101 jjj0 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z #j,d[!Areg]
|
||||
0101 jjj1 01dd dDDD:00:-----:-----:--:13: SUBA.W #j,d[Areg]
|
||||
0101 jjj1 10dd dDDD:00:-----:-----:--:13: SUBA.L #j,d[Areg]
|
||||
0101 jjj1 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z #j,d[!Areg]
|
||||
|
||||
0101 cccc 1100 1rrr:00:-----:-????:-B:31: DBcc.W Dr,#1
|
||||
0101 cccc 11dd dDDD:00:-----:-????:--:20: Scc.B d[!Areg]
|
||||
0101 cccc 1111 1010:20:-----:-????:T-:10: TRAPcc #1
|
||||
0101 cccc 1111 1011:20:-----:-????:T-:10: TRAPcc #2
|
||||
0101 cccc 1111 1100:20:-----:-????:T-:00: TRAPcc
|
||||
|
||||
% Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal
|
||||
% instruction exceptions when compiling a 68000 only emulation, which isn't
|
||||
% what we want either.
|
||||
0110 0001 0000 0000:00://///://///:40: BSR.W #1
|
||||
0110 0001 IIII IIII:00://///://///:40: BSR.B #i
|
||||
0110 0001 1111 1111:00://///://///:40: BSR.L #2
|
||||
0110 CCCC 0000 0000:00:-----:-++++:40: Bcc.W #1
|
||||
0110 CCCC IIII IIII:00:-----:-++++:40: Bcc.B #i
|
||||
0110 CCCC 1111 1111:00:-----:-++++:40: Bcc.L #2
|
||||
0110 0001 0000 0000:00:-----:-----:-B:40: BSR.W #1
|
||||
0110 0001 IIII IIII:00:-----:-----:-B:40: BSR.B #i
|
||||
0110 0001 1111 1111:00:-----:-----:-B:40: BSR.L #2
|
||||
0110 CCCC 0000 0000:00:-----:-????:-B:40: Bcc.W #1
|
||||
0110 CCCC IIII IIII:00:-----:-????:-B:40: Bcc.B #i
|
||||
0110 CCCC 1111 1111:00:-----:-????:-B:40: Bcc.L #2
|
||||
|
||||
0111 rrr0 iiii iiii:00:-NZ00:-----:12: MOVE.L #i,Dr
|
||||
0111 rrr0 iiii iiii:00:-NZ00:-----:--:12: MOVE.L #i,Dr
|
||||
|
||||
1000 rrr0 zzss sSSS:00:-NZ00:-----:13: OR.z s[!Areg],Dr
|
||||
1000 rrr0 11ss sSSS:00:?????:?????:13: DIVU.W s[!Areg],Dr
|
||||
1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr
|
||||
1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp
|
||||
1000 rrr1 zzdd dDDD:00:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg]
|
||||
1000 rrr1 01dd dDDD:20:?????:?????:12: PACK d[Dreg],Dr
|
||||
1000 rrr1 01dd dDDD:20:?????:?????:12: PACK d[Areg-Apdi],Arp
|
||||
1000 rrr1 10dd dDDD:20:?????:?????:12: UNPK d[Dreg],Dr
|
||||
1000 rrr1 10dd dDDD:20:?????:?????:12: UNPK d[Areg-Apdi],Arp
|
||||
1000 rrr1 11ss sSSS:00:?????:?????:13: DIVS.W s[!Areg],Dr
|
||||
1000 rrr0 zzss sSSS:00:-NZ00:-----:--:13: OR.z s[!Areg],Dr
|
||||
1000 rrr0 11ss sSSS:00:-NZV0:-----:T-:13: DIVU.W s[!Areg],Dr
|
||||
1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:--:13: SBCD.B d[Dreg],Dr
|
||||
1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:--:13: SBCD.B d[Areg-Apdi],Arp
|
||||
1000 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: OR.z Dr,d[!Areg,Dreg]
|
||||
1000 rrr1 01dd dDDD:20:-----:-----:--:12: PACK d[Dreg],Dr
|
||||
1000 rrr1 01dd dDDD:20:-----:-----:--:12: PACK d[Areg-Apdi],Arp
|
||||
1000 rrr1 10dd dDDD:20:-----:-----:--:12: UNPK d[Dreg],Dr
|
||||
1000 rrr1 10dd dDDD:20:-----:-----:--:12: UNPK d[Areg-Apdi],Arp
|
||||
1000 rrr1 11ss sSSS:00:-NZV0:-----:T-:13: DIVS.W s[!Areg],Dr
|
||||
|
||||
1001 rrr0 zzss sSSS:00:XNZVC:-----:13: SUB.z s,Dr
|
||||
1001 rrr0 11ss sSSS:00:-----:-----:13: SUBA.W s,Ar
|
||||
1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr
|
||||
1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp
|
||||
1001 rrr1 zzdd dDDD:00:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg]
|
||||
1001 rrr1 11ss sSSS:00:-----:-----:13: SUBA.L s,Ar
|
||||
1001 rrr0 zzss sSSS:00:XNZVC:-----:--:13: SUB.z s,Dr
|
||||
1001 rrr0 11ss sSSS:00:-----:-----:--:13: SUBA.W s,Ar
|
||||
1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: SUBX.z d[Dreg],Dr
|
||||
1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: SUBX.z d[Areg-Apdi],Arp
|
||||
1001 rrr1 zzdd dDDD:00:XNZVC:-----:--:13: SUB.z Dr,d[!Areg,Dreg]
|
||||
1001 rrr1 11ss sSSS:00:-----:-----:--:13: SUBA.L s,Ar
|
||||
|
||||
1011 rrr0 zzss sSSS:00:-NZVC:-----:11: CMP.z s,Dr
|
||||
1011 rrr0 11ss sSSS:00:-NZVC:-----:11: CMPA.W s,Ar
|
||||
1011 rrr1 11ss sSSS:00:-NZVC:-----:11: CMPA.L s,Ar
|
||||
1011 rrr1 zzdd dDDD:00:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP
|
||||
1011 rrr1 zzdd dDDD:00:-NZ00:-----:13: EOR.z Dr,d[!Areg]
|
||||
1011 rrr0 zzss sSSS:00:-NZVC:-----:--:11: CMP.z s,Dr
|
||||
1011 rrr0 11ss sSSS:00:-NZVC:-----:--:11: CMPA.W s,Ar
|
||||
1011 rrr1 11ss sSSS:00:-NZVC:-----:--:11: CMPA.L s,Ar
|
||||
1011 rrr1 zzdd dDDD:00:-NZVC:-----:--:11: CMPM.z d[Areg-Aipi],ArP
|
||||
1011 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: EOR.z Dr,d[!Areg]
|
||||
|
||||
1100 rrr0 zzss sSSS:00:-NZ00:-----:13: AND.z s[!Areg],Dr
|
||||
1100 rrr0 11ss sSSS:00:-NZ00:-----:13: MULU.W s[!Areg],Dr
|
||||
1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr
|
||||
1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp
|
||||
1100 rrr1 zzdd dDDD:00:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg]
|
||||
1100 rrr1 01dd dDDD:00:-----:-----:33: EXG.L Dr,d[Dreg]
|
||||
1100 rrr1 01dd dDDD:00:-----:-----:33: EXG.L Ar,d[Areg]
|
||||
1100 rrr1 10dd dDDD:00:-----:-----:33: EXG.L Dr,d[Areg]
|
||||
1100 rrr1 11ss sSSS:00:-NZ00:-----:13: MULS.W s[!Areg],Dr
|
||||
1100 rrr0 zzss sSSS:00:-NZ00:-----:--:13: AND.z s[!Areg],Dr
|
||||
1100 rrr0 11ss sSSS:00:-NZ00:-----:--:13: MULU.W s[!Areg],Dr
|
||||
1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:--:13: ABCD.B d[Dreg],Dr
|
||||
1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:--:13: ABCD.B d[Areg-Apdi],Arp
|
||||
1100 rrr1 zzdd dDDD:00:-NZ00:-----:--:13: AND.z Dr,d[!Areg,Dreg]
|
||||
1100 rrr1 01dd dDDD:00:-----:-----:--:33: EXG.L Dr,d[Dreg]
|
||||
1100 rrr1 01dd dDDD:00:-----:-----:--:33: EXG.L Ar,d[Areg]
|
||||
1100 rrr1 10dd dDDD:00:-----:-----:--:33: EXG.L Dr,d[Areg]
|
||||
1100 rrr1 11ss sSSS:00:-NZ00:-----:--:13: MULS.W s[!Areg],Dr
|
||||
|
||||
1101 rrr0 zzss sSSS:00:XNZVC:-----:13: ADD.z s,Dr
|
||||
1101 rrr0 11ss sSSS:00:-----:-----:13: ADDA.W s,Ar
|
||||
1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr
|
||||
1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp
|
||||
1101 rrr1 zzdd dDDD:00:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg]
|
||||
1101 rrr1 11ss sSSS:00:-----:-----:13: ADDA.L s,Ar
|
||||
1101 rrr0 zzss sSSS:00:XNZVC:-----:--:13: ADD.z s,Dr
|
||||
1101 rrr0 11ss sSSS:00:-----:-----:--:13: ADDA.W s,Ar
|
||||
1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: ADDX.z d[Dreg],Dr
|
||||
1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:--:13: ADDX.z d[Areg-Apdi],Arp
|
||||
1101 rrr1 zzdd dDDD:00:XNZVC:-----:--:13: ADD.z Dr,d[!Areg,Dreg]
|
||||
1101 rrr1 11ss sSSS:00:-----:-----:--:13: ADDA.L s,Ar
|
||||
|
||||
1110 jjjf zz00 0RRR:00:XNZVC:-----:13: ASf.z #j,DR
|
||||
1110 jjjf zz00 1RRR:00:XNZ0C:-----:13: LSf.z #j,DR
|
||||
1110 jjjf zz01 0RRR:00:XNZ0C:X----:13: ROXf.z #j,DR
|
||||
1110 jjjf zz01 1RRR:00:-NZ0C:-----:13: ROf.z #j,DR
|
||||
1110 rrrf zz10 0RRR:00:XNZVC:X----:13: ASf.z Dr,DR
|
||||
1110 rrrf zz10 1RRR:00:XNZ0C:X----:13: LSf.z Dr,DR
|
||||
1110 rrrf zz11 0RRR:00:XNZ0C:X----:13: ROXf.z Dr,DR
|
||||
1110 rrrf zz11 1RRR:00:-NZ0C:-----:13: ROf.z Dr,DR
|
||||
1110 000f 11dd dDDD:00:XNZVC:-----:13: ASfW.W d[!Dreg,Areg]
|
||||
1110 001f 11dd dDDD:00:XNZ0C:-----:13: LSfW.W d[!Dreg,Areg]
|
||||
1110 010f 11dd dDDD:00:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg]
|
||||
1110 011f 11dd dDDD:00:-NZ0C:-----:13: ROfW.W d[!Dreg,Areg]
|
||||
1110 jjjf zz00 0RRR:00:XNZVC:-----:--:13: ASf.z #j,DR
|
||||
1110 jjjf zz00 1RRR:00:XNZ0C:-----:--:13: LSf.z #j,DR
|
||||
1110 jjjf zz01 0RRR:00:XNZ0C:X----:--:13: ROXf.z #j,DR
|
||||
1110 jjjf zz01 1RRR:00:-NZ0C:-----:--:13: ROf.z #j,DR
|
||||
1110 rrrf zz10 0RRR:00:XNZVC:-----:--:13: ASf.z Dr,DR
|
||||
1110 rrrf zz10 1RRR:00:XNZ0C:-----:--:13: LSf.z Dr,DR
|
||||
1110 rrrf zz11 0RRR:00:XNZ0C:X----:--:13: ROXf.z Dr,DR
|
||||
1110 rrrf zz11 1RRR:00:-NZ0C:-----:--:13: ROf.z Dr,DR
|
||||
1110 000f 11dd dDDD:00:XNZVC:-----:--:13: ASfW.W d[!Dreg,Areg]
|
||||
1110 001f 11dd dDDD:00:XNZ0C:-----:--:13: LSfW.W d[!Dreg,Areg]
|
||||
1110 010f 11dd dDDD:00:XNZ0C:X----:--:13: ROXfW.W d[!Dreg,Areg]
|
||||
1110 011f 11dd dDDD:00:-NZ0C:-----:--:13: ROfW.W d[!Dreg,Areg]
|
||||
|
||||
1110 1000 11ss sSSS:20:?????:?????:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1001 11ss sSSS:20:?????:?????:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1010 11ss sSSS:20:?????:?????:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1011 11ss sSSS:20:?????:?????:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1100 11ss sSSS:20:?????:?????:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1101 11ss sSSS:20:?????:?????:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1110 11ss sSSS:20:?????:?????:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1111 11ss sSSS:20:?????:?????:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1000 11ss sSSS:20:-NZ00:-----:--:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1001 11ss sSSS:20:-NZ00:-----:--:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1010 11ss sSSS:20:-NZ00:-----:--:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1011 11ss sSSS:20:-NZ00:-----:--:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1100 11ss sSSS:20:-NZ00:-----:--:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1101 11ss sSSS:20:-NZ00:-----:--:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd]
|
||||
1110 1110 11ss sSSS:20:-NZ00:-----:--:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
1110 1111 11ss sSSS:20:-NZ00:-----:--:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16]
|
||||
|
||||
% floating point co processor
|
||||
1111 0010 00ss sSSS:30:?????:?????:11: FPP #1,s
|
||||
1111 0010 01ss sSSS:30:?????:?????:11: FDBcc #1,s[Areg-Dreg]
|
||||
1111 0010 01ss sSSS:30:?????:?????:11: FScc #1,s[!Areg,Immd,PC8r,PC16]
|
||||
1111 0010 0111 1010:30:?????:?????:10: FTRAPcc #1
|
||||
1111 0010 0111 1011:30:?????:?????:10: FTRAPcc #2
|
||||
1111 0010 0111 1100:30:?????:?????:00: FTRAPcc
|
||||
1111 0010 10KK KKKK:30:?????:?????:11: FBcc #K,#1
|
||||
1111 0010 11KK KKKK:30:?????:?????:11: FBcc #K,#2
|
||||
1111 0011 00ss sSSS:32:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
|
||||
1111 0011 01ss sSSS:32:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
|
||||
1111 0010 00ss sSSS:30:-----:-----:--:11: FPP #1,s
|
||||
1111 0010 01ss sSSS:30:-----:-----:-B:11: FDBcc #1,s[Areg-Dreg]
|
||||
1111 0010 01ss sSSS:30:-----:-----:--:11: FScc #1,s[!Areg,Immd,PC8r,PC16]
|
||||
1111 0010 0111 1010:30:-----:-----:T-:10: FTRAPcc #1
|
||||
1111 0010 0111 1011:30:-----:-----:T-:10: FTRAPcc #2
|
||||
1111 0010 0111 1100:30:-----:-----:T-:00: FTRAPcc
|
||||
1111 0010 10KK KKKK:30:-----:-----:-B:11: FBcc #K,#1
|
||||
1111 0010 11KK KKKK:30:-----:-----:-B:11: FBcc #K,#2
|
||||
1111 0011 00ss sSSS:32:-----:-----:--:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16]
|
||||
1111 0011 01ss sSSS:32:-----:-----:--:10: FRESTORE s[!Dreg,Areg,Apdi,Immd]
|
||||
|
||||
% 68040 instructions
|
||||
1111 0101 iiii iSSS:40:?????:?????:11: MMUOP #i,s
|
||||
1111 0100 pp00 1rrr:42:-----:-----:02: CINVL #p,Ar
|
||||
1111 0100 pp01 0rrr:42:-----:-----:02: CINVP #p,Ar
|
||||
1111 0100 pp01 1rrr:42:-----:-----:00: CINVA #p
|
||||
1111 0100 pp10 1rrr:42:-----:-----:02: CPUSHL #p,Ar
|
||||
1111 0100 pp11 0rrr:42:-----:-----:02: CPUSHP #p,Ar
|
||||
1111 0100 pp11 1rrr:42:-----:-----:00: CPUSHA #p
|
||||
1111 0101 iiii iSSS:40:-----:-----:T-:11: MMUOP #i,s
|
||||
1111 0100 pp00 1rrr:42:-----:-----:T-:02: CINVL #p,Ar
|
||||
1111 0100 pp01 0rrr:42:-----:-----:T-:02: CINVP #p,Ar
|
||||
1111 0100 pp01 1rrr:42:-----:-----:T-:00: CINVA #p
|
||||
1111 0100 pp10 1rrr:42:-----:-----:T-:02: CPUSHL #p,Ar
|
||||
1111 0100 pp11 0rrr:42:-----:-----:T-:02: CPUSHP #p,Ar
|
||||
1111 0100 pp11 1rrr:42:-----:-----:T-:00: CPUSHA #p
|
||||
% destination register number is encoded in the following word
|
||||
1111 0110 0010 0rrr:40:-----:-----:12: MOVE16 ArP,AxP
|
||||
1111 0110 00ss sSSS:40:-----:-----:12: MOVE16 s[Dreg-Aipi],L
|
||||
1111 0110 00dd dDDD:40:-----:-----:12: MOVE16 L,d[Areg-Aipi]
|
||||
1111 0110 00ss sSSS:40:-----:-----:12: MOVE16 s[Aind],L
|
||||
1111 0110 00dd dDDD:40:-----:-----:12: MOVE16 L,d[Aipi-Aind]
|
||||
1111 0110 0010 0rrr:40:-----:-----:--:12: MOVE16 ArP,AxP
|
||||
1111 0110 00ss sSSS:40:-----:-----:--:12: MOVE16 s[Dreg-Aipi],L
|
||||
1111 0110 00dd dDDD:40:-----:-----:--:12: MOVE16 L,d[Areg-Aipi]
|
||||
1111 0110 00ss sSSS:40:-----:-----:--:12: MOVE16 s[Aind],L
|
||||
1111 0110 00dd dDDD:40:-----:-----:--:12: MOVE16 L,d[Aipi-Aind]
|
||||
|
||||
% EmulOp instructions
|
||||
0111 0001 0000 0000:00:-----:-----:-R:00: EMULOP_RETURN
|
||||
0111 0001 EEEE EEEE:00:-----:-----:-J:10: EMULOP #E
|
||||
|
Loading…
Reference in New Issue
Block a user