]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
CPU tester updates and undocumented flag fixes (68020 ABCD, NBCD, SBCD, CHK, CHK2...
authorToni Wilen <twilen@winuae.net>
Sun, 11 Aug 2019 19:02:21 +0000 (22:02 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 11 Aug 2019 19:02:21 +0000 (22:02 +0300)
25 files changed:
cputest.cpp
cputest/adis/decode_ea.c [new file with mode: 0644]
cputest/adis/defs.h [new file with mode: 0644]
cputest/adis/globals.c [new file with mode: 0644]
cputest/adis/opcode_handler_cpu.c [new file with mode: 0644]
cputest/adis/opcode_handler_fpu.c [new file with mode: 0644]
cputest/adis/opcode_handler_mmu.c [new file with mode: 0644]
cputest/adis/opcodes_cpu.c [new file with mode: 0644]
cputest/adis/opcodes_fpu.c [new file with mode: 0644]
cputest/adis/opcodes_mmu.c [new file with mode: 0644]
cputest/adis/string_recog.h [new file with mode: 0644]
cputest/adis/util.c [new file with mode: 0644]
cputest/asm.S
cputest/cputestgen.ini
cputest/main.c
cputest/makefile
cputest_support.cpp
disasm.cpp
fpp.cpp
gencpu.cpp
include/fpp.h
include/newcpu.h
newcpu.cpp
newcpu_common.cpp
readcpu.cpp

index 003a6583970879973a2022744adf2c4fccdff256..a90002f5f84c7256e79b0c876940eef17ae7d97d 100644 (file)
@@ -4,6 +4,7 @@
 #include "readcpu.h"
 #include "disasm.h"
 #include "ini.h"
+#include "fpp.h"
 
 #include "options.h"
 
@@ -30,7 +31,6 @@ static uae_u32 registers[] =
        0x00000000  // replaced with stack
 };
 
-// TODO: fill FPU registers
 static floatx80 fpuregisters[8];
 static uae_u32 fpu_fpiar, fpu_fpcr, fpu_fpsr;
 
@@ -62,7 +62,6 @@ static int feature_full_extension_format = 0;
 static uae_u32 feature_addressing_modes[2];
 static int ad8r[2], pc8r[2];
 
-#define LOW_MEMORY_END 0x8000
 #define HIGH_MEMORY_START (0x01000000 - 0x8000)
 
 // large enough for RTD
@@ -75,9 +74,11 @@ static uae_u32 test_low_memory_start;
 static uae_u32 test_low_memory_end;
 static uae_u32 test_high_memory_start;
 static uae_u32 test_high_memory_end;
+static uae_u32 low_memory_size = 32768;
+static uae_u32 high_memory_size = 32768;
 
-static uae_u8 low_memory[32768], high_memory[32768], *test_memory;
-static uae_u8 low_memory_temp[32768], high_memory_temp[32768], *test_memory_temp;
+static uae_u8 *low_memory, *high_memory, *test_memory;
+static uae_u8 *low_memory_temp, *high_memory_temp, *test_memory_temp;
 static uae_u8 dummy_memory[4];
 static uaecptr test_memory_start, test_memory_end, opcode_memory_start;
 static uae_u32 test_memory_size;
@@ -131,7 +132,7 @@ static bool valid_address(uaecptr addr, int size, int w)
 {
        addr &= addressing_mask;
        size--;
-       if (addr + size < LOW_MEMORY_END) {
+       if (addr + size < low_memory_size) {
                if (addr < test_low_memory_start || test_low_memory_start == 0xffffffff)
                        goto oob;
                // exception vectors needed during tests
@@ -181,7 +182,7 @@ static uae_u8 *get_addr(uaecptr addr, int size, int w)
        }
        addr &= addressing_mask;
        size--;
-       if (addr + size < LOW_MEMORY_END) {
+       if (addr + size < low_memory_size) {
                return low_memory + addr;
        } else if (addr >= HIGH_MEMORY_START && addr < HIGH_MEMORY_START + 0x8000) {
                return high_memory + (addr - HIGH_MEMORY_START);
@@ -202,29 +203,6 @@ oob:
        return dummy_memory;
 }
 
-uae_u32 REGPARAM2 op_illg_1(uae_u32 opcode)
-{
-       if ((opcode & 0xf000) == 0xf000)
-               test_exception = 11;
-       else if ((opcode & 0xf000) == 0xa000)
-               test_exception = 10;
-       else
-               test_exception = 4;
-       return 0;
-}
-uae_u32 REGPARAM2 op_unimpl_1(uae_u32 opcode)
-{
-       return 0;
-}
-void REGPARAM2 op_unimpl(uae_u32 opcode)
-{
-       op_unimpl_1(opcode);
-}
-uae_u32 REGPARAM2 op_illg(uae_u32 opcode)
-{
-       return op_illg_1(opcode);
-}
-
 uae_u16 get_word_test_prefetch(int o)
 {
        // no real prefetch
@@ -429,6 +407,19 @@ uae_u32 sfc_nommu_get_long(uaecptr addr)
        return get_long_test(addr);
 }
 
+void dfc_nommu_put_byte(uaecptr addr, uae_u32 v)
+{
+       put_byte_test(addr, v);
+}
+void dfc_nommu_put_word(uaecptr addr, uae_u32 v)
+{
+       put_word_test(addr, v);
+}
+void dfc_nommu_put_long(uaecptr addr, uae_u32 v)
+{
+       put_long_test(addr, v);
+}
+
 uae_u32 memory_get_byte(uaecptr addr)
 {
        return get_byte_test(addr);
@@ -686,8 +677,26 @@ static void doexcstack(void)
                        mode |= test_exception_3_w ? 0 : 16;
                        Exception_build_68000_address_error_stack_frame(mode, opcode, test_exception_addr, regs.pc);
                }
-       } else if (cpu_lvl > 0) {
-               Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
+       } else if (cpu_lvl == 1) {
+               if (test_exception == 3) {
+                       uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1);
+                       ssw |= test_exception_3_w ? 0 : 0x100;
+                       ssw |= test_exception_3_inst ? 0 : 0x2000;
+                       regs.mmu_fault_addr = test_exception_addr;
+                       Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x08);
+               } else {
+                       Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
+               }
+       } else if (cpu_lvl == 2) {
+               if (test_exception == 3) {
+                       uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1);
+                       ssw |= test_exception_3_w ? 0 : 0x40;
+                       ssw |= 0x20;
+                       regs.mmu_fault_addr = test_exception_addr;
+                       Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x0a);
+               } else {
+                       Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
+               }
        }
        exception_stack_frame_size = test_memory_end + EXTRA_RESERVED_SPACE - m68k_areg(regs, 7);
 
@@ -696,6 +705,35 @@ static void doexcstack(void)
        noaccesshistory = noac;
 }
 
+uae_u32 REGPARAM2 op_illg_1(uae_u32 opcode)
+{
+       if ((opcode & 0xf000) == 0xf000)
+               test_exception = 11;
+       else if ((opcode & 0xf000) == 0xa000)
+               test_exception = 10;
+       else
+               test_exception = 4;
+       doexcstack();
+       return 0;
+}
+void REGPARAM2 op_unimpl(uae_u32 opcode)
+{
+       test_exception = 61;
+       doexcstack();
+}
+uae_u32 REGPARAM2 op_unimpl_1(uae_u32 opcode)
+{
+       if ((opcode & 0xf000) == 0xf000 || currprefs.cpu_model < 68060)
+               op_illg(opcode);
+       else
+               op_unimpl(opcode);
+       return 0;
+}
+uae_u32 REGPARAM2 op_illg(uae_u32 opcode)
+{
+       return op_illg_1(opcode);
+}
+
 void exception3_read(uae_u32 opcode, uae_u32 addr)
 {
        test_exception = 3;
@@ -869,8 +907,8 @@ static void fill_memory_buffer(uae_u8 *p, int size)
 
 static void fill_memory(void)
 {
-       fill_memory_buffer(low_memory_temp, 32768);
-       fill_memory_buffer(high_memory_temp, 32768);
+       fill_memory_buffer(low_memory_temp, low_memory_size);
+       fill_memory_buffer(high_memory_temp, high_memory_size);
        fill_memory_buffer(test_memory_temp, test_memory_size);
 }
 
@@ -905,7 +943,7 @@ static uae_u8 *store_rel(uae_u8 *dst, uae_u8 mode, uae_u32 s, uae_u32 d, int ord
                *dst++ = mode | CT_RELATIVE_START_WORD;
                *dst++ = (diff >> 8) & 0xff;
                *dst++ = diff & 0xff;
-       } else if (d < LOW_MEMORY_END) {
+       } else if (d < 0x8000) {
                *dst++ = mode | CT_ABSOLUTE_WORD;
                *dst++ = (d >> 8) & 0xff;
                *dst++ = d & 0xff;
@@ -1012,7 +1050,7 @@ static uae_u8 *store_mem(uae_u8 *dst, int storealways)
                        continue;
                uaecptr addr = ah->addr;
                addr &= addressing_mask;
-               if (addr < LOW_MEMORY_END) {
+               if (addr < 0x8000) {
                        *dst++ = CT_MEMWRITE | CT_ABSOLUTE_WORD;
                        *dst++ = (addr >> 8) & 0xff;
                        *dst++ = addr & 0xff;
@@ -1054,6 +1092,10 @@ static uae_u32 gl(uae_u8 *p)
 {
        return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
 }
+static uae_u32 gw(uae_u8 *p)
+{
+       return (p[0] << 8) | (p[1] << 0);
+}
 
 static bool load_file(const TCHAR *path, const TCHAR *file, uae_u8 *p, int size, int offset)
 {
@@ -1397,6 +1439,19 @@ static int create_ea(uae_u16 *opcodep, uaecptr pc, int mode, int reg, struct ins
 
 static int imm_special;
 
+static int handle_specials_preea(uae_u16 opcode, uaecptr pc, struct instr *dp)
+{
+       if (dp->mnemo == i_FTRAPcc) {
+               uae_u16 v = rand16();
+               v &= ~7;
+               v |= imm_special;
+               put_word_test(pc, v);
+               imm_special++;
+               return 2;
+       }
+       return 0;
+}
+
 static int handle_specials_branch(uae_u16 opcode, uaecptr pc, struct instr *dp, int *isconstant)
 {
        // 68020 BCC.L is BCC.B to odd address if 68000/010
@@ -1405,6 +1460,12 @@ static int handle_specials_branch(uae_u16 opcode, uaecptr pc, struct instr *dp,
                        return 0;
                }
                return -2;
+       } else if (dp->mnemo == i_FDBcc) {
+               // FDBcc jump offset
+               uae_u16 v = rand16();
+               put_word_test(pc, v);
+               *isconstant = 16;
+               return 2;
        }
        return 0;
 }
@@ -1421,16 +1482,65 @@ static int handle_specials_pack(uae_u16 opcode, uaecptr pc, struct instr *dp, in
        return 0;
 }
 
+static void handle_specials_extra(uae_u16 opcode, uaecptr pc, struct instr *dp)
+{
+       // if MOVES to A7: change it to MOVES from A7. SSP modification would cause crash.
+       if (dp->mnemo == i_MOVES) {
+               uae_u16 extra = get_word_test(opcode_memory_start + 2);
+               if (!(extra & 0x800)) {
+                       int reg = extra >> 12;
+                       if (reg == 7 + 8) {
+                               extra |= 0x800;
+                               put_word_test(opcode_memory_start + 2, extra);
+                       }
+               }
+       }
+       // cas undocumented (marked as zero in document) fields do something weird, for example
+       // setting bit 9 will make "Du" address register but results are not correct.
+       // so lets make sure unused zero bits are zeroed.
+       if (dp->mnemo == i_CAS) {
+               uae_u16 extra = get_word_test(opcode_memory_start + 2);
+               uae_u16 extra2 = extra;
+               extra &= (7 << 6) | (7 << 0);
+               if (extra != extra2) {
+                       put_word_test(opcode_memory_start + 2, extra);
+               }
+       }
+       if (dp->mnemo == i_CAS2) {
+               uae_u16 extra = get_word_test(opcode_memory_start + 2);
+               uae_u16 extra2 = extra;
+               extra &= (7 << 6) | (7 << 0) | (15 << 12);
+               if (extra != extra2) {
+                       put_word_test(opcode_memory_start + 2, extra);
+               }
+               extra = get_word_test(opcode_memory_start + 4);
+               extra2 = extra;
+               extra &= (7 << 6) | (7 << 0) | (15 << 12);
+               if (extra != extra2) {
+                       put_word_test(opcode_memory_start + 4, extra);
+               }
+
+       }
+       if (dp->mnemo == i_CHK2) {
+               uae_u16 extra = get_word_test(opcode_memory_start + 2);
+               uae_u16 extra2 = extra;
+               extra &= (15 << 12);
+               if (extra != extra2) {
+                       put_word_test(opcode_memory_start + 2, extra);
+               }
+
+       }
+}
 
 static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, int *isconstant)
 {
        int offset = 0;
-       if (opcode == 0x4e73 || opcode == 0x4e74 || opcode == 0x4e75 || opcode == 0x4e77) {
+       if (dp->mnemo == i_RTE || dp->mnemo == i_RTD || dp->mnemo == i_RTS || dp->mnemo == i_RTR || dp->mnemo == i_UNLK) {
                uae_u32 v;
                uaecptr addr = regs.regs[8 + 7];
                imm_special++;
                // RTE, RTD, RTS and RTR
-               if (opcode == 0x4e77) {
+               if (dp->mnemo == i_RTR) {
                        // RTR
                        v = imm_special;
                        uae_u16 ccr = v & 31;
@@ -1439,14 +1549,14 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i
                        addr += 2;
                        offset += 2;
                        *isconstant = imm_special >= (1 << (0 + 5)) * 4 ? 0 : -1;
-               } else if (opcode == 0x4e74) {
+               } else if (dp->mnemo == i_RTD) {
                        // RTD
                        v = imm_special >> 2;
                        uae_u16 sr = v & 31;
                        sr |= (v >> 5) << 12;
                        put_word_test(addr + 4, sr);
                        *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1;
-               } else if (opcode == 0x4e73) {
+               } else if (dp->mnemo == i_RTE) {
                        // RTE
                        if (currprefs.cpu_model == 68000) {
                                v = imm_special >> 2;
@@ -1459,7 +1569,7 @@ static int handle_specials_stack(uae_u16 opcode, uaecptr pc, struct instr *dp, i
                                // TODO 68010+ RTE
                        }
                        *isconstant = imm_special >= (1 << (4 + 5)) * 4 ? 0 : -1;
-               } else if (opcode == 0x4e75) {
+               } else if (dp->mnemo == i_RTS) {
                        // RTS
                        *isconstant = imm_special >= 256 ? 0 : -1;
                }
@@ -1495,6 +1605,8 @@ static void execute_ins(uae_u16 opc, uaecptr endpc, uaecptr targetpc)
                && opw2 == 0x9908
                )
                printf("");
+       if (regs.sr & 0x2000)
+               printf("");
 
        // execute instruction
        SPCFLAG_TRACE = 0;
@@ -1581,9 +1693,8 @@ static int isbranchinst(struct instr *dp)
                return 2;
        case i_DBcc:
        case i_FBcc:
-               return -1;
        case i_FDBcc:
-               return 1;
+               return -1;
        }
        return 0;
 }
@@ -1610,6 +1721,8 @@ static int isunsupported(struct instr *dp)
        {
        case i_MOVE2C:
        case i_MOVEC2:
+       case i_FSAVE:
+       case i_FRESTORE:
                return 1;
        case i_RTE:
                if (cpu_lvl > 0)
@@ -1623,7 +1736,7 @@ static int isunsupported(struct instr *dp)
 static uae_u8 last_exception[256];
 static int last_exception_len;
 
-static uae_u8 *save_exception(uae_u8 *p)
+static uae_u8 *save_exception(uae_u8 *p, struct instr *dp)
 {
        uae_u8 *op = p;
        p++;
@@ -1637,6 +1750,7 @@ static uae_u8 *save_exception(uae_u8 *p)
                        p = store_rel(p, 0, opcode_memory_start, gl(sf + 2), 1);
                }
        } else if (cpu_lvl > 0) {
+               uae_u8 ccrmask = 0;
                uae_u16 frame = (sf[6] << 8) | sf[7];
                // frame + vector offset
                *p++ = sf[6];
@@ -1653,12 +1767,19 @@ static uae_u8 *save_exception(uae_u8 *p)
                        // effective address
                        p = store_rel(p, 0, opcode_memory_start, gl(sf + 8), 1);
                        break;
-               case 8:
+               case 4: // floating point unimplemented (68040/060)
                        // fault/effective address
                        p = store_rel(p, 0, opcode_memory_start, gl(sf + 8), 1);
                        // FSLW or PC of faulted instruction
                        p = store_rel(p, 0, opcode_memory_start, gl(sf + 12), 1);
                        break;
+               case 0x0a: // 68020/030 address error. Only check SSW.
+                       // SSW
+                       p = store_reg(p, 0, 0, gw(sf + 0x0a), sz_word);
+                       exception_stack_frame_size = 0x0c;
+                       sf[8] = sf[9] = 0;
+                       last_exception[8] = last_exception[9] = 0;
+                       break;
                default:
                        wprintf(_T("Unknown frame %04x!\n"), frame);
                        abort();
@@ -1677,6 +1798,17 @@ static uae_u8 *save_exception(uae_u8 *p)
        return p;
 }
 
+static uae_u16 get_ccr_ignore(struct instr *dp)
+{
+       uae_u16 ccrignoremask = 0;
+       if (cpu_lvl == 2 && test_exception == 5 && dp->mnemo == i_DIVS) {
+               // 68020/030 DIVS + Divide by Zero: V state is not stable.
+               ccrignoremask |= 2; // mask CCR=V
+       }
+       return ccrignoremask;
+}
+
+
 static const TCHAR *sizes[] = { _T("B"), _T("W"), _T("L") };
 
 static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, int fpuopcode)
@@ -1702,7 +1834,6 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                        size = 0;
        }
 
-       xorshiftstate = 1;
        filecount = 0;
 
        struct mnemolookup *lookup = NULL;
@@ -1715,15 +1846,22 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                wprintf(_T("'%s' not found.\n"), mnemo);
                return;
        }
+
        mn = lookup->mnemo;
+       xorshiftstate = lookup - lookuptab;
        const TCHAR *mns = lookup->name;
        if (fpuopcode >= 0) {
+               xorshiftstate = 128 + fpuopcode;
                mns = fpuopcodes[fpuopcode];
-               if (opcodesize == 7)
+               if (opcodesize == 7) {
                        mns = _T("FMOVECR");
-               if (opcodesize == 8)
+                       xorshiftstate = 128 + 64;
+               } else if (opcodesize == 8) {
                        mns = _T("FMOVEM");
+                       xorshiftstate = 128 + 64 + 1;
+               }
        }
+       xorshiftstate += 256 * opcodesize;
 
        int pathlen = _tcslen(path);
        _stprintf(dir, _T("%s%s"), path, mns);
@@ -1775,19 +1913,43 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
        registers[8 + 6] = opcode_memory_start - 0x100;
        registers[8 + 7] = test_memory_end - STACK_SIZE;
 
+       // 1.0
+       fpuregisters[0].high = 0x3fff;
+       fpuregisters[0].low = 0x8000000000000000;
+       // -1.0
+       fpuregisters[1].high = 0xbfff;
+       fpuregisters[1].low = 0x8000000000000000;
+       // 0.0
+       fpuregisters[2].high = 0x0000;
+       fpuregisters[2].low = 0x0000000000000000;
+       // NaN
+       fpuregisters[3].high = 0x7fff;
+       fpuregisters[3].low = 0xffffffffffffffff;
+       // inf+
+       fpuregisters[4].high = 0x7fff;
+       fpuregisters[4].low = 0x0000000000000000;
+       // inf-
+       fpuregisters[5].high = 0xffff;
+       fpuregisters[5].low = 0x0000000000000000;
+
+       for (int i = 6; i < 8; i++) {
+               fpuregisters[i].high = rand16();
+               fpuregisters[i].low = (((uae_u64)rand32()) << 32) | (rand32());
+       }
+
        uae_u32 cur_registers[MAX_REGISTERS];
        for (int i = 0; i < MAX_REGISTERS; i++) {
                cur_registers[i] = registers[i];
        }
-       floatx80 cur_fpuregisters[MAX_REGISTERS];
+       floatx80 cur_fpuregisters[8];
        for (int i = 0; i < 8; i++) {
                cur_fpuregisters[i] = fpuregisters[i];
        }
 
        dst = storage_buffer;
 
-       memcpy(low_memory, low_memory_temp, 32768);
-       memcpy(high_memory, high_memory_temp, 32768);
+       memcpy(low_memory, low_memory_temp, low_memory_size);
+       memcpy(high_memory, high_memory_temp, high_memory_size);
        memcpy(test_memory, test_memory_temp, test_memory_size);
 
        full_format_cnt = 0;
@@ -1877,12 +2039,14 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
 
                                        if (opc == 0xf228)
                                                printf("");
-                                       if (subtest_count == 1568)
+                                       if (subtest_count == 3136)
                                                printf("");
 
 
                                        uaecptr pc = opcode_memory_start + 2;
 
+                                       pc += handle_specials_preea(opc, pc, dp);
+
                                        // create source addressing mode
                                        if (dp->suse) {
                                                int o = create_ea(&opc, pc, dp->smode, dp->sreg, dp, &isconstant_src, 0, fpuopcode, opcodesize);
@@ -1920,6 +2084,8 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                                pc += o;
                                        }
 
+                                       handle_specials_extra(opc, pc, dp);
+
                                        // if destination EA modified opcode
                                        dp = table68k + opc;
 
@@ -2048,7 +2214,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                        int ok = 0;
                                        int cnt_stopped = 0;
 
-                                       uae_u16 last_sr = 0;
+                                       uae_u32 last_sr = 0;
                                        uae_u32 last_pc = 0;
                                        uae_u32 last_registers[MAX_REGISTERS];
                                        floatx80 last_fpuregisters[8];
@@ -2105,18 +2271,15 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                                        for (int i = 0; i < MAX_REGISTERS; i++) {
                                                                regs.regs[i] = cur_registers[i];
                                                        }
-                                                       regs.fpcr = 0;
-                                                       regs.fpsr = 0;
-                                                       regs.fpiar = 0;
                                                        if (fpumode) {
                                                                for (int i = 0; i < 8; i++) {
                                                                        regs.fp[i].fpx = cur_fpuregisters[i];
                                                                }
                                                                regs.fpiar = regs.pc;
                                                                // condition codes
-                                                               regs.fpsr = (ccr & 15) << 24;
+                                                               fpp_set_fpsr((ccr & 15) << 24);
                                                                // precision and rounding
-                                                               regs.fpcr = (ccr >> 4) << 4;
+                                                               fpp_set_fpcr((ccr >> 4) << 4);
                                                        }
                                                        regs.sr = ccr | sr_mask;
                                                        regs.usp = regs.regs[8 + 7];
@@ -2142,6 +2305,9 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                                        if (regs.sr & 0x2000)
                                                                prev_s_cnt++;
 
+                                                       if (subtest_count == 928)
+                                                               printf("");
+
                                                        execute_ins(opc, pc - 2, branch_target);
 
                                                        if (regs.s)
@@ -2211,9 +2377,10 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                                                                last_registers[i] = d;
                                                                        }
                                                                }
-                                                               if (regs.sr != last_sr) {
-                                                                       dst = store_reg(dst, CT_SR, last_sr, regs.sr, -1);
-                                                                       last_sr = regs.sr;
+                                                               uae_u32 ccrignoremask = get_ccr_ignore(dp) << 16;
+                                                               if ((regs.sr | ccrignoremask) != last_sr) {
+                                                                       dst = store_reg(dst, CT_SR, last_sr, regs.sr | ccrignoremask, -1);
+                                                                       last_sr = regs.sr | ccrignoremask;
                                                                }
                                                                if (regs.pc != last_pc) {
                                                                        dst = store_rel(dst, CT_PC, last_pc, regs.pc, 0);
@@ -2244,7 +2411,7 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                                                                dst = store_mem(dst, 0);
                                                                if (test_exception) {
                                                                        *dst++ = CT_END | test_exception;
-                                                                       dst = save_exception(dst);
+                                                                       dst = save_exception(dst, dp);
                                                                } else {
                                                                        *dst++ = CT_END;
                                                                }
@@ -2331,11 +2498,96 @@ static void test_mnemo(const TCHAR *path, const TCHAR *mnemo, int opcodesize, in
                cur_registers[8 + 6]--;
                cur_registers[8 + 7] -= 2;
 
+               for (int i = 0; i < 8; i++) {
+                       cur_fpuregisters[i].high = rand16();
+                       cur_fpuregisters[i].low = (((uae_u64)rand32()) << 32) | (rand32());
+                       if (rand16() & 1) {
+                               cur_fpuregisters[i].low |= 0x8000000000000000;
+                       }
+               }
        }
 
        wprintf(_T("- %d tests\n"), subtest_count);
 }
 
+static void test_mnemo_text(const TCHAR *path, const TCHAR *mode)
+{
+       TCHAR modetxt[100];
+       int mnemo = -1;
+       int fpuopcode = -1;
+       int sizes = -1;
+
+       _tcscpy(modetxt, mode);
+       my_trim(modetxt);
+       TCHAR *s = _tcschr(modetxt, '.');
+       if (s) {
+               *s = 0;
+               TCHAR c = _totlower(s[1]);
+               if (c == 'b')
+                       sizes = 6;
+               if (c == 'w')
+                       sizes = 4;
+               if (c == 'l')
+                       sizes = 0;
+               if (c == 'u')
+                       sizes = 8;
+               if (c == 's')
+                       sizes = 1;
+               if (c == 'x')
+                       sizes = 2;
+               if (c == 'p')
+                       sizes = 3;
+               if (c == 'd')
+                       sizes = 5;
+       }
+       for (int j = 0; lookuptab[j].name; j++) {
+               if (!_tcsicmp(modetxt, lookuptab[j].name)) {
+                       mnemo = j;
+                       break;
+               }
+       }
+       if (mnemo < 0) {
+               if (_totlower(modetxt[0]) == 'f') {
+                       if (!_tcsicmp(modetxt, _T("fmovecr"))) {
+                               mnemo = i_FPP;
+                               sizes = 7;
+                               fpuopcode = 0;
+                       } else if (!_tcsicmp(modetxt, _T("fmovem"))) {
+                               mnemo = i_FPP;
+                               sizes = 8;
+                               fpuopcode = 0;
+                       } else {
+                               for (int i = 0; i < 64; i++) {
+                                       if (fpuopcodes[i] && !_tcsicmp(modetxt, fpuopcodes[i])) {
+                                               mnemo = i_FPP;
+                                               fpuopcode = i;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               if (mnemo < 0) {
+                       wprintf(_T("Couldn't find '%s'\n"), modetxt);
+                       return;
+               }
+       }
+
+       if (mnemo >= 0 && sizes < 0) {
+               if (fpuopcode >= 0) {
+                       for (int i = 0; i < 7; i++) {
+                               test_mnemo(path, lookuptab[mnemo].name, i, fpuopcode);
+                       }
+               } else {
+                       test_mnemo(path, lookuptab[mnemo].name, 0, -1);
+                       test_mnemo(path, lookuptab[mnemo].name, 4, -1);
+                       test_mnemo(path, lookuptab[mnemo].name, 6, -1);
+                       test_mnemo(path, lookuptab[mnemo].name, -1, -1);
+               }
+       } else {
+               test_mnemo(path, lookuptab[mnemo].name, sizes, fpuopcode);
+       }
+}
+
 static void my_trim(TCHAR *s)
 {
        int len;
@@ -2530,12 +2782,21 @@ int __cdecl main(int argc, char *argv[])
        opcode_memory = test_memory + test_memory_size / 2;
        opcode_memory_start = test_memory_start + test_memory_size / 2;
 
+       low_memory_size = test_low_memory_end;
+       if (low_memory_size < 0x8000)
+               low_memory_size = 0x8000;
+
+       low_memory = (uae_u8 *)calloc(1, low_memory_size);
+       low_memory_temp = (uae_u8 *)calloc(1, low_memory_size);
+       high_memory = (uae_u8 *)calloc(1, high_memory_size);
+       high_memory_temp = (uae_u8 *)calloc(1, high_memory_size);
+
        fill_memory();
 
        TCHAR *lmem_rom_name = NULL;
        ini_getstring(ini, INISECTION, _T("low_rom"), &lmem_rom_name);
        if (lmem_rom_name && test_low_memory_start != 0xffffffff) {
-               if (load_file(NULL, lmem_rom_name, low_memory_temp, 32768, 0)) {
+               if (load_file(NULL, lmem_rom_name, low_memory_temp, low_memory_size, 0)) {
                        wprintf(_T("Low test memory ROM loaded\n"));
                        lmem_rom = 1;
                }
@@ -2545,15 +2806,15 @@ int __cdecl main(int argc, char *argv[])
        TCHAR *hmem_rom_name = NULL;
        ini_getstring(ini, INISECTION, _T("high_rom"), &hmem_rom_name);
        if (hmem_rom_name && test_high_memory_start != 0xffffffff) {
-               if (load_file(NULL, hmem_rom_name, high_memory_temp, 32768, -1)) {
+               if (load_file(NULL, hmem_rom_name, high_memory_temp, high_memory_size, -1)) {
                        wprintf(_T("High test memory ROM loaded\n"));
                        hmem_rom = 1;
                }
        }
        free(hmem_rom_name);
 
-       save_memory(path, _T("lmem.dat"), low_memory_temp, 32768);
-       save_memory(path, _T("hmem.dat"), high_memory_temp, 32768);
+       save_memory(path, _T("lmem.dat"), low_memory_temp, low_memory_size);
+       save_memory(path, _T("hmem.dat"), high_memory_temp, high_memory_size);
        save_memory(path, _T("tmem.dat"), test_memory_temp, test_memory_size);
 
        storage_buffer = (uae_u8 *)calloc(max_storage_buffer, 1);
@@ -2657,102 +2918,46 @@ int __cdecl main(int argc, char *argv[])
        while(modep) {
 
                int all = 0;
-               int mnemo = -1;
-               int fpuopcode = -1;
-               int sizes = -1;
 
                if (!_tcsicmp(mode, _T("all"))) {
 
                        verbose = 0;
                        for (int j = 1; lookuptab[j].name; j++) {
-                               test_mnemo(path, lookuptab[j].name, 0, -1);
-                               test_mnemo(path, lookuptab[j].name, 4, -1);
-                               test_mnemo(path, lookuptab[j].name, 6, -1);
-                               test_mnemo(path, lookuptab[j].name, -1, -1);
+                               test_mnemo_text(path, lookuptab[j].name);
                        }
-                       // illg last. All currently selected CPU model's unsupported opcodes
-                       // (illegal instruction, a-line and f-line)
-                       test_mnemo(path, lookuptab[0].name, 0, -1);
-                       test_mnemo(path, lookuptab[0].name, 4, -1);
-                       test_mnemo(path, lookuptab[0].name, 6, -1);
-                       test_mnemo(path, lookuptab[0].name, -1, -1);
+                       // Illegal instructions last. All currently selected CPU model's unsupported opcodes
+                       // (Generates illegal instruction, a-line or f-line exception)
+                       test_mnemo_text(path, _T("ILLEGAL"));
                        break;
                }
 
-               TCHAR *sp = _tcschr(modep, ',');
-               if (sp)
-                       *sp++ = 0;
-               TCHAR modetxt[100];
-               _tcscpy(modetxt, modep);
-               my_trim(modetxt);
-               TCHAR *s = _tcschr(modetxt, '.');
-               if (s) {
-                       *s = 0;
-                       TCHAR c = _totlower(s[1]);
-                       if (c == 'b')
-                               sizes = 6;
-                       if (c == 'w')
-                               sizes = 4;
-                       if (c == 'l')
-                               sizes = 0;
-                       if (c == 'u')
-                               sizes = 8;
-                       if (c == 's')
-                               sizes = 1;
-                       if (c == 'x')
-                               sizes = 2;
-                       if (c == 'p')
-                               sizes = 3;
-                       if (c == 'd')
-                               sizes = 5;
-               }
-               for (int j = 0; lookuptab[j].name; j++) {
-                       if (!_tcsicmp(modetxt, lookuptab[j].name)) {
-                               mnemo = j;
-                               break;
-                       }
-               }
-               if (mnemo < 0) {
-                       if (_totlower(modetxt[0]) == 'f') {
-                               if (!_tcsicmp(modetxt, _T("fmovecr"))) {
-                                       mnemo = i_FPP;
-                                       sizes = 7;
-                                       fpuopcode = 0;
-                               } else if (!_tcsicmp(modetxt, _T("fmovem"))) {
-                                       mnemo = i_FPP;
-                                       sizes = 8;
-                                       fpuopcode = 0;
-                               } else {
-                                       for (int i = 0; i < 64; i++) {
-                                               if (fpuopcodes[i] && !_tcsicmp(modetxt, fpuopcodes[i])) {
-                                                       mnemo = i_FPP;
-                                                       fpuopcode = i;
-                                                       break;
-                                               }
-                                       }
+               if (!_tcsicmp(mode, _T("fall"))) {
+
+                       verbose = 0;
+                       test_mnemo_text(path, _T("FMOVECR"));
+                       const TCHAR *prev = _T("");
+                       for (int j = 0; j < 64; j++) {
+                               if (fpuopcodes[j] && _tcscmp(prev, fpuopcodes[j])) {
+                                       test_mnemo_text(path, fpuopcodes[j]);
+                                       prev = fpuopcodes[j];
                                }
                        }
-                       if (mnemo < 0) {
-                               wprintf(_T("Couldn't find '%s'\n"), modetxt);
-                               return 0;
-                       }
-               }
-
-               if (mnemo >= 0 && sizes < 0) {
-                       if (fpuopcode >= 0) {
-                               for (int i = 0; i < 8; i++) {
-                                       test_mnemo(path, lookuptab[mnemo].name, i, fpuopcode);
+                       for (int j = 1; lookuptab[j].name; j++) {
+                               if (lookuptab[j].name[0] == 'F' && _tcscmp(lookuptab[j].name, _T("FPP"))) {
+                                       test_mnemo_text(path, lookuptab[j].name);
                                }
-                       } else {
-                               test_mnemo(path, lookuptab[mnemo].name, 0, -1);
-                               test_mnemo(path, lookuptab[mnemo].name, 4, -1);
-                               test_mnemo(path, lookuptab[mnemo].name, 6, -1);
-                               test_mnemo(path, lookuptab[mnemo].name, -1, -1);
                        }
-               } else {
-                       test_mnemo(path, lookuptab[mnemo].name, sizes, fpuopcode);
+                       test_mnemo_text(path, _T("FMOVEM"));
+                       break;
                }
 
+
+               TCHAR *sp = _tcschr(modep, ',');
+               if (sp)
+                       *sp++ = 0;
+
+               test_mnemo_text(path, modep);
+
                modep = sp;
        }
 
diff --git a/cputest/adis/decode_ea.c b/cputest/adis/decode_ea.c
new file mode 100644 (file)
index 0000000..b44eb73
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * Change history
+ * $Log:       decode_ea.c,v $
+ * Revision 3.1  09/12/11 Matt Hey
+ * Minor mod.: enter_ref() for immediate and PC memory indirect with index
+ *             relocations is now ACC_UNKNOWN instead of access
+ *
+ * Revision 3.0  93/09/24  17:53:50  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.5  93/07/18  22:55:43  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.4  93/07/11  21:38:04  Martin_Apel
+ * Major mod.: Jump table support tested and changed
+ * 
+ * Revision 2.3  93/07/10  13:01:56  Martin_Apel
+ * Major mod.: Added full jump table support. Seems to work quite well
+ * 
+ * Revision 2.2  93/07/08  22:27:46  Martin_Apel
+ * 
+ * Minor mod.: Displacements below 4 used with pc indirect indexed are
+ *             not entered into the symbol table anymore
+ * 
+ * Revision 2.1  93/07/08  20:47:04  Martin_Apel
+ * Bug fix: Extended precision reals were printed wrong
+ * 
+ * Revision 2.0  93/07/01  11:53:45  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.12  93/07/01  11:38:28  Martin_Apel
+ * Minor mod.: PC relative addressing is now marked as such
+ * 
+ * Revision 1.11  93/06/16  20:26:17  Martin_Apel
+ * Minor mod.: Added jump table support. UNTESTED !!!
+ * 
+ * Revision 1.10  93/06/06  13:45:34  Martin_Apel
+ * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
+ * 
+ * Revision 1.9  93/06/03  18:22:12  Martin_Apel
+ * Minor mod.: Addressing relative to hunk end changed
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: decode_ea.c,v 3.0 93/09/24 17:53:50 Martin_Apel Exp $"; */
+
+uint decode_ea (char *to, ushort mode, ushort reg, UWORD access, ushort first_ext)
+
+/* returns the number of extension words used for ea */
+{
+static ULONG maybe_jmptable_ref = UNSET;  /* for jump table disassembly */
+ULONG ref;
+register UWORD first_ext_w;
+
+first_ext_w = *(code + first_ext);
+switch (mode)
+  {
+  /********************** data register direct ************************/
+
+  case 0:
+    if (pass3)
+      str_cpy (to, reg_names [reg]);
+    return (0);
+
+  /********************* address register direct **********************/
+
+  case 1:
+    if (access & ACC_BYTE)
+      {
+      instr_bad = TRUE;
+      return (0);
+      }
+    if (pass3)
+      str_cpy (to, reg_names [reg + 8]);
+    return (0);
+
+  /********************** address register indirect *******************/
+
+  case 2:
+    if (pass3)
+      indirect (to, (ushort)(reg + 8));
+    else if ((*code & 0xfff8) == 0x4ed0)  /* jmp (An) */
+      {
+      if (!FLAGS_RELOC (maybe_jmptable_ref))
+        enter_jmptab (maybe_jmptable_ref, 0);  /* jmp table with word entries */
+      else
+        {
+        /* Probably a jmp table of long relocs. The refs/labels pointed to
+           by the jmp table entries should already be entered but may not
+           be marked as code. */
+
+        while ((*(ULONG*)(flags + maybe_jmptable_ref - first_ref) &
+              ((FLAG_RELOC << 24) | (FLAG_RELOC << 16) |
+               (FLAG_RELOC << 8) | FLAG_RELOC)) ==
+              ((FLAG_RELOC << 24) | (FLAG_RELOC << 16) |
+               (FLAG_RELOC << 8) | FLAG_RELOC))
+          {
+          ref = *(ULONG*)(hunk_address + maybe_jmptable_ref - first_ref);
+          if (ODD (ref) || ref < first_ref || ref >= last_ref)
+            break;
+          enter_ref (ref, NULL, ACC_CODE);  /* mark ref/label as code */
+          maybe_jmptable_ref += 4;
+          }
+        }
+      }
+    return (0);
+
+  /************ address register indirect post-increment **************/
+
+  case 3:
+    if (pass3)
+      post_inc (to, (ushort)(reg + 8));
+    return (0);
+
+  /************* address register indirect pre-decrement **************/
+
+  case 4:
+    if (pass3)
+      pre_dec (to, (ushort)(reg + 8));
+    return (0);
+
+  /************* address register indirect with displacement **********/
+
+  case 5:
+    if (try_small && reg == 4)
+      {
+      ref = (WORD)first_ext_w + a4_offset;
+      if (pass3)
+        gen_label_ref (to, ref);
+      else
+        enter_ref (ref, NULL, access);
+      }
+    else if (pass3)
+      disp_an (to, (ushort)(reg + 8), (ushort)first_ext_w);
+    return (1);
+
+  /****************** address register indirect indexed ***************/
+
+  case 6:
+    if (first_ext_w & 0x100)
+      {
+      if (cpu68020)
+        return (full_extension (to, code + first_ext, mode, reg));
+      else
+        {
+        instr_bad = TRUE;
+        return (0);
+        }
+      }
+    else
+      {
+      UWORD size = (first_ext_w >> 9) & 0x3;
+
+      if (!cpu68020 && size != 0)  /* Only size of 1 allowed for 68000 */
+        {
+        instr_bad = TRUE;
+        return (0);
+        }
+      if (pass3)
+        {
+        /* To get the sign right */
+        disp_an_indexed (to, (ushort)(reg + 8),
+                         (BYTE)first_ext_w,
+                         (ushort)(first_ext_w >> 12),
+                         (ushort)(1 << size),
+                         (first_ext_w & 0x0800) ? ACC_LONG : ACC_WORD);
+        }
+      return (1);
+      }
+
+  /************************* Mode 7 with submodes *********************/
+
+  case 7:
+    switch (reg)
+      {
+      /*********************** absolute short *********************/
+
+      case 0:
+        if (pass3)
+          {
+          to = format_ulx (to, (WORD)first_ext_w);
+          *to++ = '.';
+          *to++ = 'w';
+          *to = 0;
+          }
+        return (1);
+
+      /*********************** absolute long **********************/
+
+      case 1:
+        ref = *(ULONG*)(code + first_ext);
+        if (FLAGS_RELOC (current_ref + first_ext * 2))
+          {
+          if (pass3)
+            /* This reference is relocated and thus needs a label */
+            gen_label_ref (to, ref);
+          else
+            {
+            enter_ref (ref, NULL, access);
+            /*
+            if (EVEN (ref) && ref >= first_ref && ref < last_ref)
+              maybe_jmptable_ref = ref;
+            */
+            }
+          }
+        else if (pass3)
+          {
+          to = format_ulx (to, ref);
+          if (!optimize)
+            {
+            *to++ = '.';
+            *to++ = 'l';
+            *to = 0;
+            }
+          }
+        return (2);
+
+      /************************** d16(PC) *************************/
+
+      case 2:
+/* It's possible, that a program accesses its hunk structure PC relative,
+   thus it generates a reference to a location outside valid code addresses */
+
+        /* A neg displacement can make ref neg if out of bounds. */
+        ref = current_ref + ((ULONG)first_ext << 1) + (WORD)first_ext_w;
+        if (pass3)
+          {
+          if (!old_style)
+            *to++ = '(';
+          if ((LONG)ref < (LONG)first_ref)
+            {
+            to = gen_label_ref (to, first_ref);
+            *to++ = '-';
+            to = format_lx (to, (LONG)first_ref - (LONG)ref);
+            }
+          else if (ref >= last_ref)
+            {
+            to = gen_label_ref (to, last_ref - 2);
+            *to++ = '+';
+            to = format_lx (to, ref - last_ref + 2);
+            }
+          else
+            to = gen_label_ref (to, ref);
+          if (old_style)
+            *to++ = '(';
+          else
+            *to++ = ',';
+          to = str_cpy (to, reg_names [PC]);
+          *to++ =')';
+          *to = 0;
+          }
+        else if ((LONG)ref >= (LONG)first_ref && (LONG)ref < (LONG)last_ref)
+          {
+          enter_ref (ref, NULL, access);
+          if (EVEN (ref))
+            maybe_jmptable_ref = ref;
+          }
+        return (1);
+
+      /***************** PC memory indirect with index ************/
+
+      case 3:
+        if (first_ext_w & 0x0100)
+          {
+          /* long extension word */
+          if (cpu68020)
+            return (full_extension (to, code + first_ext, mode, reg));
+          else
+            {
+            instr_bad = TRUE;
+            return (0);
+            }
+          }
+        else
+          {
+          UWORD size = (first_ext_w >> 9) & 0x3;
+
+          if (!cpu68020 && size != 0)  /* Only size of 1 allowed for 68000 */
+            {
+            instr_bad = TRUE;
+            return (0);
+            }
+          /* A neg displacement can make ref neg if out of bounds. */
+          ref = current_ref + ((ULONG)first_ext << 1) + (BYTE)first_ext_w;
+          if (pass3)
+            disp_pc_indexed (to, ref, (BYTE)first_ext_w,
+                            (ushort)(first_ext_w >> 12),
+                            (ushort)(1 << size),
+                            (first_ext_w & 0x0800) ? ACC_LONG : ACC_WORD);
+          else if ((LONG)ref >= (LONG)first_ref && (LONG)ref < (LONG)last_ref)
+            {
+            if (*code == 0x4efb)  /* Check for JMP (d8,PC,Xn) */
+              {
+              enter_jmptab (maybe_jmptable_ref, (ULONG)((BYTE)first_ext_w) + 2);
+              }
+            else
+              {
+              enter_ref (ref, NULL, access);
+              if (EVEN (ref))
+                maybe_jmptable_ref = ref;
+              }
+            }
+          return (1);
+          }
+
+      /************************ immediate *************************/
+
+      case 4:
+        if (access & ACC_BYTE)
+          {
+          if (pass3)
+            {
+            *to++ = '#';
+            if (access & ACC_SIGNED)
+              format_x (to, (BYTE)first_ext_w);
+            else
+              format_ux (to, (UBYTE)first_ext_w);
+            }
+          return (1);
+          }
+        else if (access & ACC_WORD)
+          {
+          if (pass3)
+            {
+            *to++ = '#';
+            if (access & ACC_SIGNED)
+              format_x (to, (WORD)first_ext_w);
+            else
+              format_ux (to, (UWORD)first_ext_w);
+            }
+          return (1);
+          }
+        else if (access & ACC_LONG)
+          {
+          ref = *(ULONG*)(code + first_ext);
+          if (FLAGS_RELOC (current_ref + first_ext * 2))
+            {
+            if (pass2)
+              {
+              enter_ref (ref, NULL, ACC_UNKNOWN);  /* data type and size is unknown */
+              if (EVEN (ref) && ref >= first_ref && ref < last_ref)
+                maybe_jmptable_ref = ref;
+              }
+            else
+              {
+              /* This reference is relocated and thus needs a label */
+              *to++ = '#';
+              *to++ = '(';
+              to = gen_label_ref (to, ref);
+              *to++ = ')';
+              *to++ = 0;
+              }
+            }
+          else if (pass3)
+            {
+            *to++ = '#';
+            if (access & ACC_SIGNED)
+              format_lx (to, (LONG)ref);
+            else
+              format_ulx (to, ref);
+            }
+          return (2);
+          }
+        else if (access & ACC_DOUBLE)
+          {
+          if (pass3)
+            {
+            sprintf (to, "#$%lx%08lx", *(ULONG*)(code + first_ext),
+                     *(ULONG*)(code + first_ext + 2));
+            }
+          return (4);
+          }
+        else if (access & ACC_EXTEND)
+          {
+          if (pass3)
+            {
+            sprintf (to, "#$%lx%08lx%08lx", *(ULONG*)(code + first_ext),
+                     *(ULONG*)(code + first_ext + 2), 
+                     *(ULONG*)(code + first_ext + 4));
+            }
+          return (6);
+          }
+#ifdef DEBUG
+        else
+          {
+          fprintf (stderr, "WARNING: Unknown immediate addressing size at %lx\n", current_ref);
+          }
+#endif
+        break;
+      default:
+        /* Should not occur, as it should be caught by the submode test in disasm.c */
+        instr_bad = TRUE;
+#ifdef DEBUG
+        fprintf (stderr, "WARNING: Illegal submode at %lx\n", current_ref);
+#endif
+      }
+    break;    
+  }
+return (0);
+}
diff --git a/cputest/adis/defs.h b/cputest/adis/defs.h
new file mode 100644 (file)
index 0000000..63c2454
--- /dev/null
@@ -0,0 +1,522 @@
+/*
+ * Change history
+ * $Log:       defs.h,v $
+ * Revision 3.0  93/09/24  17:54:36  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.4  93/07/18  22:57:05  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.3  93/07/11  21:40:10  Martin_Apel
+ * Major mod.: Jump table support tested and changed
+ * 
+ * Revision 2.2  93/07/10  13:02:39  Martin_Apel
+ * Major mod.: Added full jump table support. Seems to work quite well
+ * 
+ * Revision 2.1  93/07/08  20:50:47  Martin_Apel
+ * Minor mod.: Added print_flags for debugging purposes
+ * 
+ * Revision 2.0  93/07/01  11:55:04  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.30  93/07/01  11:46:54  Martin_Apel
+ * Minor mod.: Prepared for tabs instead of spaces
+ * 
+ * Revision 1.29  93/06/19  12:12:20  Martin_Apel
+ * Major mod.: Added full 68030/040 support
+ * 
+ * Revision 1.28  93/06/16  20:31:52  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * Minor mod.: Added variables for 68030 / 040 support
+ * 
+ * Revision 1.27  93/06/06  13:48:45  Martin_Apel
+ * Minor mod.: Added preliminary support for jump tables recognition
+ * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
+ * 
+ * Revision 1.26  93/06/06  00:16:26  Martin_Apel
+ * Major mod.: Added support for library/device disassembly (option -dl)
+ * 
+ * Revision 1.25  93/06/04  11:57:34  Martin_Apel
+ * New feature: Added -ln option for generation of ascending label numbers
+ * 
+ * Revision 1.24  93/06/03  20:31:01  Martin_Apel
+ * New feature: Added -a switch to generate comments for file offsets
+ * 
+ * Revision 1.23  93/06/03  18:28:15  Martin_Apel
+ * Minor mod.: Added new prototypes an variables for hunk-handling routines.
+ * Minor mod.: Remove temporary files upon exit (even with CTRL-C).
+ * 
+ */
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#if 0
+#include <exec/types.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef MCH_AMIGA
+#ifndef AMIGA
+#define AMIGA
+#endif
+#endif
+
+#ifdef DEBUG
+#define PRIVATE
+#else
+#define PRIVATE static
+#endif
+
+typedef unsigned char UBYTE;
+typedef unsigned short UWORD;
+typedef unsigned long ULONG;
+
+typedef signed char BYTE;
+typedef signed short WORD;
+typedef signed long LONG;
+
+typedef signed short BOOL;
+#define TRUE 1
+#define FALSE 0
+
+#if !defined(__GNUC__)
+/* Already defined in sys/types.h for GCC */
+typedef unsigned int uint;
+typedef unsigned short ushort;
+#endif
+typedef unsigned char uchar;
+
+/* $Id: defs.h,v 3.0 93/09/24 17:54:36 Martin_Apel Exp $ */
+
+struct opcode_entry
+  {
+  uint (*handler) (struct opcode_entry*);
+  UBYTE modes;      /* addressing modes allowed for this opcode */
+  UBYTE submodes;   /* addressing submodes of mode 7 allowed for this opcode */
+  UWORD chain;      /* if another opcode is possible for this bit pattern, */
+                    /* this is the index of another entry in opcode_table. */
+                    /* Otherwise it's zero */
+  char *mnemonic;
+  UWORD param;      /* given to handler () */
+  UWORD access;     /* data type of instruction access (ACC_ flags) */
+  };
+
+struct opcode_sub_entry
+  {
+  uint (*handler) (struct opcode_sub_entry*);
+  char *mnemonic;
+  UWORD param;      /* given to handler () */
+  UWORD access;     /* data type of instruction access (ACC_ flags) */
+  };
+
+#define TRANSFER 0                /* The handler didn't handle this opcode */
+                                  /* Transfer to next in chain */
+/* Param values */
+/* MOVEM direction */
+#define REG_TO_MEM 0
+#define MEM_TO_REG 1
+/* Bitfield instructions */
+#define DATADEST 0
+#define DATASRC  1
+#define SINGLEOP 2
+/* MOVE to or from SR, CCR */
+#define TO_CCR   0
+#define FROM_CCR 1
+#define TO_SR    2
+#define FROM_SR  3
+/* Extended precision and BCD instructions */
+#define NO_ADJ 0
+#define ADJUST 1
+
+/* Bit masks */
+#define EA_MODE 0x038      /* Bits 5 - 3 */
+#define EA_REG  0x007      /* Bits 2 - 0 */
+#define REG2    0xe00      /* Bits 11 - 9 */
+#define OP_MODE 0x1c0      /* Bits 8 - 6 */
+
+/* Shift values */
+#define MODE_SHIFT 3
+#define REG2_SHIFT 9
+#define OP_MODE_SHIFT 6
+
+#define MODE_NUM(x) ((UWORD)(((x) >> 3) & 0x7))
+#define REG_NUM(x)  ((UWORD)((x) & EA_REG))
+
+#define USE_SIGN    TRUE
+#define NO_SIGN     FALSE
+#define USE_LABEL   TRUE
+#define NO_LABEL    FALSE
+#define USE_COMMENT TRUE
+#define NO_COMMENT  FALSE
+
+#define DEF_BUF_SIZE (16L * 1024L)
+
+enum 
+  {
+  SR, CCR, USP, SFC, DFC, CACR, VBR, CAAR, MSP, ISP, TC, 
+  ITT0, ITT1, DTT0, DTT1, MMUSR, URP, SRP, TT0, TT1, CRP
+  };
+
+#define PC (ushort)16               /* index into reg_names array */
+
+/* Access types for reference table. */
+#define ACC_BYTE     (UWORD)0x0001  /* referenced as byte */
+#define ACC_WORD     (UWORD)0x0002  /* referenced as word */
+#define ACC_LONG     (UWORD)0x0004  /* referenced as long or fp single (4 bytes) */
+#define ACC_DOUBLE   (UWORD)0x0008  /* referenced as fp double (8 bytes) */
+#define ACC_EXTEND   (UWORD)0x0010  /* referenced as fp extended (12 bytes) */
+#define ACC_SIGNED   (UWORD)0x0020
+#define ACC_DATA     (UWORD)0x0040  /* referenced as data but size unknown */
+#define ACC_CODE     (UWORD)0x0080  /* referenced as code */
+#define ACC_UNKNOWN  (UWORD)0x0100  /* accessed but unknown if code or data */
+/* ... */
+#define ACC_INACTIVE (UWORD)0x4000  /* This label is temporarily deactivated */
+#define ACC_NEW      (UWORD)0x8000  /* ref is new and easily deleted */
+
+#define ACC_SBYTE    ACC_BYTE|ACC_SIGNED  /* shortcut for signed byte */
+#define ACC_SWORD    ACC_WORD|ACC_SIGNED  /* shortcut for signed word */
+#define ACC_SLONG    ACC_LONG|ACC_SIGNED  /* shortcut for signed long */
+
+/* Flags (UBYTE) */
+#define FLAG_BYTE       0x01  /* data size is byte */
+#define FLAG_WORD       0x02  /* data size is word */
+#define FLAG_LONG       0x04  /* data size is long */
+#define FLAG_SIGNED     0x08  /* data is signed */
+#define FLAG_RELOC      0x10  /* data is relocatable */
+#define FLAG_STRING     0x20  /* data is a string */
+#define FLAG_TABLE      0x40  /* data is a table */
+#define FLAG_CODE       0x80  /* data is code */
+
+#define FLAGS_BYTE(ref)    (*(flags + (ref) - first_ref) & FLAG_BYTE)
+#define FLAGS_WORD(ref)    (*(flags + (ref) - first_ref) & FLAG_WORD)
+#define FLAGS_LONG(ref)    (*(flags + (ref) - first_ref) & FLAG_LONG)
+#define FLAGS_SIGNED(ref)  (*(flags + (ref) - first_ref) & FLAG_SIGNED)
+#define FLAGS_RELOC(ref)   (*(flags + (ref) - first_ref) & FLAG_RELOC)
+#define FLAGS_CODE(ref)    (*(flags + (ref) - first_ref) & FLAG_CODE)
+#define FLAGS_STRING(ref)  (*(flags + (ref) - first_ref) & FLAG_STRING)
+#define FLAGS_BAD(ref)     (*(flags + (ref) - first_ref) &\
+                                        (FLAG_CODE | FLAG_RELOC))
+#define FLAGS_ANY(ref)     (*(flags + (ref) - first_ref))
+#define FLAGS_NONE(ref)    (!FLAGS_ANY(ref))
+
+#define FLAGS_BYTE_P(ptr)      (*(ptr) & FLAG_BYTE)
+#define FLAGS_WORD_P(ptr)      (*(ptr) & FLAG_WORD)
+#define FLAGS_LONG_P(ptr)      (*(ptr) & FLAG_LONG)
+#define FLAGS_SIGNED_P(ptr)    (*(ptr) & FLAG_SIGNED)
+#define FLAGS_RELOC_P(ptr)     (*(ptr) & FLAG_RELOC)
+#define FLAGS_CODE_P(ptr)      (*(ptr) & FLAG_CODE)
+#define FLAGS_STRING_P(ptr)    (*(ptr) & FLAG_STRING)
+#define FLAGS_BAD_P(ptr)       (*(ptr) & (FLAG_CODE | FLAG_RELOC))
+#define FLAGS_ANY_P(ptr)       (*(ptr))
+
+/* Marker for jump-tables */
+#ifdef DEBUG
+#define UNSET 0xffffffffL
+#else
+#define UNSET 0L
+#endif
+
+#define ODD(x) ((x) & 1)
+#define EVEN(x) (!ODD(x))
+
+/* More efficient use of disassembler pass variables than 3 booleans */
+#define set_pass1 (pass = 0)
+#define set_pass2 (pass = 1)
+#define set_pass3 (pass = -1)
+#define pass1 (pass == 0)
+#define pass2 (pass > 0)
+#define pass3 (pass < 0)
+
+extern UBYTE *hunk_address;
+extern UBYTE *flags;  /* UBYTE array of flags describing data. See Flags above */
+extern UWORD *code;
+
+/* Refs are total offsets of the program starting with lowest numbered hunk.
+   hunk_offset = current_ref - first_ref;
+   data_address = *hunk_address + current_ref - first_ref;  */
+
+extern ULONG current_ref;  /* like Program Counter (PC) but with refs */
+extern ULONG first_ref;    /* start ref of current hunk */
+extern ULONG last_ref;     /* last ref of current hunk */
+extern ULONG total_size;   /* total program size in bytes */
+extern ULONG current_hunk; /* hunk number of current hunk */
+/* The following point to a table (array) of hunk attributes indexed by hunk number */
+extern ULONG *hunk_start,
+             *hunk_end,
+             *hunk_offset,    /* hunk f_offset */
+             *hunk_memtype;   /* hunk memory type */
+
+extern char *conditions [];
+extern char *reg_names []; 
+extern char *special_regs [];
+extern char opcode [];
+extern char src [];
+extern char dest [];
+extern char spaces [];
+
+extern ULONG f_offset;     /* file offset */
+extern FILE *in,
+            *out,
+            *tmp_f;
+extern char *in_buf,
+            *out_buf;
+extern char *input_filename;
+extern char *output_filename;
+extern char *fd_filename;
+
+extern int buf_size;
+extern long a4_offset;
+extern BOOL try_small;
+extern BOOL instr_bad;
+extern BOOL instr_end;
+extern char pass;
+extern char space_char;
+extern char comment;
+extern BOOL optimize;
+extern BOOL branch_sizes;
+extern BOOL verbose;
+extern BOOL print_illegal_instr_offset;
+extern BOOL single_file;
+extern BOOL ascending_label_numbers;
+extern BOOL disasm_as_lib;
+extern BOOL old_style;
+extern BOOL cpu68020,
+            cpu68030,
+            cpu68040,
+            cpu68060,
+            cpuCF,
+            fpu68881;
+
+extern BOOL ROMTagFound;
+extern UBYTE ROMTagType;
+extern ULONG ROMTagRef;
+extern ULONG InitTableRef;
+extern ULONG FuncTableRef;
+extern ULONG DataTableRef;
+
+extern short cpu68020_disabled [];
+extern short cpu68030_disabled [];
+extern short cpu68040_disabled [];
+extern short cpu68060_disabled [];
+extern short cpuCF_disabled [];
+extern short fpu68881_disabled [];
+
+extern int OPCODE_COL;
+extern int PARAM_COL;
+extern int COMMENT_COL;
+extern int MAX_STR_COL;
+
+
+/* Prototypes */
+
+/* analyze.c */
+void analyze_code (UBYTE *seg);
+
+/* decode_ea.c */
+uint decode_ea (char *to, ushort mode, ushort reg, UWORD access, ushort first_ext);
+
+/* disasm_code.c */
+uint disasm_instr (UWORD *instr, char*);
+void disasm_code (UBYTE *seg, ULONG seg_size);
+
+/* disasm_data.c */
+void disasm_data (UBYTE *seg, ULONG seg_size);
+void disasm_bss (void);
+
+/* main.c */
+int main (int argc, char *argv []);
+void parse_args (int argc, char *argv []);
+#ifdef DEBUG
+void usage (void);
+#endif
+void open_files (void);
+void close_files (void);
+void open_output_file (void);
+void close_output_file (void);
+void ExitADis (void);
+#ifdef DEBUG
+void check_consistency (void);
+#endif
+
+/* util.c */
+char *str_cpy (char *dest, const char *src);
+char *str_cat (char *dest, const char *src);
+BOOL is_str (char *maybe_string, uint max_len);
+int str_len (char *maybe_string, uint max_len);
+void emit (char *string);
+void col_emit (char *string);
+
+char *format_ulx (char *to, ULONG val);
+char *format_lx (char *to, ULONG val);
+char *format_ulx_no_dollar (char *to, ULONG val);
+char *format_ulx_digits (char *to, ULONG val, uint digits);
+/* Processing .l is as fast or faster than .w for 68020+. */
+/* format_ulx () can handle UWORD values thus define below. */
+#define format_ux(to,val) format_ulx(to,val)
+/* format_lx () can handle WORD (and BYTE) values thus define below. */
+#define format_x(to,val) format_lx(to,val)
+/* format_ulx_no_dollar () can handle UWORD values thus define below. */
+#define format_ux_no_dollar(to,val) format_ulx_no_dollar(to,val)
+
+void format_reg_list (char *to, UWORD list, BOOL to_mem, ushort reglist_offset);
+char *immed (char *to, ULONG val);
+void pre_dec (char *to, ushort reg_num);
+void post_inc (char *to, ushort reg_num);
+void indirect (char *to, ushort reg_num);
+void disp_an (char *to, ushort reg_num, WORD disp);
+void disp_an_indexed (char *to, ushort an, BYTE disp, ushort index_reg, 
+                             ushort scale, ushort size);
+void disp_pc_indexed (char *to, ULONG ref, BYTE disp, ushort index_reg, 
+                             ushort scale, ushort size);
+uint full_extension (char *to, UWORD *instr, ushort mode, ushort reg);
+char *gen_xref (char *to, ULONG address);
+char *gen_label_ref (char *to, ULONG ref);
+char *gen_label (char *to, ULONG ref);
+char *format_line (char *to, BOOL commented, int instr_words);
+void assign_label_names (void);
+
+/* hunks.c */
+BOOL readfile (void);
+void read_hunk_header (void);
+void read_hunk_unit (void);
+BOOL read_hunk_code (void);
+BOOL read_hunk_data (void);
+BOOL read_hunk_bss (void);
+void process_hunks (UBYTE *seg);
+BOOL read_hunk_symbol (void);
+BOOL read_hunk_reloc16 (UBYTE *seg);
+BOOL read_hunk_reloc32 (UBYTE *seg);
+
+/* refs.c */
+BOOL init_ref_table (ULONG size);
+void kill_ref_table (void);
+void enter_ref (ULONG ref, char *name, UWORD access_type);
+ULONG ext_enter_ref (ULONG ref, ULONG hunk, char *name, UWORD access_type);
+BOOL find_ref (ULONG ref, char **name, UWORD *access_type);
+BOOL find_active_ref (ULONG ref, char **name, UWORD *access_type);
+ULONG next_ref (ULONG from, ULONG to, UWORD *access_type);
+ULONG next_active_ref (ULONG from, ULONG to, UWORD *access_type);
+void deactivate_refs (ULONG from, ULONG to);
+void save_new_refs (void);
+void delete_new_refs (void);
+
+/* mem.c */
+void *alloc_mem (ULONG size);
+void free_mem (void *buffer);
+
+/* user_defined.c */
+void predefine_label (ULONG address, UWORD access);
+void add_predefined_labels (void);
+
+#ifdef DEBUG
+void print_ref_table (ULONG from, ULONG to);
+void print_active_table (ULONG from, ULONG to);
+void check_active_table (void);
+#endif
+
+/* opcodes.c */
+extern struct opcode_entry opcode_table [];
+
+/* opcode_handler.c */
+
+uint EA_to_Rn (struct opcode_entry *op);
+uint Rn_to_EA (struct opcode_entry *op);
+uint op1 (struct opcode_entry *op);
+uint op1_end (struct opcode_entry *op);
+uint imm_b (struct opcode_entry *op);
+uint imm_w (struct opcode_entry *op);
+uint imm_l (struct opcode_entry *op);
+uint quick (struct opcode_entry *op);
+uint bit_reg (struct opcode_entry *op);
+uint bit_imm (struct opcode_entry *op);
+uint move (struct opcode_entry *op);
+uint movem (struct opcode_entry *op);
+uint moveq (struct opcode_entry *op);
+uint srccr (struct opcode_entry *op);
+uint special (struct opcode_entry *op);
+uint illegal (struct opcode_entry *op);
+uint invalid (struct opcode_entry *op);
+uint branch (struct opcode_entry *op);
+uint dbranch (struct opcode_entry *op);
+uint shiftreg (struct opcode_entry *op);
+uint op2_bcdx (struct opcode_entry *op);
+uint scc (struct opcode_entry *op);
+uint exg (struct opcode_entry *op);
+uint movesrccr (struct opcode_entry *op);
+uint cmpm (struct opcode_entry *op);
+uint movep (struct opcode_entry *op);
+uint bkpt (struct opcode_entry *op);
+uint muldivl (struct opcode_entry *op);
+uint bitfield (struct opcode_entry *op);
+uint trapcc (struct opcode_entry *op);
+uint chkcmp2 (struct opcode_entry *op);
+uint cas (struct opcode_entry *op);
+uint cas2 (struct opcode_entry *op);
+uint moves (struct opcode_entry *op);
+uint link_l (struct opcode_entry *op);
+uint move16 (struct opcode_entry *op);
+uint cache (struct opcode_entry *op);
+uint mov3q (struct opcode_entry *op); /* ColdFire */
+uint invalid2 (struct opcode_sub_entry *op); /* for mmu & fpu subtables */
+
+#define SNG_ALL 1        /* Single operand syntax allowed */
+
+/* opcodes_fpu.c */
+extern struct opcode_sub_entry fpu_opcode_table [];
+extern char *xfer_size [];
+extern UWORD sizes [];
+extern char *fpu_conditions [];
+
+/* opcode_handler_fpu.c */
+uint fpu (struct opcode_entry *op);
+uint fscc (struct opcode_entry *op);
+uint fbranch (struct opcode_entry *op);
+uint ftrapcc (struct opcode_entry *op);
+uint fdbranch (struct opcode_entry *op);
+
+uint std_fpu (struct opcode_sub_entry *op);
+uint fsincos (struct opcode_sub_entry *op);
+uint ftst (struct opcode_sub_entry *op);
+
+
+/* opcodes_mmu.c */
+extern struct opcode_sub_entry mmu_opcode_table [];
+
+/* opcode_handler_mmu.c */
+uint plpa60 (struct opcode_entry *op);
+uint pflush40 (struct opcode_entry *op);
+uint ptest40 (struct opcode_entry *op);
+uint mmu30 (struct opcode_entry *op);
+uint ptest30 (struct opcode_entry *op);
+
+uint pfl_or_ld (struct opcode_sub_entry *op);
+uint pflush30 (struct opcode_sub_entry *op);
+uint pmove30 (struct opcode_sub_entry *op);
+
+/* amiga.c */
+BOOL user_aborted_analysis (void);
+void delete_tmp_files (void);
+#ifdef AMIGA
+void use_host_cpu_type (void);
+ULONG req_off (void);
+void req_on (ULONG oldwindowptr);
+#endif
+
+/* version.c */
+void print_version (void);
+
+/* jmptab.c */
+void free_jmptab_list (void);
+void enter_jmptab (ULONG start, ULONG offset);
+BOOL next_code_ref_from_jmptab (UBYTE *seg);
+/* BOOL invalidate_last_jmptab_entry (void); */
+BOOL find_and_format_jmptab (char *to, WORD current_w);
+#ifdef DEBUG
+void print_jmptab_list (void);
+#endif
+
+/* library.c */
+void enter_library_refs (UBYTE *seg);
diff --git a/cputest/adis/globals.c b/cputest/adis/globals.c
new file mode 100644 (file)
index 0000000..79d472f
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Change history
+ * $Log:       globals.c,v $
+ *
+ * Revision 3.1  09/10/19 Matt_Hey
+ * New feature: Added cpu68060 support
+ *
+ * Revision 3.0  93/09/24  17:54:00  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.1  93/07/18  22:55:57  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.0  93/07/01  11:54:00  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.15  93/07/01  11:39:52  Martin_Apel
+ * Minor mod.: Prepared for tabs instead of spaces.
+ * Minor mod.: Added 68030 opcodes to disable list
+ * 
+ * Revision 1.14  93/06/19  12:08:38  Martin_Apel
+ * Major mod.: Added full 68030/040 support
+ * 
+ * Revision 1.13  93/06/16  20:28:04  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * Minor mod.: Added variables for 68030 / 040 support
+ * 
+ * Revision 1.12  93/06/06  13:46:34  Martin_Apel
+ * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
+ * 
+ * Revision 1.11  93/06/06  00:11:41  Martin_Apel
+ * Major mod.: Added support for library/device disassembly (option -dl)
+ * 
+ * Revision 1.10  93/06/04  11:50:40  Martin_Apel
+ * New feature: Added -ln option for generation of ascending label numbers
+ * 
+ * Revision 1.9  93/06/03  20:27:16  Martin_Apel
+ * New feature: Added -a switch to generate comments for file offsets
+ * 
+ * Revision 1.8  93/06/03  18:31:10  Martin_Apel
+ * Minor mod.: Added hunk_end array
+ * Minor mod.: Remove temporary files upon exit (even with CTRL-C)
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: globals.c,v 3.0 93/09/24 17:54:00 Martin_Apel Exp $"; */
+
+UBYTE *hunk_address;
+UBYTE *flags;
+UWORD *code;
+ULONG current_ref;
+ULONG first_ref;
+ULONG last_ref;
+ULONG total_size;
+ULONG current_hunk;
+ULONG *hunk_start = NULL,
+      *hunk_end = NULL,
+      *hunk_offset = NULL,
+      *hunk_memtype = NULL;
+
+ULONG f_offset;
+FILE *in = NULL,
+     *out = NULL,
+     *tmp_f = NULL;
+char *in_buf = NULL,
+     *out_buf = NULL;
+char *input_filename = NULL;
+char *output_filename = NULL;
+char *fd_filename = NULL;
+
+/* Variables for options */
+
+int OPCODE_COL = 3;               /* def column instructions */
+int PARAM_COL = 12;               /* def column paramaters */
+int COMMENT_COL = 40;             /* def column comments */
+int MAX_STR_COL = 77;             /* max column for dc.b string */
+
+int buf_size = DEF_BUF_SIZE;       /* -f */
+
+/* Try to resolve addressing used by many compilers in small mode. */
+/* (Addressing relative to A4) */
+long a4_offset = -1;
+BOOL try_small = FALSE;             /* -b */
+
+BOOL single_file = TRUE;                                   
+BOOL print_illegal_instr_offset = FALSE;         /* -i */
+BOOL old_style = FALSE;
+BOOL cpu68020 = FALSE,              /* -m2 */
+     cpu68030 = FALSE,              /* -m3 */
+     cpu68040 = FALSE,              /* -m4 */
+     cpu68060 = FALSE,              /* -m6 */
+     cpuCF = FALSE,
+     fpu68881 = FALSE;              /* -m8 */
+BOOL disasm_as_lib = FALSE;         /* -l */
+BOOL ascending_label_numbers = FALSE;   /* -dn */
+BOOL verbose = FALSE;
+BOOL optimize = TRUE;
+BOOL branch_sizes = TRUE;
+BOOL instr_bad;
+BOOL instr_end;
+char pass;
+char space_char = ' ';  /* space or tab for column seperator */
+char comment = 0;                   /* -a */
+
+ULONG InitTableRef = 0;
+ULONG FuncTableRef = 0;
+ULONG DataTableRef = 0;
+ULONG ROMTagRef = 0;
+BOOL  ROMTagFound = FALSE;
+UBYTE ROMTagType;
+
+char spaces [44];  /* storage for leading spaces before instructions */
+char opcode [20];  /* storage for instruction name (mnemonic) */
+char src [200];    /* storage for source op */
+char dest [200];   /* storage for destination op */
+
+char *conditions [] =
+  {
+  "t",
+  "f",
+  "hi",
+  "ls",
+  "cc",
+  "cs",
+  "ne",
+  "eq",
+  "vc",
+  "vs",
+  "pl",
+  "mi",
+  "ge",
+  "lt",
+  "gt",
+  "le"
+  };
+
+char *reg_names [] =
+  {
+  "d0",
+  "d1",
+  "d2",
+  "d3",
+  "d4",
+  "d5",
+  "d6",
+  "d7",
+  "a0",
+  "a1",
+  "a2",
+  "a3",
+  "a4",
+  "a5",
+  "a6",
+  "sp",
+  "pc",       /* Start at offset 17 */
+  "fp0",
+  "fp1",
+  "fp2",
+  "fp3",
+  "fp4",
+  "fp5",
+  "fp6",
+  "fp7"
+  };
+
+char *special_regs [] =
+  {
+  "sr",        /* 0 */
+  "ccr",       /* 1 */
+  "usp",       /* 2 */
+  "sfc",       /* 3 */
+  "dfc",       /* 4 */
+  "cacr",      /* 5 */
+  "vbr",       /* 6 */
+  "caar",      /* 7 */
+  "msp",       /* 8 */
+  "isp",       /* 9 */
+  "tc",        /* 10 */
+  "itt0",      /* 11 */
+  "itt1",      /* 12 */
+  "dtt0",      /* 13 */
+  "dtt1",      /* 14 */
+  "mmusr",     /* 15 */
+  "urp",       /* 16 */
+  "srp",       /* 17 */
+  "tt0",       /* 18 */
+  "tt1",       /* 19 */
+  "crp"        /* 20 */
+  };
+
+/**********************************************************************/
+/*      When the program is compiled for use on a 68020 system,       */
+/*        68020 instructions disassembly can be switched off          */
+/*                     via a command line switch.                     */
+/*      Then those following instructions are marked as illegal       */
+/**********************************************************************/
+
+short cpu68020_disabled [] =
+  {
+    3, /* CHK2, CMP2 */
+   11, /* CHK2, CMP2 */
+   19, /* CHK2, CMP2 */
+   27, /* CALLM */
+   43, /* CAS */
+   51, /* CAS */
+   56, /* MOVES */
+   57, /* MOVES */
+   58, /* MOVES */
+   59, /* CAS */
+  260, /* CHK.L */
+  268, /* CHK.L */
+  276, /* CHK.L */
+  284, /* CHK.L */
+  292, /* CHK.L */
+  300, /* CHK.L */
+  304, /* MUL .L */
+  305, /* DIV .L */
+  308, /* CHK.L */
+  316, /* CHK.L */
+  931, /* BFTST */
+  935, /* BFEXTU */
+  939, /* BFCHG */
+  943, /* BFEXTS */
+  947, /* BFCLR */
+  951, /* BFFFO */
+  955, /* BFSET */
+  959, /* BFINS */
+ 1027, /* RTM */
+ 1028, /* UNPK */
+ 1032, /* PACK */
+ 1040, /* CAS2 */
+ 1041, /* CAS2 */
+ 1042, /* CAS2 */
+ 1045, /* TRAPcc */
+ 1049, /* BKPT */
+ 1051, /* EXTB.L */
+    0
+  };
+
+short fpu68881_disabled [] =
+  {
+  968, /* General fpu opcode */
+  969, /* FScc */
+  970, /* FBcc */
+  971, /* FBcc */
+  972, /* FSAVE */
+  973, /* FRESTORE */
+ 1047, /* FDBcc */
+ 1048, /* FTRAPcc */
+    0
+  };
+
+short cpu68030_disabled [] =
+  {
+  960, /* MMU instructions */
+  0
+  };
+
+short cpu68040_disabled [] =
+  {
+  976, /* CPUSH, CINV */
+  977, /* CPUSH, CINV */
+  978, /* CPUSH, CINV */
+  979, /* CPUSH, CINV */
+  980, /* PFLUSH */
+  981, /* PTEST */
+  984, /* MOVE16 */
+    0
+  };
+
+short cpu68060_disabled [] =
+  {
+  982, /* PLPAW */
+  983, /* PLPAR */
+    0
+  };
+
+short cpuCF_disabled [] =
+  {
+  452, /* MVS.B */
+  453, /* MVS.W */
+  454, /* MVZ.B */
+  455, /* MVZ.W */
+  460, /* MVS.B */
+  461, /* MVS.W */
+  462, /* MVZ.B */
+  463, /* MVZ.W */
+  468, /* MVS.B */
+  469, /* MVS.W */
+  470, /* MVZ.B */
+  471, /* MVZ.W */
+  476, /* MVS.B */
+  477, /* MVS.W */
+  478, /* MVZ.B */
+  479, /* MVZ.W */
+  484, /* MVS.B */
+  485, /* MVS.W */
+  486, /* MVZ.B */
+  487, /* MVZ.W */
+  492, /* MVS.B */
+  493, /* MVS.W */
+  494, /* MVZ.B */
+  495, /* MVZ.W */
+  500, /* MVS.B */
+  501, /* MVS.W */
+  502, /* MVZ.B */
+  503, /* MVZ.W */
+  508, /* MVS.B */
+  509, /* MVS.W */
+  510, /* MVZ.B */
+  511, /* MVZ.W */
+  645, /* MOV3Q */
+  653, /* MOV3Q */
+  661, /* MOV3Q */
+  669, /* MOV3Q */
+  677, /* MOV3Q */
+  685, /* MOV3Q */
+  693, /* MOV3Q */
+  701, /* MOV3Q */
+ 1056, /* BITREV */
+ 1057, /* BYTEREV */
+ 1058, /* FF1 */
+ 1059, /* SATS */
+    0
+  };
diff --git a/cputest/adis/opcode_handler_cpu.c b/cputest/adis/opcode_handler_cpu.c
new file mode 100644 (file)
index 0000000..4afbc9f
--- /dev/null
@@ -0,0 +1,1220 @@
+/*
+ * Change history
+ * $Log:       opcode_handler_cpu.c,v $
+ *
+ * Revision 3.1  09/10/15  Matt Hey
+ * Fixed mulsl.l, mulul.l, bf width of 32
+ *
+ * Revision 3.0  93/09/24  17:54:12  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.2  93/07/18  22:56:17  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.1  93/07/08  20:48:55  Martin_Apel
+ * Minor mod.: Disabled internal error message in non-debugging version
+ * 
+ * Revision 2.0  93/07/01  11:54:21  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.14  93/07/01  11:41:49  Martin_Apel
+ * Minor mod.: Now checks for zero upper byte on using CCR
+ * 
+ * Revision 1.13  93/06/16  20:28:56  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * Minor mod.: Added variables for 68030 / 040 support
+ * 
+ * Revision 1.12  93/06/06  13:47:17  Martin_Apel
+ * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
+ * 
+ * Revision 1.11  93/06/03  20:28:42  Martin_Apel
+ * Minor mod.: Additional linefeed generation for end instructions has been
+ *             moved to format_line
+ * 
+ * Revision 1.10  93/05/27  20:47:51  Martin_Apel
+ * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM
+ *          instructions.
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: opcode_handler_cpu.c,v 3.1 09/10/15 Martin_Apel Exp $"; */
+
+/**********************************************************************/
+
+uint EA_to_Rn (struct opcode_entry *op)
+
+/* 2 op instruction where src is an EA and dest is a register (op->param)  */
+{
+if (pass3)
+  str_cpy (dest, reg_names [op->param]);
+return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), op->access, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint Rn_to_EA (struct opcode_entry *op)
+
+/* 2 op instruction where src is a register (op->param) and dest is an EA  */
+{
+if (pass3)
+  str_cpy (src, reg_names [op->param]);
+return (decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), op->access, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint op1 (struct opcode_entry *op)
+
+/* handler for 1 op instructions */
+{
+return (decode_ea (src, MODE_NUM(*code), REG_NUM(*code), op->access, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint op1_end (struct opcode_entry *op)
+
+/* handler for a single operand instruction ending an instruction sequence
+   i.e. jmp rtm */
+{
+instr_end = TRUE;
+return (decode_ea (src, MODE_NUM(*code), REG_NUM(*code), op->access, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint quick (struct opcode_entry *op)
+
+/* handler for addq and subq */
+{
+if (pass3)
+  {
+  char *to;
+
+  to = src;
+  *to++ = '#';
+  *to++ = (UBYTE)(op->param) + '0';
+  *to = 0;
+  }
+return (decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), op->access, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint moveq (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  char *to;
+  to = src;
+  *to++ = '#';
+  format_x (to, (BYTE)(*code));
+  str_cpy (dest, reg_names [op->param]);
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+uint move (struct opcode_entry *op)
+
+{
+uint used;
+
+used = decode_ea (src, MODE_NUM (*code), REG_NUM (*code), op->access, 1);
+used += decode_ea (dest,((*code >> 6) & 0x7), ((*code >> 9) & 0x7),
+                     op->access, used + 1);
+return (used + 1);
+}
+
+/**********************************************************************/
+
+uint movem (struct opcode_entry *op)
+
+{
+char *reg_list;
+uint used;
+
+if (op->param == REG_TO_MEM)
+  {
+  /* Transfer registers to memory */
+  reg_list = src;
+  used = decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), ACC_DATA, 2);
+  }
+else
+  {
+  reg_list = dest;
+  used = decode_ea (src, MODE_NUM (*code), REG_NUM (*code), ACC_DATA, 2);
+  }
+
+if (pass3)
+  {
+  format_reg_list (reg_list, *(code + 1), (MODE_NUM (*code) != 4), 0);
+  if (*reg_list == 0)
+    {
+    /* some compilers generate empty reg lists for movem instructions */
+    *reg_list++ = '#';
+    *reg_list++ = '0';
+    *reg_list = 0;
+    }
+  }
+return (used + 2);
+}
+
+/**********************************************************************/
+
+uint imm_b (struct opcode_entry *op)
+
+/* handler for ori.b andi.b eori.b subi.b addi.b cmpi.b callm */
+{
+ULONG instr = *(ULONG*)code;
+
+if ((instr & 0xfc0000ff) == 0)  /* if ori.b #0,ea or andi.b #0,ea */
+  {
+  /* ori.b #0,ea and andi.b #0,ea are probably not code */
+  instr_bad = TRUE;
+  return (1);
+  }
+instr &= 0x0000ff00;
+if (!((instr == 0) || (instr == 0x0000ff00)))  /* GCC immediate may be $ffxx */
+  {
+  /* probably not code if upper byte of immediate has trash */
+  instr_bad = TRUE;
+  return (1);
+  }
+
+if (pass3)
+  {
+  char *to;
+  to = src;
+  *to++ = '#';
+  format_ux (to, (*(code + 1) & 0xff));
+  }
+return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), op->access, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint imm_w (struct opcode_entry *op)
+
+/* handler for ori.w andi.w eori.w subi.w addi.w cmpi.w */
+{
+if ((*((ULONG*)code) & 0xfc00ffff) == 0)
+  {
+  /* ori.w #0,ea and andi.w #0,ea are probably not code */
+  instr_bad = TRUE;
+  return (1);
+  }
+
+if (pass3)
+  {
+  char *to;
+  to = src;
+  *to++ = '#';
+  format_ux (to, *(code + 1));
+  }
+return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), op->access, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint imm_l (struct opcode_entry *op)
+
+/* handler for ori.l andi.l eori.l subi.l addi.l cmpi.l */
+{
+register ULONG instr_ext = *(ULONG*)(code + 1);
+
+if ((instr_ext == 0) && (*(code) & 0xfc00) == 0)
+  {
+  /* ori.l #0,ea and andi.l #0,ea are probably not code */
+  instr_bad = TRUE;
+  return (1);
+  }
+
+if (pass2 && FLAGS_RELOC (current_ref + 2))
+  {
+  enter_ref (instr_ext, NULL, ACC_UNKNOWN);
+
+  /*  Needed for jump tables?
+  if (EVEN (instr_ext) && instr_ext >= first_ref && instr_ext < last_ref)
+    last_code_reference = instr_ext;
+  */
+  }
+else if (pass3)
+  {
+  char *to;
+
+  to = src;
+  *to++ = '#';  
+  if (FLAGS_RELOC (current_ref + 2))
+    {
+    /* This reference is relocated and thus needs a label */
+    *to++ = '(';
+    to = gen_label_ref (to, instr_ext);
+    *to++ = ')';
+    *to = 0;
+    }
+  else
+    format_ulx (to, instr_ext);
+  }
+return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), op->access, 3) + 3);
+}
+
+/**********************************************************************/
+
+uint bit_reg (struct opcode_entry *op)
+
+{
+UWORD code_w = *code;
+
+if (pass3)
+  str_cpy (src, reg_names [op->param]);
+
+if (MODE_NUM (code_w) == 0)  /* data register */
+  {
+  if (pass3)
+    str_cpy (dest, reg_names [REG_NUM (code_w)]);
+  return (1);
+  }
+else
+  return (decode_ea (dest, MODE_NUM (code_w), REG_NUM (code_w), ACC_BYTE, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint bit_imm (struct opcode_entry *op)
+
+{
+UWORD code_w = *code;
+UWORD data_w = *(code + 1);
+
+if ((data_w & 0xff00) != 0)
+  {
+  /* only bit #0-255 are valid */
+  instr_bad = TRUE;
+  return (1);
+  }
+
+if (pass3)
+  {
+  char *to;
+  to = src;
+  *to++ = '#';
+  format_ux (to, data_w);
+  }
+
+if (MODE_NUM (code_w) == 0)  /* data register */
+  {
+  if (pass3)
+    str_cpy (dest, reg_names [REG_NUM (code_w)]);
+  return (2);
+  }
+else
+  return (decode_ea (dest, MODE_NUM (code_w), REG_NUM(code_w), ACC_BYTE, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint srccr (struct opcode_entry *op)
+
+/* ANDI, ORI, EORI to CCR or SR */
+{
+UWORD size = (*code & 0x00C0) >> 6;  /* size: byte=0 word=1 long=2 */
+/* Only allow word size SR or byte size CCR instructions. */
+if (size == 0 && (*(code + 1) & 0xff00))
+  return (TRANSFER);
+if (pass3)
+  {
+  str_cpy (opcode, opcode_table [*code >> 6].mnemonic);
+  immed (src, (ULONG)(*(code + 1)));
+  str_cpy (dest, special_regs [!size]);
+  }
+return (2);
+}
+
+/**********************************************************************/
+
+uint special (struct opcode_entry *op)
+
+{
+/* move usp,     10dxxx
+   trap,         00xxxx
+   unlk,         011xxx
+   link.w        010xxx
+
+   reset,        110000
+   nop,          110001
+   stop,         110010
+   rte,          110011
+   rtd,          110100
+   rts,          110101
+   trapv         110110
+   rtr,          110111
+
+   movec,        11101d
+*/
+
+char *ptr = NULL;
+uint used = 1;
+
+if ((*code & 0x38) == 0x30)
+  {
+  switch (*code & 0xf)
+    {
+    case 0: ptr = "reset";
+            break;
+    case 1: ptr = "nop";
+            break;
+    case 2: ptr = "stop";
+            if (pass3)
+              immed (src, (ULONG)*(code + 1));
+            used = 2;
+            break;
+    case 3: ptr = "rte";
+            instr_end = TRUE;
+            break;
+    case 4: if (!cpu68020)
+              return (TRANSFER);
+            ptr = "rtd";
+            instr_end = TRUE;
+            if (pass3)
+              {
+              src [0] = '#';
+              format_ux (src + 1, (UWORD)*(code + 1));
+              }
+            used = 2;
+            break;
+    case 5: ptr = "rts";
+            instr_end = TRUE;
+            break;
+    case 6: ptr = "trapv";
+            break;
+    case 7: ptr = "rtr";
+            instr_end = TRUE;
+            break;
+    }
+  if (pass3)
+    str_cpy (opcode, ptr);
+  return (used);
+  }
+else if ((*code & 0x3e) == 0x3a)          /* MOVEC */
+  {
+  short reg_offset;
+
+  if (!cpu68020)
+    return (TRANSFER);
+  switch (*(code + 1) & 0xfff)
+    {
+    case 0x000: ptr = special_regs [SFC];
+                break;
+    case 0x001: ptr = special_regs [DFC];
+                break;
+    case 0x002: ptr = special_regs [CACR];
+                break;
+    case 0x003: if (cpu68040)
+                  ptr = special_regs [TC];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x004: if (cpu68040)
+                  ptr = special_regs [ITT0];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x005: if (cpu68040)
+                  ptr = special_regs [ITT1];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x006: if (cpu68040)
+                  ptr = special_regs [DTT0];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x007: if (cpu68040)
+                  ptr = special_regs [DTT1];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x800: ptr = special_regs [USP];
+                break;
+    case 0x801: ptr = special_regs [VBR];
+                break;
+    case 0x802: ptr = special_regs [CAAR];
+                break;
+    case 0x803: ptr = special_regs [MSP];
+                break;
+    case 0x804: ptr = special_regs [ISP];
+                break;
+    case 0x805: if (cpu68040)
+                  ptr = special_regs [MMUSR];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x806: if (cpu68040)
+                  ptr = special_regs [URP];
+                else
+                  return (TRANSFER);
+                break;
+    case 0x807: if (cpu68040)
+                  ptr = special_regs [SRP];
+                else
+                  return (TRANSFER);
+                break;
+    default : return (TRANSFER);
+    }
+
+  reg_offset = (*(code + 1) & 0x8000) ? 8 : 0;
+  if (pass3)
+    {
+    str_cpy (opcode, "movec.l");
+    if (*code & 0x1)
+      {
+      /* from general register to control register */
+      str_cpy (dest, ptr);
+      str_cpy (src, reg_names [((*(code + 1) >> 12) & 0x7) + reg_offset]);
+      }
+    else
+      {
+      str_cpy (src, ptr);
+      str_cpy (dest, reg_names [((*(code + 1) >> 12) & 0x7) + reg_offset]);
+      }
+    }
+  return (2);
+  }
+else if ((*code & 0x30) == 0)
+  {
+  /* TRAP */
+  if (pass3)
+    {
+    str_cpy (opcode, "trap");
+    src [0] = '#';
+    format_ux (src + 1, (UWORD)(*code & 0xf));
+    }
+  return (1);
+  }
+else if ((*code & 0x38) == 0x10)
+  {
+  /* LINK */
+  if (pass3)
+    {
+    str_cpy (opcode, "link");
+    str_cpy (src, reg_names [(*code & 0x7) + 8]);
+    dest [0] = '#';
+    format_x (dest + 1, (WORD)*(code + 1));
+    }
+  return (2);
+  }
+else if ((*code & 0x38) == 0x18)
+  {
+  /* UNLK */
+  if (pass3)
+    {
+    str_cpy (opcode, "unlk");
+    str_cpy (src, reg_names [(*code & 0x7) + 8]);
+    }
+  return (1);
+  }
+else if ((*code & 0x38) == 0x20)
+  {
+  if (pass3)
+    {
+    str_cpy (opcode, "move.l");
+    str_cpy (dest, special_regs [USP]);
+    str_cpy (src, reg_names [(*code & 0x7) + 8]);
+    }
+  return (1);
+  }
+else if ((*code & 0x38) == 0x28)
+  {
+  if (pass3)
+    {
+    str_cpy (opcode, "move");
+    str_cpy (src, special_regs [USP]);
+    str_cpy (dest, reg_names [(*code & 0x7) + 8]);
+    }
+  return (1);
+  }
+return (TRANSFER);
+}
+
+/**********************************************************************/
+
+uint illegal (struct opcode_entry *op)
+
+/* The official illegal instruction */
+{
+return (1);
+}
+
+/**********************************************************************/
+
+uint invalid (struct opcode_entry *op)
+
+/* unimplemented instruction */
+{
+src [0] = 0;
+dest [0] = 0;
+instr_bad = TRUE;
+return (1);
+}
+
+/**********************************************************************/
+
+uint invalid2 (struct opcode_sub_entry *op)
+
+/* unimplemented instruction in the mmu & fpu sub tables */
+{
+src [0] = 0;
+dest [0] = 0;
+instr_bad = TRUE;
+return (1);
+}
+
+/**********************************************************************/
+
+uint branch (struct opcode_entry *op)
+
+{
+uint used;
+ULONG ref;
+register LONG offset = (BYTE)(*code & 0xff);
+
+if (offset == 0)
+  {
+  /* word displacement */
+  offset = (WORD)*(code + 1);
+  used = 2;
+  }
+else if (offset == -1)
+  {
+  /* long displacement */
+  if (!cpu68020)
+    return (TRANSFER);
+  offset = *(LONG*)(code + 1);
+  used = 3;
+  }
+else
+  {
+  /* byte displacement */
+  used = 1;
+  }
+
+ref = offset + current_ref + 2;
+if (ODD (offset) || ref < first_ref || ref >= last_ref)
+  return (TRANSFER);
+
+if (pass3)
+  {
+  gen_label_ref (src, ref);
+  if (branch_sizes)
+    {
+    if (used == 1)
+      str_cat (opcode, ".b");
+    else if (used == 2)
+      str_cat (opcode, ".w");
+    else
+      str_cat (opcode, ".l");
+    }
+  }
+else
+  {
+  enter_ref (ref, NULL, ACC_CODE);
+  if ((*code & 0xff00) == 0x6000)  /* bra */
+    instr_end = TRUE;  /* NOT on pass3 as it looks better without blank line */
+  }
+return (used);
+}
+
+/**********************************************************************/
+
+uint dbranch (struct opcode_entry *op)
+
+{
+ULONG ref;
+
+if (*(code + 1) & 0x1)  /* branch to an odd address */
+  return (TRANSFER);
+
+if (pass3)
+  str_cpy (src, reg_names [*code & 7]);
+ref = current_ref + 2 + (short)(*(code + 1));
+if (ref < first_ref || ref > last_ref)
+  return (TRANSFER);
+if (pass3)
+  gen_label_ref (dest, ref);
+else
+  enter_ref (ref, NULL, ACC_CODE);
+
+return (2);
+}
+
+/**********************************************************************/
+
+uint shiftreg (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  opcode [1] = 's';
+  opcode [2] = 0;
+  switch ((*code >> 3) & 0x3)
+    {
+    case 0:  /* Arithmetic shift */
+             opcode [0] = 'a';
+             break;
+    case 1:  /* Logical shift */
+             opcode [0] = 'l';
+             break;
+    case 2:  /* Rotate with extend */
+             str_cpy (opcode, "rox");
+             break;
+    case 3:  /* Rotate */
+             opcode [0] = 'r';
+             opcode [1] = 'o';
+             break;
+    }
+  str_cat (opcode, op->mnemonic);
+
+  if (*code & 0x20)
+    {
+    /* shift count is in register */
+    str_cpy (src, reg_names [op->param & 0x7]);
+    /* This is because param gives a shift count of 8, if this bitfield is 0 */
+    }
+  else
+    {
+    /* shift count specified as immediate */
+    src [0] = '#';
+    format_ux (src + 1, (UWORD)op->param);
+    }
+
+  str_cpy (dest, reg_names [REG_NUM (*code)]);
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+uint op2_bcdx (struct opcode_entry *op)
+
+/* For opcodes such as ADDX, SUBX, ABCD, SBCD, PACK, UNPK with only 
+   -(Ax) and Dn addressing allowed */
+{
+char *tmp;
+
+if (pass3)
+  {
+  if (*code & 0x8)
+    {
+    /* -(Ax) addressing */
+    pre_dec (src, (ushort)(REG_NUM (*code) + 8));
+    pre_dec (dest, (ushort)(((*code >> 9) & 0x7) + 8));
+    }
+  else
+    {
+    /* Dn addressing */
+    str_cpy (src, reg_names [REG_NUM (*code)]);
+    str_cpy (dest, reg_names [((*code >> 9) & 0x7)]);
+    }
+  }
+
+if (op->param == NO_ADJ)
+  return (1);
+else
+  {
+  if (pass3)
+    {
+    tmp = dest + strlen (dest);
+    *tmp++ = ',';
+    immed (tmp, (ULONG)*(code + 1));
+    }
+  return (2);
+  }
+}
+
+/**********************************************************************/
+
+uint muldivl (struct opcode_entry *op)
+
+{
+UWORD instr1w = *code;
+UWORD instr2w = *(code + 1);
+UWORD access = ACC_LONG;
+
+if ((instr2w & 0x800) != 0)
+  access |= ACC_SIGNED;
+
+if (pass3)
+  {
+  char *tmp_o;
+  char *tmp_d;
+  register UWORD dr, dq;
+
+  tmp_o = opcode + 3;
+
+  if (access & ACC_SIGNED)
+    *tmp_o++ = 's';
+  else
+    *tmp_o++ = 'u';
+
+  dr = instr2w & 0x7;
+  dq = (instr2w >> 12) & 0x7;
+
+  tmp_d = dest;
+
+  if (instr2w & 0x400)
+    {
+    /* 64-bit operation, size = 1 */
+    tmp_d = str_cpy (tmp_d, reg_names [dr]);
+    *tmp_d++ = ':';
+    }
+  else if ((instr1w & 0x40) && (dr != dq))
+    {
+    /* divl */
+    *tmp_o++ = 'l';
+    tmp_d = str_cpy (tmp_d, reg_names [dr]);
+    *tmp_d++ = ':';
+    }
+  str_cpy (tmp_d, reg_names [dq]);
+  *tmp_o++ = '.';
+  *tmp_o++ = 'l';
+  *tmp_o = 0;
+  }
+return (decode_ea (src, MODE_NUM (instr1w), REG_NUM (instr1w), access, 2) + 2);
+}
+
+/**********************************************************************/
+    
+uint bitfield (struct opcode_entry *op)
+
+{
+uint used;
+UWORD offset, width;
+register char *ptr_ea = NULL, *ptr_dn = NULL;
+
+offset = (*(code + 1) >> 6) & 0x1f;
+width = *(code + 1) & 0x1f;
+
+switch (op->param)
+  {
+  case SINGLEOP: ptr_ea = src;
+                 break;
+  case DATADEST: ptr_ea = src;
+                 ptr_dn = dest;
+                 break;
+  case DATASRC : ptr_ea = dest;
+                 ptr_dn = src;
+                 break;
+  }
+
+used = decode_ea (ptr_ea, MODE_NUM (*code), REG_NUM (*code), ACC_DATA, 2);
+
+if (pass3)
+  {
+  ptr_ea = str_cat (ptr_ea, "{");
+  if (op->param != SINGLEOP)
+    str_cpy (ptr_dn, reg_names [(*(code + 1) >> 12) & 0x7]);
+  }
+
+if (*(code + 1) & 0x800)
+  {
+  /* Offset specified in register */
+  if (offset > 7)
+    return (TRANSFER);
+  if (pass3)
+    ptr_ea = str_cpy (ptr_ea, reg_names [offset]);
+  }
+else if (pass3)
+  {
+  /* Offset specified as immediate */
+  ptr_ea = format_ux (ptr_ea, offset);
+  }
+
+if (pass3)
+  *ptr_ea++ = ':';
+
+if (*(code + 1) & 0x20)
+  {
+  /* Width specified in register */
+  if (width > 7)
+    return (TRANSFER);
+  if (pass3)
+    ptr_ea = str_cpy (ptr_ea, reg_names [width]);
+  }
+else if (pass3)
+  {
+  /* Width specified as immediate */
+  if (!width)
+    width = 0x20;
+  ptr_ea = format_ux (ptr_ea, width);
+  }
+
+if (pass3)
+  {
+  *ptr_ea++ = '}';
+  *ptr_ea = 0;
+  }
+
+return (2 + used);
+}
+
+/**********************************************************************/
+
+uint scc (struct opcode_entry *op)
+
+{
+if (pass3)
+  str_cat (opcode, conditions [(*code >> 8) & 0xf]);
+return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), ACC_BYTE, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint exg (struct opcode_entry *op)
+
+{
+UWORD rx = (*code >> REG2_SHIFT) & 0x7;
+
+if (((*code >> 3) & 0x1f) == 0x8)
+  {
+  /* exchange two data registers */
+  if (pass3)
+    {
+    str_cpy (src, reg_names [rx]);
+    str_cpy (dest, reg_names [*code & 0x7]);
+    }
+  }
+else if (((*code >> 3) & 0x1f) == 0x9)
+  {
+  /* exchange two address registers */
+  if (pass3)
+    {
+    str_cpy (src, reg_names [rx + 8]);
+    str_cpy (dest, reg_names [(*code & 0x7) + 8]);
+    }
+  }
+else if (((*code >> 3) & 0x1f) == 0x11)
+  {
+  /* exchange an address and a data register */
+  if (pass3)
+    {
+    str_cpy (src, reg_names [rx]);
+    str_cpy (dest, reg_names [(*code & 0x7) + 8]);
+    }
+  }
+else
+  return (TRANSFER);
+return (1);
+}
+
+/**********************************************************************/
+
+uint trapcc (struct opcode_entry *op)
+
+{
+if (pass3)
+  str_cat (opcode, conditions [(*code >> 8) & 0xf]);
+if ((*code & 0x7) == 2)
+  {
+  if (pass3)
+    immed (src, (ULONG)*(code + 1));
+  return (2);
+  }
+if ((*code & 0x7) == 3)
+  {
+  if (pass3)
+    immed (src, *(ULONG*)(code + 1));
+  return (3);
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+uint chkcmp2 (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  if (*(code + 1) & 0x800)
+    {
+    /* CHK2 */
+    opcode [1] = 'h';
+    opcode [2] = 'k';
+    }
+  else
+    {
+    /* CMP2 */
+    opcode [1] = 'm';
+    opcode [2] = 'p';
+    }
+  if (pass3)
+    str_cpy (dest, reg_names [*(code + 1) >> 12]);
+  }
+return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), op->access, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint cas (struct opcode_entry *op)
+
+{
+register char *tmp_s;
+
+if (pass3)
+  {
+  tmp_s = str_cpy (src, reg_names [*(code + 1) & 0x7]);
+  *tmp_s++ = ',';
+  str_cpy (tmp_s, reg_names [(*(code + 1) >> 6) & 0x7]);
+  }
+return (decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), op->access, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint cas2 (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  sprintf (src, "%s:%s,%s:%s", reg_names [*(code + 1) & 0x7],
+                               reg_names [*(code + 2) & 0x7],
+                               reg_names [(*(code + 1) >> 6) & 0x7],
+                               reg_names [(*(code + 2) >> 6) & 0x7]);
+
+  sprintf (dest, "(%s):(%s)",  reg_names [*(code + 1) >> 12],
+                               reg_names [*(code + 2) >> 12]);
+  }
+return (3);
+}
+
+/**********************************************************************/
+
+uint moves (struct opcode_entry *op)
+
+{
+char *reg, *ea;
+
+if (*(code + 1) & 0x800)
+  {
+  reg = src;
+  ea = dest;
+  }
+else
+  {
+  reg = dest;
+  ea = src;
+  }
+
+if (pass3)
+  str_cpy (reg, reg_names [(*(code + 1) >> 12) & 0xf]);
+return (decode_ea (ea, MODE_NUM (*code), REG_NUM (*code), op->access, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint movesrccr (struct opcode_entry *op)
+
+{
+char *ea = NULL;
+
+if (pass3)
+  {
+  switch (op->param)
+    {
+    case FROM_CCR: str_cpy (src, special_regs [CCR]);
+                   ea = dest;
+                   break;
+    case TO_CCR  : str_cpy (dest, special_regs [CCR]);
+                   ea = src;
+                   break;
+    case FROM_SR : str_cpy (src, special_regs [SR]);
+                   ea = dest;
+                   break;
+    case TO_SR   : str_cpy (dest, special_regs [SR]);
+                   ea = src;
+                   break;
+    }
+  }
+return (decode_ea (ea, MODE_NUM (*code), REG_NUM (*code), ACC_WORD, 1) + 1);
+}
+
+/**********************************************************************/
+
+uint cmpm (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  post_inc (src, (*code & 0xf));
+  post_inc (dest, ((*code >> 9) & 0xf));
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+uint movep (struct opcode_entry *op)
+
+{
+char *dn, *an;
+
+if (pass3)
+  {
+  if (*code & 0x40)
+    str_cat (opcode, ".l");
+  else
+    str_cat (opcode, ".w");
+  }
+if (*code & 0x80)
+  {
+  /* Transfer to memory */
+  an = dest;
+  dn = src;
+  }
+else
+  {
+  /* Transfer from memory */
+  an = src;
+  dn = dest;
+  }
+
+if (pass3)
+  {
+  str_cpy (dn, reg_names [(*code >> 9) & 0x7]);
+  disp_an (an, ((*code & 0x7) + 8), *(code + 1));
+  }
+return (2);
+}
+
+/**********************************************************************/
+
+uint bkpt (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  src [0] = '#';
+  format_ux (src + 1, (UWORD)(*code & 0x7));
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+uint link_l (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  dest [0] = '#';
+  format_ulx (dest + 1, *(ULONG*)(code + 1));
+  str_cpy (src, reg_names [REG_NUM (*code) + 8]);
+  }
+return (3);
+}
+
+/**********************************************************************/
+
+uint move16 (struct opcode_entry *op)
+
+{
+char *tmp;
+
+if ((*code & 0x20) && ((*(code + 1) & 0x8fff) == 0x8000))
+  {  /* post increment mode for src and dest */
+  if (pass3)
+    {
+    post_inc (src, (*code & 0x7) + 8);
+    post_inc (dest, ((*(code + 1) >> 12) & 0x7) + 8);
+    }
+  return (2);
+  }
+else if ((*code & 0x20) == 0)
+  {
+  if (pass3)
+    {
+    if (*code & 0x8)    
+      {
+      tmp = dest;
+      decode_ea (src, 7, 1, ACC_LONG, 1);
+      }
+    else
+      {
+      tmp = src;
+      decode_ea (dest, 7, 1, ACC_LONG, 1);
+      }
+    if (*code & 0x10)
+      indirect (tmp, (*code & 0x7) + 8);
+    else
+      post_inc (tmp, (*code & 0x7) + 8);
+    }
+  return (3);
+  }
+return (TRANSFER);
+}
+
+/**********************************************************************/
+
+uint cache (struct opcode_entry *op)
+
+{
+char *tmp_o;
+
+if (pass3)
+  {
+  if (*code & 0x20)
+    tmp_o = str_cpy (opcode, "cpush");
+  else
+    tmp_o = str_cpy (opcode, "cinv");
+  switch ((*code >> 3) & 0x3)
+    {
+    case 1: *tmp_o++ = 'l'; break;
+    case 2: *tmp_o++ = 'p'; break;
+    case 3: *tmp_o++ = 'a'; break;
+    }
+  *tmp_o = 0;
+
+  switch (op->param)          /* which cache to modify */
+    {
+    case 0: str_cpy (src, "nc"); break;
+    case 1: str_cpy (src, "dc"); break;
+    case 2: str_cpy (src, "ic"); break;
+    case 3: str_cpy (src, "bc"); break;
+    }
+
+  if (((*code >> 3) & 0x3) != 0x3)      /* not all --> page or line */
+    indirect (dest, (REG_NUM (*code) + 8));
+  }
+return (1);
+}
+
+/**********************************************************************
+ ColdFire handlers
+**********************************************************************/
+
+uint mov3q (struct opcode_entry *op)
+
+/* handler for ColdFire mov3q */
+{
+if (pass3)
+  {
+  char *to;
+  to = src;
+  *to++ = '#';
+  UBYTE data = (UBYTE)op->param;
+  if (data)
+    *to++ = data + '0';
+  else
+    {
+    *to++ = '-';
+    *to++ = '1';
+    }
+  *to = 0;
+  }
+return (decode_ea (dest, MODE_NUM(*code), REG_NUM(*code), ACC_LONG, 1) + 1);
+}
diff --git a/cputest/adis/opcode_handler_fpu.c b/cputest/adis/opcode_handler_fpu.c
new file mode 100644 (file)
index 0000000..3a78308
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * Change history:
+ * $Log:       opcode_handler_fpu.c,v $
+ * Revision 3.0  93/09/24  17:54:15  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.1  93/07/18  22:56:24  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.0  93/07/01  11:54:27  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.7  93/06/16  20:29:03  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * Minor mod.: Added variables for 68030 / 040 support
+ * 
+ * Revision 1.6  93/06/06  13:47:37  Martin_Apel
+ * Minor mod.: Replaced first_pass and read_symbols by pass1, pass2, pass3
+ * 
+ * Revision 1.5  93/05/27  20:48:41  Martin_Apel
+ * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM
+ *          instructions.
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: opcode_handler_fpu.c,v 3.0 93/09/24 17:54:15 Martin_Apel Exp $"; */
+
+/**********************************************************************/
+
+uint fpu (struct opcode_entry *op)
+
+{
+uint used;
+char *reg_list,
+     *ea;
+register char *tmp = NULL;
+uint num_regs;
+register UWORD instr_word1;
+register UWORD instr_word2;
+register UWORD mode;
+
+instr_word1 = *code;
+instr_word2 = *(code + 1);
+mode = MODE_NUM (instr_word1);
+if ((instr_word2 & 0xfc00) == 0x5c00)
+  {
+  /* fmovecr */
+  if (pass3)
+    {
+    str_cpy (opcode, "fmovecr.x");
+    immed (src, (ULONG)(instr_word2 & 0x7f));
+    str_cpy (dest, reg_names [17 + ((instr_word2 >> 7) & 0x7)]);
+    }
+  return (2);
+  }
+else
+  {
+  switch (instr_word2 >> 13)
+    {
+    case 0:
+    case 2: /* Use the fpu_opcode_table */
+            if ((instr_word2 & 0x0040) && !cpu68040)
+              return (TRANSFER);
+            struct opcode_sub_entry *subop;
+            subop = &(fpu_opcode_table [instr_word2 & 0x7f]);
+            return ((*subop->handler) (subop));
+
+    case 3: /* fmove from FPx */
+            if (pass3)
+              {
+              tmp = str_cpy (opcode, "fmove");
+              str_cpy (tmp, xfer_size [(instr_word2 >> 10) & 0x7]);
+              str_cpy (src, reg_names [17 + ((instr_word2 >> 7) & 0x7)]);
+              }
+            used = decode_ea (dest, mode, REG_NUM (instr_word1), 
+                              sizes [(instr_word2 >> 10) & 0x7], 2);
+            if ((instr_word2 & 0x1c00) == 0x0c00)
+              {
+              /* Packed decimal real with static k-factor */
+              if (pass3)
+                {
+                tmp = dest + strlen (dest);
+                *tmp++ = '{';
+                tmp = immed (tmp, (ULONG)(instr_word2 & 0x7f));
+                *tmp++ = '}';
+                *tmp = 0;
+                  /* Same as:
+                     sprintf (dest + strlen (dest), "{#$%x}", 
+                              instr_word2 & 0x7f);
+                  */
+                }
+              }
+            else if ((instr_word2 & 0x1c00) == 0x1c00)
+              {
+              /* Packed decimal real with dynamic k-factor */
+              if (pass3)
+                {
+                tmp = dest + strlen (dest);
+                *tmp++ = '{';
+                tmp = str_cpy (tmp, reg_names [(instr_word2 >> 4) & 0x7]);
+                *tmp++ = '}';
+                *tmp = 0;
+                /* Same as:
+                   sprintf (dest + strlen (dest), "{%s}", 
+                            reg_names [(instr_word2 >> 4) & 0x7]);
+                */
+                }
+              }
+            return (2 + used);
+
+    case 4: 
+    case 5: /* fmove.l and fmovem.l control registers */
+            num_regs = 0;
+            if (pass3)
+              tmp = str_cpy (opcode, "fmove");
+            if (instr_word2 & 0x2000)
+              {
+              ea = dest;
+              reg_list = src;
+              }
+            else
+              {
+              ea = src;
+              reg_list = dest;
+              }
+            used = decode_ea (ea, mode, REG_NUM (instr_word1), ACC_LONG, 2);
+            if (pass3)
+              {
+              if (instr_word2 & 0x1000)
+                {
+                reg_list = str_cpy (reg_list, "fpcr");
+                num_regs++;
+                }
+              if (instr_word2 & 0x0800)
+                {
+                if (num_regs != 0)
+                  *reg_list++ = '/';
+                reg_list = str_cpy (reg_list, "fpsr");
+                num_regs++;
+                }
+              if (instr_word2 & 0x0400)
+                {
+                if (num_regs != 0)
+                  *reg_list++ = '/';
+                str_cpy (reg_list, "fpiar");
+                num_regs++;
+                }
+              if (num_regs > 1)
+                *tmp++ = 'm';  /* for fmovem.l */
+              *tmp++ = '.';
+              *tmp++ = 'l';
+              *tmp = 0;
+              }
+            return (2 + used);
+
+    case 6:
+    case 7: /* fmovem.x */
+            if (mode < 2 || (instr_word1 & 0x3f) == 0x3c)  /* dn, an || immediate */
+              return (TRANSFER);
+            if (instr_word2 & 0x2000)
+              {
+              /* registers to memory */
+              if (mode == 3 || (instr_word1 & 0x3f) >= 0x3a)  /* (an)+ || pc modes */
+                return (TRANSFER);
+              reg_list = src;
+              ea = dest;
+              }
+            else
+              {
+              /* memory to registers */
+              if (mode == 4)  /* -(an) */
+                return (TRANSFER);
+              reg_list = dest;
+              ea = src;
+              }
+
+            if (pass3)
+              {
+              str_cpy (opcode, "fmovem.x");
+              if (instr_word2 & 0x0800)
+                {
+                /* Dynamic register list in data register */
+                str_cpy (reg_list, reg_names [(instr_word2 >> 4) & 0x7]);
+                }
+              else
+                {
+                /* Test for predecrement mode */
+                if (mode == 4)
+                  format_reg_list (reg_list, (instr_word2 & 0xff),
+                                   TRUE, 17);
+                else
+                  format_reg_list (reg_list, (instr_word2 << 8),
+                                   FALSE, 17);
+                }
+              }
+            return (decode_ea (ea, mode, REG_NUM (instr_word1), ACC_EXTEND, 2) + 2);
+    }
+  }
+return (TRANSFER);
+}
+
+/**********************************************************************/
+
+uint fbranch (struct opcode_entry *op)
+
+{
+LONG offset;
+ULONG ref;
+uint used;
+
+if (pass3)
+  str_cat (opcode, fpu_conditions [*code & 0x1f]);
+if (!op->param)
+  {
+  offset = (WORD)*(code + 1);
+  used = 2;
+  }
+else
+  {
+  offset = *(LONG*)(code + 1);
+  used = 3;
+  }
+
+if (offset == 0 && pass3)
+  str_cpy (opcode, "fnop");
+else if (offset != 0)
+  {
+  ref = current_ref + 2 + offset;
+  if (ref < first_ref || ref > last_ref)
+    return (TRANSFER);
+  if (pass3)
+    {
+    gen_label_ref (src, ref);
+    if (branch_sizes)
+      {
+      if (used == 2)
+        str_cat (opcode, ".w");
+      else
+        str_cat (opcode, ".l");
+      }
+    }
+  else
+    enter_ref (ref, NULL, ACC_CODE);
+  }
+return (used);
+}
+
+/**********************************************************************/
+
+uint fdbranch (struct opcode_entry *op)
+
+{
+ULONG ref;
+
+if ((*(code + 1) & 0xffe0) != 0)
+  return (TRANSFER);
+if ((*code & 0x0038) != 0x8)
+  return (TRANSFER);
+if (pass3)
+  {
+  str_cat (opcode, fpu_conditions [*(code + 1)]);
+  str_cpy (src, reg_names [*code & 0x7]);
+  }
+ref = current_ref + 4 + (WORD)*(code + 2);
+if (ref < first_ref || ref > last_ref)
+  return (TRANSFER);
+if (pass3)
+  gen_label_ref (dest, ref);
+else
+  enter_ref (ref, NULL, ACC_CODE);
+return (3);
+}
+
+/**********************************************************************/
+
+uint fscc (struct opcode_entry *op)
+
+{
+if ((*(code + 1) & 0xffe0) != 0)
+  return (TRANSFER);
+
+if (pass3)
+  str_cat (opcode, fpu_conditions [*(code + 1)]);
+return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), ACC_BYTE, 2) + 2);
+}
+
+/**********************************************************************/
+
+uint ftrapcc (struct opcode_entry *op)
+
+{
+if ((*(code + 1) & 0xffe0) != 0)
+  return (TRANSFER);
+if (pass3)
+  str_cat (opcode, fpu_conditions [*(code + 1)]);
+if ((*code & 0x7) == 2)
+  {
+  if (pass3)
+    immed (src, (ULONG)*(code + 2));
+  return (3);
+  }
+if ((*code & 0x7) == 3)
+  {
+  if (pass3)
+    immed (src, *(ULONG*)(code + 2));
+  return (4);
+  }
+
+return (2);
+}
+
+/**********************************************************************
+ fpu_opcode_table (opcodes_fpu.c) instructions using an opcode_sub_entry
+**********************************************************************/
+
+uint std_fpu (struct opcode_sub_entry *op)
+
+{
+char *tmp_op = NULL;
+
+if (pass3)
+  {
+  tmp_op = str_cpy (opcode, op->mnemonic);
+  str_cpy (dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]);
+  }
+if (*(code + 1) & 0x4000)          /* R/M - Bit */
+  {
+  if (pass3)
+    str_cpy (tmp_op, xfer_size [(*(code + 1) >> 10) & 0x7]);
+  return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), 
+                     sizes [(*(code + 1) >> 10) & 0x7], 2) + 2);
+  }
+else if (pass3)
+  {
+  str_cpy (tmp_op, xfer_size [2]);       /* ".X" */
+  str_cpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]);
+  }
+
+if ((src [2] == dest [2]) && (op->param == SNG_ALL))      /* single operand */
+  dest [0] = 0;
+return (2);
+}
+
+/**********************************************************************/
+
+uint ftst (struct opcode_sub_entry *op)
+
+/* ftst is unusual because it only allows 1 opcode */
+{
+char *tmp_op = NULL;
+
+if (pass3)
+  tmp_op = str_cpy (opcode, op->mnemonic);
+if (*(code + 1) & 0x4000)          /* R/M - Bit */
+  {
+  if (pass3)
+    str_cpy (tmp_op, xfer_size [(*(code + 1) >> 10) & 0x7]);
+  return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), 
+                     sizes [(*(code + 1) >> 10) & 0x7], 2) + 2);
+  }
+else if (pass3)
+  {
+  str_cpy (tmp_op, xfer_size [2]);       /* ".X" */
+  str_cpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]);
+  }
+return (2);
+}
+
+/**********************************************************************/
+
+uint fsincos (struct opcode_sub_entry *op)
+
+{
+char *tmp_op = NULL;
+char *tmp_dest;
+
+if (pass3)
+  {
+  tmp_op = str_cpy (opcode, op->mnemonic);
+  tmp_dest = str_cpy (dest, reg_names [17 + op->param]);
+  *tmp_dest++ = ':';
+  str_cpy (tmp_dest, reg_names [17 + ((*(code + 1) >> 7) & 0x7)]);
+  }
+if (*(code + 1) & 0x4000)          /* R/M-Bit */
+  {
+  if (pass3)
+    str_cpy (tmp_op, xfer_size [(*(code + 1) >> 10) & 0x7]);
+  return (decode_ea (src, MODE_NUM (*code), REG_NUM (*code), 
+                     sizes [(*(code + 1) >> 10) & 0x7], 2) + 2);
+  }
+else
+  {
+  if (pass3)
+    {
+    str_cpy (tmp_op, xfer_size [2]);       /* ".X" */
+    str_cpy (src, reg_names [17 + ((*(code + 1) >> 10) & 0x7)]);
+    }
+  return (2);
+  }
+}
diff --git a/cputest/adis/opcode_handler_mmu.c b/cputest/adis/opcode_handler_mmu.c
new file mode 100644 (file)
index 0000000..0e3dbb8
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Change history
+ * $Log:       opcode_handler_mmu.c,v $
+ *
+ * Revision 3.1  09/10/15 Matt_Hey
+ * New feature: Added 68060 plpa60 MMU function
+ *
+ * Revision 3.0  93/09/24  17:54:17  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.4  93/07/18  22:56:27  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.3  93/07/11  21:39:02  Martin_Apel
+ * Bug fix: Changed PTEST function for 68030
+ * 
+ * Revision 2.2  93/07/08  22:29:17  Martin_Apel
+ * 
+ * Bug fix: Fixed PFLUSH bug. Mode and mask bits were confused
+ * 
+ * Revision 2.1  93/07/08  20:49:34  Martin_Apel
+ * Bug fixes: Fixed various bugs regarding 68030 opcodes
+ * 
+ * Revision 2.0  93/07/01  11:54:31  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.3  93/07/01  11:42:59  Martin_Apel
+ * 
+ * Revision 1.2  93/06/19  12:11:49  Martin_Apel
+ * Major mod.: Added full 68030/040 support
+ * 
+ * Revision 1.1  93/06/16  20:29:09  Martin_Apel
+ * Initial revision
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: opcode_handler_mmu.c,v 3.0 93/09/24 17:54:17 Martin_Apel Exp $"; */
+
+/**********************************************************************/
+
+uint plpa60 (struct opcode_entry *op)
+
+{
+indirect (src, (REG_NUM (*code) + 8));
+return (1);
+}
+
+/**********************************************************************/
+
+uint pflush40 (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  switch ((*code >> 3) & 0x3)
+    {
+    case 0: str_cat (opcode, "n");  break;
+    case 1:                        break;
+    case 2: str_cat (opcode, "an"); break;
+    case 3: str_cat (opcode, "a");  break;
+    }
+  if ((*code & 0x10) == 0)
+    indirect (src, (REG_NUM (*code) + 8));
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+uint ptest40 (struct opcode_entry *op)
+
+{
+if (pass3)
+  {
+  if (*code & 0x20)
+    str_cat (opcode, "r");
+  else
+    str_cat (opcode, "w");
+  indirect (src, (REG_NUM (*code) + 8));
+  }
+return (1);
+}
+
+/**********************************************************************/
+
+PRIVATE BOOL eval_fc (char *to)
+
+{
+if ((*(code + 1) & 0x0018) == 0x0010)
+  immed (to, (ULONG)(*(code + 1) & 0x7));
+else if ((*(code + 1) & 0x0018) == 0x0008)
+  str_cpy (to, reg_names [*(code + 1) & 0x7]);
+else if ((*(code + 1) & 0x001f) == 0)
+  str_cpy (to, special_regs [SFC]);
+else if ((*(code + 1) & 0x001f) == 0x0001)
+  str_cpy (to, special_regs [DFC]);
+else return (FALSE);
+return (TRUE);
+}
+
+/**********************************************************************/
+
+uint mmu30 (struct opcode_entry *op)
+
+{
+/* Test for PTEST instruction */
+if (((*(code + 1) & 0xfc00) == 0x9c00) && ((*code & 0x003f) != 0))
+  return ptest30 (op);
+else if (!(*(code + 1) & 0x8000))
+  {
+  struct opcode_sub_entry *subop;
+  subop = &(mmu_opcode_table [*(code + 1) >> 10]);
+  if (pass3)
+    str_cpy (opcode, subop->mnemonic);
+  return ((*subop->handler) (subop));
+  }
+return (TRANSFER);
+}
+
+/**********************************************************************/
+
+uint ptest30 (struct opcode_entry *op)
+
+{
+if ((*code & 0x003f) == 0)         /* Check for illegal mode */
+  return (TRANSFER);
+
+str_cpy (opcode, "ptestwfc");
+if (*(code + 1) & 0x0200)
+  opcode [5] = 'R';
+if (!eval_fc (dest))     
+  return (TRANSFER);
+if (*(code + 1) & 0x0100)
+  {
+  str_cat (dest, ",");
+  str_cat (dest, reg_names [(*(code + 1) >> 5) & 0x7]);
+  }
+return (2 + decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), ACC_UNKNOWN, 2));
+}
+
+/**********************************************************************
+ mmu_opcode_table (opcodes_mmu.c) instructions using an opcode_sub_entry
+**********************************************************************/
+
+uint pfl_or_ld (struct opcode_sub_entry *op)
+
+/* Tests for PLOAD instruction first. Otherwise it's a standard
+   PFLUSH instruction */
+{
+if ((*(code + 1) & 0x00e0) != 0x0000)
+  return (pflush30 (op));
+
+if ((*code & 0x3f) == 0)
+  return (TRANSFER);
+
+str_cpy (opcode, "pload");
+if (*(code + 1) & 0x0200)
+  str_cat (opcode, "r");
+else
+  str_cat (opcode, "w");
+
+if (!eval_fc (src))
+  return (TRANSFER);
+return (2 + decode_ea (dest, MODE_NUM (*code), REG_NUM (*code), ACC_UNKNOWN, 2));
+}
+
+/**********************************************************************/
+
+uint pflush30 (struct opcode_sub_entry *op)
+
+{
+switch (op->param)
+  {
+  case 1: /* PFLUSHA */
+          if (*(code + 1) != 0x2400)
+            return (TRANSFER);
+          str_cat (opcode, "a");
+          return (2);
+  case 4: /* PFLUSH FC,MASK */
+          /* EA ignored !?! */
+          if (!eval_fc (src))
+            return (TRANSFER);
+          immed (dest, (ULONG)((*(code + 1) >> 5) & 0x7));
+          return (2);
+
+  case 6: /* PFLUSH FC,MASK,EA */
+          if (!eval_fc (src))
+            return (TRANSFER);
+          str_cat (src, ",");
+          immed (src + strlen (src), (ULONG)((*(code + 1) >> 5) & 0x7));
+          return (2 + decode_ea (dest, MODE_NUM (*code), REG_NUM (*code),
+                                 ACC_UNKNOWN, 2));
+  }
+return (TRANSFER);
+}
+
+/**********************************************************************/
+
+uint pmove30 (struct opcode_sub_entry *op)
+
+{
+char *ea,
+     *reg;
+
+if ((*code & 0x003f) == 0)
+  return (TRANSFER);
+
+if ((*(code + 1) & 0xff) || ((*(code + 1) & 0x0010) && op->param == MMUSR))
+  return (TRANSFER);
+
+if (*(code + 1) & 0x0200)
+  {
+  ea = dest;
+  reg = src;
+  }
+else
+  {
+  ea = src;
+  reg = dest;
+  }
+if ((*(code + 1) & 0x0100))
+  str_cat (opcode, "fd");
+
+str_cpy (reg, special_regs [op->param]);
+return (2 + decode_ea (ea, MODE_NUM (*code), REG_NUM (*code), ACC_LONG, 2));
+}
diff --git a/cputest/adis/opcodes_cpu.c b/cputest/adis/opcodes_cpu.c
new file mode 100644 (file)
index 0000000..12a6cbb
--- /dev/null
@@ -0,0 +1,1123 @@
+/*
+ * Change history
+ * $Log:       opcodes.c,v $
+ *
+ * Revision 3.1  09/10/15  Matt_Hey
+ * New feature: Added 68060 MMU opcodes for plpaw & plpar
+ * Minor mod.: pea (and lea) now enter_ref() ACC_UNKNOWN instead of ACC_LONG
+ *             as nothing is known about data length or type at that offset
+ *
+ * Revision 3.0  93/09/24  17:54:19  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.2  93/07/18  22:56:30  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.1  93/07/08  20:49:58  Martin_Apel
+ * Bug fix: Enabled addressing mode 0 for mmu30 instruction
+ * 
+ * Revision 2.0  93/07/01  11:54:33  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.13  93/07/01  11:43:07  Martin_Apel
+ * Bug fix: TST.x Ax for 68020 enabled (Error in 68020 manual)
+ * 
+ * Revision 1.12  93/06/19  12:11:54  Martin_Apel
+ * Major mod.: Added full 68030/040 support
+ * 
+ * Revision 1.11  93/06/16  20:29:10  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * Minor mod.: Added variables for 68030 / 040 support
+ * 
+ * Revision 1.10  93/06/03  20:29:25  Martin_Apel
+ * 
+ * 
+ */
+
+/* The opcode table is an opcode_entry array (defined in defs.h) that is
+   indexed by the first 10 bits of each instruction encoding. The handler
+   of that index is then called. See disasm_instr () in disasm_code.c for use. */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: opcodes.c,v 3.0 93/09/24 17:54:19 Martin_Apel Exp $"; */
+
+/* If the opcode_table is 16 byte aligned, then only one cache line is needed
+   per entry instead of 2. Unfortunatly, __attribute__((aligned(16)) doesn't
+   seem to work with GCC 3.4.0. The Amiga hunk loader can only guarentee 4 byte
+   alignment (8 with TLSFMem?). Memory could be dynamically allocated, manually
+   aligned, and copied but that needs more memory and effort. */
+
+struct opcode_entry opcode_table [] =
+{
+/* *handler , modes, submodes, chain, *mnemonic , param, access */
+
+{ imm_b    , 0xfd, 0x03, 1026, "ori.b"   , 0, ACC_BYTE     }, /* 0000 000 000 */
+{ imm_w    , 0xfd, 0x03, 1026, "ori.w"   , 0, ACC_WORD     }, /* 0000 000 001 */
+{ imm_l    , 0xfd, 0x03, 1024, "ori.l"   , 0, ACC_LONG     }, /* 0000 000 010 */
+{ chkcmp2  , 0xe4, 0x0f, 1056, "c  2.b"  , 0, ACC_BYTE     }, /* 0000 000 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 0, 0            }, /* 0000 000 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 0, 0            }, /* 0000 000 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 0, 0            }, /* 0000 000 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 0, 0            }, /* 0000 000 111 */
+{ imm_b    , 0xfd, 0x03, 1026, "andi.b"  , 0, ACC_BYTE     }, /* 0000 001 000 */
+{ imm_w    , 0xfd, 0x03, 1026, "andi.w"  , 0, ACC_WORD     }, /* 0000 001 001 */
+{ imm_l    , 0xfd, 0x03, 1024, "andi.l"  , 0, ACC_LONG     }, /* 0000 001 010 */
+{ chkcmp2  , 0xe4, 0x0f, 1057, "c  2.w"  , 0, ACC_WORD     }, /* 0000 001 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 1, 0            }, /* 0000 001 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 1, 0            }, /* 0000 001 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 1, 0            }, /* 0000 001 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 1, 0            }, /* 0000 001 111 */
+{ imm_b    , 0xfd, 0x03, 1024, "subi.b"  , 0, ACC_BYTE     }, /* 0000 010 000 */
+{ imm_w    , 0xfd, 0x03, 1024, "subi.w"  , 0, ACC_WORD     }, /* 0000 010 001 */
+{ imm_l    , 0xfd, 0x03, 1024, "subi.l"  , 0, ACC_LONG     }, /* 0000 010 010 */
+{ chkcmp2  , 0xe4, 0x0f, 1058, "c  2.l"  , 0, ACC_LONG     }, /* 0000 010 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 2, 0            }, /* 0000 010 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 2, 0            }, /* 0000 010 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 2, 0            }, /* 0000 010 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 2, 0            }, /* 0000 010 111 */
+{ imm_b    , 0xfd, 0x03, 1024, "addi.b"  , 0, ACC_BYTE     }, /* 0000 011 000 */
+{ imm_w    , 0xfd, 0x03, 1024, "addi.w"  , 0, ACC_WORD     }, /* 0000 011 001 */
+{ imm_l    , 0xfd, 0x03, 1024, "addi.l"  , 0, ACC_LONG     }, /* 0000 011 010 */
+{ imm_b    , 0xe4, 0x0f, 1027, "callm"   , 0, 0            }, /* 0000 011 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 3, 0            }, /* 0000 011 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 3, 0            }, /* 0000 011 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 3, 0            }, /* 0000 011 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 3, 0            }, /* 0000 011 111 */
+{ bit_imm  , 0xfd, 0x0f, 1024, "btst"    , 0, 0            }, /* 0000 100 000 */
+{ bit_imm  , 0xfd, 0x03, 1024, "bchg"    , 0, 0            }, /* 0000 100 001 */
+{ bit_imm  , 0xfd, 0x03, 1024, "bclr"    , 0, 0            }, /* 0000 100 010 */
+{ bit_imm  , 0xfd, 0x03, 1024, "bset"    , 0, 0            }, /* 0000 100 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 4, 0            }, /* 0000 100 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 4, 0            }, /* 0000 100 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 4, 0            }, /* 0000 100 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 4, 0            }, /* 0000 100 111 */
+{ imm_b    , 0xfd, 0x03, 1026, "eori.b"  , 0, ACC_BYTE     }, /* 0000 101 000 */
+{ imm_w    , 0xfd, 0x03, 1026, "eori.w"  , 0, ACC_WORD     }, /* 0000 101 001 */
+{ imm_l    , 0xfd, 0x03, 1024, "eori.l"  , 0, ACC_LONG     }, /* 0000 101 010 */
+{ cas      , 0xfc, 0x03, 1040, "cas.b"   , 0, ACC_BYTE     }, /* 0000 101 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 5, 0            }, /* 0000 101 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 5, 0            }, /* 0000 101 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 5, 0            }, /* 0000 101 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 5, 0            }, /* 0000 101 111 */
+{ imm_b    , 0xfd, 0x0f, 1024, "cmpi.b"  , 0, ACC_BYTE     }, /* 0000 110 000 */
+{ imm_w    , 0xfd, 0x0f, 1024, "cmpi.w"  , 0, ACC_WORD     }, /* 0000 110 001 */
+{ imm_l    , 0xfd, 0x0f, 1024, "cmpi.l"  , 0, ACC_LONG     }, /* 0000 110 010 */
+{ cas      , 0xfc, 0x03, 1041, "cas.w"   , 0, ACC_WORD     }, /* 0000 110 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 6, 0            }, /* 0000 110 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 6, 0            }, /* 0000 110 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 6, 0            }, /* 0000 110 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 6, 0            }, /* 0000 110 111 */
+{ moves    , 0xfc, 0x03, 1024, "moves.b" , 0, ACC_BYTE     }, /* 0000 111 000 */
+{ moves    , 0xfc, 0x03, 1024, "moves.w" , 0, ACC_WORD     }, /* 0000 111 001 */
+{ moves    , 0xfc, 0x03, 1024, "moves.l" , 0, ACC_LONG     }, /* 0000 111 010 */
+{ cas      , 0xfc, 0x03, 1042, "cas.l"   , 0, ACC_LONG     }, /* 0000 111 011 */
+{ bit_reg  , 0xfd, 0x1f, 1037, "btst"    , 7, 0            }, /* 0000 111 100 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bchg"    , 7, 0            }, /* 0000 111 101 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bclr"    , 7, 0            }, /* 0000 111 110 */
+{ bit_reg  , 0xfd, 0x03, 1037, "bset"    , 7, 0            }, /* 0000 111 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0001 000 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 110 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 000 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 1, ACC_BYTE     }, /* 0001 001 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 1, 0            }, /* 0001 001 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 001 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 001 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 001 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 001 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 001 110 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 001 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 2, ACC_BYTE     }, /* 0001 010 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 2, 0            }, /* 0001 010 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 010 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 010 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 010 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 010 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 010 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 2, 0            }, /* 0001 010 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 3, ACC_BYTE     }, /* 0001 011 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 3, 0            }, /* 0001 011 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 011 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 011 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 011 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 011 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 011 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 3, 0            }, /* 0001 011 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 4, ACC_BYTE     }, /* 0001 100 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 4, 0            }, /* 0001 100 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 100 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 100 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 100 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 100 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 100 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 4, 0            }, /* 0001 100 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 5, ACC_BYTE     }, /* 0001 101 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 5, 0            }, /* 0001 101 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 101 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 101 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 101 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 101 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 101 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 5, 0            }, /* 0001 101 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 6, ACC_BYTE     }, /* 0001 110 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 6, 0            }, /* 0001 110 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 110 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 110 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 110 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 110 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 110 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 6, 0            }, /* 0001 110 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.b"  , 7, ACC_BYTE     }, /* 0001 111 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 0001 111 001 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 111 010 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 111 011 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 111 100 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 111 101 */
+{ move     , 0xff, 0x1f, 1024, "move.b"  , 0, ACC_BYTE     }, /* 0001 111 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 0001 111 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" , 8, ACC_LONG     }, /* 0010 000 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 110 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 000 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 1, ACC_LONG     }, /* 0010 001 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" , 9, ACC_LONG     }, /* 0010 001 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 001 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 001 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 001 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 001 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 001 110 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 001 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 2, ACC_LONG     }, /* 0010 010 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,10, ACC_LONG     }, /* 0010 010 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 010 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 010 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 010 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 010 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 010 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 2, 0            }, /* 0010 010 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 3, ACC_LONG     }, /* 0010 011 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,11, ACC_LONG     }, /* 0010 011 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 011 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 011 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 011 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 011 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 011 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 3, 0            }, /* 0010 011 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 4, ACC_LONG     }, /* 0010 100 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,12, ACC_LONG     }, /* 0010 100 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 100 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 100 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 100 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 100 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 100 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 4, 0            }, /* 0010 100 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 5, ACC_LONG     }, /* 0010 101 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,13, ACC_LONG     }, /* 0010 101 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 101 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 101 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 101 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 101 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 101 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 5, 0            }, /* 0010 101 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 6, ACC_LONG     }, /* 0010 110 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,14, ACC_LONG     }, /* 0010 110 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 110 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 110 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 110 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 110 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 110 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 6, 0            }, /* 0010 110 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.l"  , 7, ACC_LONG     }, /* 0010 111 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.l" ,15, ACC_LONG     }, /* 0010 111 001 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 111 010 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 111 011 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 111 100 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 111 101 */
+{ move     , 0xff, 0x1f, 1024, "move.l"  , 0, ACC_LONG     }, /* 0010 111 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 0010 111 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" , 8, ACC_WORD     }, /* 0011 000 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 110 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 000 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 1, ACC_WORD     }, /* 0011 001 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" , 9, ACC_WORD     }, /* 0011 001 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 001 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 001 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 001 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 001 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 001 110 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 001 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 2, ACC_WORD     }, /* 0011 010 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,10, ACC_WORD     }, /* 0011 010 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 010 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 010 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 010 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 010 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 010 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 2, 0            }, /* 0011 010 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 3, ACC_WORD     }, /* 0011 011 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,11, ACC_WORD     }, /* 0011 011 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 011 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 011 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 011 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 011 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 011 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 3, 0            }, /* 0011 011 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 4, ACC_WORD     }, /* 0011 100 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,12, ACC_WORD     }, /* 0011 100 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 100 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 100 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 100 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 100 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 100 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 4, 0            }, /* 0011 100 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 5, ACC_WORD     }, /* 0011 101 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,13, ACC_WORD     }, /* 0011 101 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 101 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 101 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 101 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 101 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 101 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 5, 0            }, /* 0011 101 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 6, ACC_WORD     }, /* 0011 110 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,14, ACC_WORD     }, /* 0011 110 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 110 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 110 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 110 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 110 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 110 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 6, 0            }, /* 0011 110 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "move.w"  , 7, ACC_WORD     }, /* 0011 111 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "movea.w" ,15, ACC_WORD     }, /* 0011 111 001 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 111 010 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 111 011 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 111 100 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 111 101 */
+{ move     , 0xff, 0x1f, 1024, "move.w"  , 0, ACC_WORD     }, /* 0011 111 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 0011 111 111 */
+{ op1      , 0xfd, 0x03, 1024, "negx.b"  , 0, ACC_BYTE     }, /* 0100 000 000 */
+{ op1      , 0xfd, 0x03, 1024, "negx.w"  , 0, ACC_WORD     }, /* 0100 000 001 */
+{ op1      , 0xfd, 0x03, 1024, "negx.l"  , 0, ACC_LONG     }, /* 0100 000 010 */
+{ movesrccr, 0xfd, 0x03, 1024, "move.w", FROM_SR, ACC_WORD }, /* 0100 000 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 0, ACC_LONG     }, /* 0100 000 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 000 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 0, ACC_WORD     }, /* 0100 000 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     , 8, ACC_UNKNOWN  }, /* 0100 000 111 */
+{ op1      , 0xfd, 0x03, 1024, "clr.b"   , 0, ACC_BYTE     }, /* 0100 001 000 */
+{ op1      , 0xfd, 0x03, 1024, "clr.w"   , 0, ACC_WORD     }, /* 0100 001 001 */
+{ op1      , 0xfd, 0x03, 1024, "clr.l"   , 0, ACC_LONG     }, /* 0100 001 010 */
+{ movesrccr, 0xfd, 0x03, 1024, "move.w", FROM_CCR, ACC_WORD}, /* 0100 001 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 1, ACC_LONG     }, /* 0100 001 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 001 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 1, ACC_WORD     }, /* 0100 001 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     , 9, ACC_UNKNOWN  }, /* 0100 001 111 */
+{ op1      , 0xfd, 0x03, 1024, "neg.b"   , 0, ACC_BYTE     }, /* 0100 010 000 */
+{ op1      , 0xfd, 0x03, 1024, "neg.w"   , 0, ACC_WORD     }, /* 0100 010 001 */
+{ op1      , 0xfd, 0x03, 1024, "neg.l"   , 0, ACC_LONG     }, /* 0100 010 010 */
+{ movesrccr, 0xfd, 0x1f, 1024, "move.w", TO_CCR, ACC_WORD  }, /* 0100 010 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 2, ACC_LONG     }, /* 0100 010 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 010 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 2, ACC_WORD     }, /* 0100 010 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     ,10, ACC_UNKNOWN  }, /* 0100 010 111 */
+{ op1      , 0xfd, 0x03, 1024, "not.b"   , 0, ACC_BYTE     }, /* 0100 011 000 */
+{ op1      , 0xfd, 0x03, 1024, "not.w"   , 0, ACC_WORD     }, /* 0100 011 001 */
+{ op1      , 0xfd, 0x03, 1024, "not.l"   , 0, ACC_LONG     }, /* 0100 011 010 */
+{ movesrccr, 0xfd, 0x1f, 1024, "move.w", TO_SR, ACC_WORD   }, /* 0100 011 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 3, ACC_LONG     }, /* 0100 011 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 011 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 3, ACC_WORD     }, /* 0100 011 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     ,11, ACC_UNKNOWN  }, /* 0100 011 111 */
+{ op1      , 0xfd, 0x03, 1055, "nbcd.b"  , 0, ACC_BYTE     }, /* 0100 100 000 */
+{ op1      , 0xe4, 0x0f, 1029, "pea"     , 0, ACC_UNKNOWN  }, /* 0100 100 001 */
+{ movem    , 0xf4, 0x03, 1030, "movem.w", REG_TO_MEM, 0    }, /* 0100 100 010 */
+{ movem    , 0xf4, 0x03, 1050, "movem.l", REG_TO_MEM, 0    }, /* 0100 100 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 4, ACC_LONG     }, /* 0100 100 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 100 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 4, ACC_WORD     }, /* 0100 100 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1051, "lea"     ,12, ACC_UNKNOWN  }, /* 0100 100 111 */
+{ op1      , 0xff, 0x1f, 1024, "tst.b"   , 0, ACC_BYTE     }, /* 0100 101 000 */
+{ op1      , 0xff, 0x1f, 1024, "tst.w"   , 0, ACC_WORD     }, /* 0100 101 001 */
+{ op1      , 0xff, 0x1f, 1024, "tst.l"   , 0, ACC_LONG     }, /* 0100 101 010 */
+{ op1      , 0xfd, 0x03, 1025, "tas"     , 0, ACC_BYTE     }, /* 0100 101 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 5, ACC_LONG     }, /* 0100 101 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 101 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 5, ACC_WORD     }, /* 0100 101 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     ,13, ACC_UNKNOWN  }, /* 0100 101 111 */
+{ muldivl  , 0xfd, 0x1f, 1024, "mul "    , 0, ACC_LONG     }, /* 0100 110 000 */
+{ muldivl  , 0xfd, 0x1f, 1024, "div "    , 0, ACC_LONG     }, /* 0100 110 001 */
+{ movem    , 0xec, 0x0f, 1059, "movem.w" , MEM_TO_REG, 0   }, /* 0100 110 010 */
+{ movem    , 0xec, 0x0f, 1024, "movem.l" , MEM_TO_REG, 0   }, /* 0100 110 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 6, ACC_LONG     }, /* 0100 110 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 110 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 6, ACC_WORD     }, /* 0100 110 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     ,14, ACC_UNKNOWN  }, /* 0100 110 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 111 000 */
+{ special  , 0xff, 0x0c, 1024, 0         , 0, 0            }, /* 0100 111 001 */ 
+{ op1      , 0xe4, 0x0f, 1024, "jsr"     , 0, ACC_CODE     }, /* 0100 111 010 */
+{ op1_end  , 0xe4, 0x0f, 1024, "jmp"     , 0, ACC_CODE     }, /* 0100 111 011 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.l"   , 7, ACC_LONG     }, /* 0100 111 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 0100 111 101 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "chk.w"   , 7, ACC_WORD     }, /* 0100 111 110 */
+{ EA_to_Rn , 0xe4, 0x0f, 1024, "lea"     ,15, ACC_UNKNOWN  }, /* 0100 111 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 8, ACC_BYTE     }, /* 0101 000 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 8, ACC_WORD     }, /* 0101 000 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 8, ACC_LONG     }, /* 0101 000 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbt"     , 0, 0            }, /* 0101 000 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 8, ACC_BYTE     }, /* 0101 000 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 8, ACC_WORD     }, /* 0101 000 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 8, ACC_LONG     }, /* 0101 000 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dbra"    , 0, 0            }, /* 0101 000 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 1, ACC_BYTE     }, /* 0101 001 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 1, ACC_WORD     }, /* 0101 001 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 1, ACC_LONG     }, /* 0101 001 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbhi"    , 1, 0            }, /* 0101 001 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 1, ACC_BYTE     }, /* 0101 001 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 1, ACC_WORD     }, /* 0101 001 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 1, ACC_LONG     }, /* 0101 001 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dbls"    , 1, 0            }, /* 0101 001 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 2, ACC_BYTE     }, /* 0101 010 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 2, ACC_WORD     }, /* 0101 010 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 2, ACC_LONG     }, /* 0101 010 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbcc"    , 2, 0            }, /* 0101 010 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 2, ACC_BYTE     }, /* 0101 010 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 2, ACC_WORD     }, /* 0101 010 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 2, ACC_LONG     }, /* 0101 010 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dbcs"    , 2, 0            }, /* 0101 010 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 3, ACC_BYTE     }, /* 0101 011 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 3, ACC_WORD     }, /* 0101 011 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 3, ACC_LONG     }, /* 0101 011 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbne"    , 3, 0            }, /* 0101 011 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 3, ACC_BYTE     }, /* 0101 011 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 3, ACC_WORD     }, /* 0101 011 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 3, ACC_LONG     }, /* 0101 011 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dbeq"    , 3, 0            }, /* 0101 011 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 4, ACC_BYTE     }, /* 0101 100 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 4, ACC_WORD     }, /* 0101 100 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 4, ACC_LONG     }, /* 0101 100 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbvc"    , 4, 0            }, /* 0101 100 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 4, ACC_BYTE     }, /* 0101 100 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 4, ACC_WORD     }, /* 0101 100 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 4, ACC_LONG     }, /* 0101 100 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dbvs"    , 4, 0            }, /* 0101 100 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 5, ACC_BYTE     }, /* 0101 101 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 5, ACC_WORD     }, /* 0101 101 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 5, ACC_LONG     }, /* 0101 101 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbpl"    , 5, 0            }, /* 0101 101 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 5, ACC_BYTE     }, /* 0101 101 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 5, ACC_WORD     }, /* 0101 101 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 5, ACC_LONG     }, /* 0101 101 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dbmi"    , 5, 0            }, /* 0101 101 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 6, ACC_BYTE     }, /* 0101 110 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 6, ACC_WORD     }, /* 0101 110 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 6, ACC_LONG     }, /* 0101 110 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbge"    , 6, 0            }, /* 0101 110 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 6, ACC_BYTE     }, /* 0101 110 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 6, ACC_WORD     }, /* 0101 110 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 6, ACC_LONG     }, /* 0101 110 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dble"    , 6, 0            }, /* 0101 110 111 */
+{ quick    , 0xff, 0x03, 1024, "addq.b"  , 7, ACC_BYTE     }, /* 0101 111 000 */
+{ quick    , 0xff, 0x03, 1024, "addq.w"  , 7, ACC_WORD     }, /* 0101 111 001 */
+{ quick    , 0xff, 0x03, 1024, "addq.l"  , 7, ACC_LONG     }, /* 0101 111 010 */
+{ dbranch  , 0x02, 0xff, 1046, "dbgt"    , 7, 0            }, /* 0101 111 011 */
+{ quick    , 0xff, 0x03, 1024, "subq.b"  , 7, ACC_BYTE     }, /* 0101 111 100 */
+{ quick    , 0xff, 0x03, 1024, "subq.w"  , 7, ACC_WORD     }, /* 0101 111 101 */
+{ quick    , 0xff, 0x03, 1024, "subq.l"  , 7, ACC_LONG     }, /* 0101 111 110 */
+{ dbranch  , 0x02, 0xff, 1046, "dble"    , 7, 0            }, /* 0101 111 111 */
+{ branch   , 0xff, 0xff, 1024, "bra"     , 0, 0            }, /* 0110 000 000 */
+{ branch   , 0xff, 0xff, 1024, "bra"     , 0, 0            }, /* 0110 000 001 */
+{ branch   , 0xff, 0xff, 1024, "bra"     , 0, 0            }, /* 0110 000 010 */
+{ branch   , 0xff, 0xff, 1024, "bra"     , 0, 0            }, /* 0110 000 011 */
+{ branch   , 0xff, 0xff, 1024, "bsr"     , 0, 0            }, /* 0110 000 100 */
+{ branch   , 0xff, 0xff, 1024, "bsr"     , 0, 0            }, /* 0110 000 101 */
+{ branch   , 0xff, 0xff, 1024, "bsr"     , 0, 0            }, /* 0110 000 110 */
+{ branch   , 0xff, 0xff, 1024, "bsr"     , 0, 0            }, /* 0110 000 111 */
+{ branch   , 0xff, 0xff, 1024, "bhi"     , 0, 0            }, /* 0110 001 000 */
+{ branch   , 0xff, 0xff, 1024, "bhi"     , 0, 0            }, /* 0110 001 001 */
+{ branch   , 0xff, 0xff, 1024, "bhi"     , 0, 0            }, /* 0110 001 010 */
+{ branch   , 0xff, 0xff, 1024, "bhi"     , 0, 0            }, /* 0110 001 011 */
+{ branch   , 0xff, 0xff, 1024, "bls"     , 0, 0            }, /* 0110 001 100 */
+{ branch   , 0xff, 0xff, 1024, "bls"     , 0, 0            }, /* 0110 001 101 */
+{ branch   , 0xff, 0xff, 1024, "bls"     , 0, 0            }, /* 0110 001 110 */
+{ branch   , 0xff, 0xff, 1024, "bls"     , 0, 0            }, /* 0110 001 111 */
+{ branch   , 0xff, 0xff, 1024, "bcc"     , 0, 0            }, /* 0110 010 000 */
+{ branch   , 0xff, 0xff, 1024, "bcc"     , 0, 0            }, /* 0110 010 001 */
+{ branch   , 0xff, 0xff, 1024, "bcc"     , 0, 0            }, /* 0110 010 010 */
+{ branch   , 0xff, 0xff, 1024, "bcc"     , 0, 0            }, /* 0110 010 011 */
+{ branch   , 0xff, 0xff, 1024, "bcs"     , 0, 0            }, /* 0110 010 100 */
+{ branch   , 0xff, 0xff, 1024, "bcs"     , 0, 0            }, /* 0110 010 101 */
+{ branch   , 0xff, 0xff, 1024, "bcs"     , 0, 0            }, /* 0110 010 110 */
+{ branch   , 0xff, 0xff, 1024, "bcs"     , 0, 0            }, /* 0110 010 111 */
+{ branch   , 0xff, 0xff, 1024, "bne"     , 0, 0            }, /* 0110 011 000 */
+{ branch   , 0xff, 0xff, 1024, "bne"     , 0, 0            }, /* 0110 011 001 */
+{ branch   , 0xff, 0xff, 1024, "bne"     , 0, 0            }, /* 0110 011 010 */
+{ branch   , 0xff, 0xff, 1024, "bne"     , 0, 0            }, /* 0110 011 011 */
+{ branch   , 0xff, 0xff, 1024, "beq"     , 0, 0            }, /* 0110 011 100 */
+{ branch   , 0xff, 0xff, 1024, "beq"     , 0, 0            }, /* 0110 011 101 */
+{ branch   , 0xff, 0xff, 1024, "beq"     , 0, 0            }, /* 0110 011 110 */
+{ branch   , 0xff, 0xff, 1024, "beq"     , 0, 0            }, /* 0110 011 111 */
+{ branch   , 0xff, 0xff, 1024, "bvc"     , 0, 0            }, /* 0110 100 000 */
+{ branch   , 0xff, 0xff, 1024, "bvc"     , 0, 0            }, /* 0110 100 001 */
+{ branch   , 0xff, 0xff, 1024, "bvc"     , 0, 0            }, /* 0110 100 010 */
+{ branch   , 0xff, 0xff, 1024, "bvc"     , 0, 0            }, /* 0110 100 011 */
+{ branch   , 0xff, 0xff, 1024, "bvs"     , 0, 0            }, /* 0110 100 100 */
+{ branch   , 0xff, 0xff, 1024, "bvs"     , 0, 0            }, /* 0110 100 101 */
+{ branch   , 0xff, 0xff, 1024, "bvs"     , 0, 0            }, /* 0110 100 110 */
+{ branch   , 0xff, 0xff, 1024, "bvs"     , 0, 0            }, /* 0110 100 111 */
+{ branch   , 0xff, 0xff, 1024, "bpl"     , 0, 0            }, /* 0110 101 000 */
+{ branch   , 0xff, 0xff, 1024, "bpl"     , 0, 0            }, /* 0110 101 001 */
+{ branch   , 0xff, 0xff, 1024, "bpl"     , 0, 0            }, /* 0110 101 010 */
+{ branch   , 0xff, 0xff, 1024, "bpl"     , 0, 0            }, /* 0110 101 011 */
+{ branch   , 0xff, 0xff, 1024, "bmi"     , 0, 0            }, /* 0110 101 100 */
+{ branch   , 0xff, 0xff, 1024, "bmi"     , 0, 0            }, /* 0110 101 101 */
+{ branch   , 0xff, 0xff, 1024, "bmi"     , 0, 0            }, /* 0110 101 110 */
+{ branch   , 0xff, 0xff, 1024, "bmi"     , 0, 0            }, /* 0110 101 111 */
+{ branch   , 0xff, 0xff, 1024, "bge"     , 0, 0            }, /* 0110 110 000 */
+{ branch   , 0xff, 0xff, 1024, "bge"     , 0, 0            }, /* 0110 110 001 */
+{ branch   , 0xff, 0xff, 1024, "bge"     , 0, 0            }, /* 0110 110 010 */
+{ branch   , 0xff, 0xff, 1024, "bge"     , 0, 0            }, /* 0110 110 011 */
+{ branch   , 0xff, 0xff, 1024, "blt"     , 0, 0            }, /* 0110 110 100 */
+{ branch   , 0xff, 0xff, 1024, "blt"     , 0, 0            }, /* 0110 110 101 */
+{ branch   , 0xff, 0xff, 1024, "blt"     , 0, 0            }, /* 0110 110 110 */
+{ branch   , 0xff, 0xff, 1024, "blt"     , 0, 0            }, /* 0110 110 111 */
+{ branch   , 0xff, 0xff, 1024, "bgt"     , 0, 0            }, /* 0110 111 000 */
+{ branch   , 0xff, 0xff, 1024, "bgt"     , 0, 0            }, /* 0110 111 001 */
+{ branch   , 0xff, 0xff, 1024, "bgt"     , 0, 0            }, /* 0110 111 010 */
+{ branch   , 0xff, 0xff, 1024, "bgt"     , 0, 0            }, /* 0110 111 011 */
+{ branch   , 0xff, 0xff, 1024, "ble"     , 0, 0            }, /* 0110 111 100 */
+{ branch   , 0xff, 0xff, 1024, "ble"     , 0, 0            }, /* 0110 111 101 */
+{ branch   , 0xff, 0xff, 1024, "ble"     , 0, 0            }, /* 0110 111 110 */
+{ branch   , 0xff, 0xff, 1024, "ble"     , 0, 0            }, /* 0110 111 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 0, 0            }, /* 0111 000 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 0, 0            }, /* 0111 000 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 0, 0            }, /* 0111 000 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 0, 0            }, /* 0111 000 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 0, ACC_SBYTE    }, /* 0111 000 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 0, ACC_SWORD    }, /* 0111 000 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 0, ACC_BYTE     }, /* 0111 000 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 0, ACC_WORD     }, /* 0111 000 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 1, 0            }, /* 0111 001 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 1, 0            }, /* 0111 001 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 1, 0            }, /* 0111 001 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 1, 0            }, /* 0111 001 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 1, ACC_SBYTE    }, /* 0111 001 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 1, ACC_SWORD    }, /* 0111 001 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 1, ACC_BYTE     }, /* 0111 001 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 1, ACC_WORD     }, /* 0111 001 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 2, 0            }, /* 0111 010 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 2, 0            }, /* 0111 010 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 2, 0            }, /* 0111 010 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 2, 0            }, /* 0111 010 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 2, ACC_SBYTE    }, /* 0111 010 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 2, ACC_SWORD    }, /* 0111 010 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 2, ACC_BYTE     }, /* 0111 010 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 2, ACC_WORD     }, /* 0111 010 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 3, 0            }, /* 0111 011 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 3, 0            }, /* 0111 011 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 3, 0            }, /* 0111 011 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 3, 0            }, /* 0111 011 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 3, ACC_SBYTE    }, /* 0111 011 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 3, ACC_SWORD    }, /* 0111 011 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 3, ACC_BYTE     }, /* 0111 011 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 3, ACC_WORD     }, /* 0111 011 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 4, 0            }, /* 0111 100 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 4, 0            }, /* 0111 100 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 4, 0            }, /* 0111 100 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 4, 0            }, /* 0111 100 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 4, ACC_SBYTE    }, /* 0111 100 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 4, ACC_SWORD    }, /* 0111 100 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 4, ACC_BYTE     }, /* 0111 100 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 4, ACC_WORD     }, /* 0111 100 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 5, 0            }, /* 0111 101 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 5, 0            }, /* 0111 101 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 5, 0            }, /* 0111 101 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 5, 0            }, /* 0111 101 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 5, ACC_SBYTE    }, /* 0111 101 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 5, ACC_SWORD    }, /* 0111 101 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 5, ACC_BYTE     }, /* 0111 101 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 5, ACC_WORD     }, /* 0111 101 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 6, 0            }, /* 0111 110 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 6, 0            }, /* 0111 110 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 6, 0            }, /* 0111 110 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 6, 0            }, /* 0111 110 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 6, ACC_SBYTE    }, /* 0111 110 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 6, ACC_SWORD    }, /* 0111 110 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 6, ACC_BYTE     }, /* 0111 110 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 6, ACC_WORD     }, /* 0111 110 111 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 7, 0            }, /* 0111 111 000 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 7, 0            }, /* 0111 111 001 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 7, 0            }, /* 0111 111 010 */
+{ moveq    , 0xff, 0xff, 1024, "moveq"   , 7, 0            }, /* 0111 111 011 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.b"   , 7, ACC_SBYTE    }, /* 0111 111 100 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvs.w"   , 7, ACC_SWORD    }, /* 0111 111 101 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.b"   , 7, ACC_BYTE     }, /* 0111 111 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "mvz.w"   , 7, ACC_WORD     }, /* 0111 111 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 0, ACC_BYTE     }, /* 1000 000 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 0, ACC_WORD     }, /* 1000 000 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 0, ACC_LONG     }, /* 1000 000 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 0, ACC_WORD     }, /* 1000 000 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 0, ACC_BYTE     }, /* 1000 000 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 0, ACC_WORD     }, /* 1000 000 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 0, ACC_LONG     }, /* 1000 000 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 0, ACC_SWORD    }, /* 1000 000 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 1, ACC_BYTE     }, /* 1000 001 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 1, ACC_WORD     }, /* 1000 001 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 1, ACC_LONG     }, /* 1000 001 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 1, ACC_WORD     }, /* 1000 001 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 1, ACC_BYTE     }, /* 1000 001 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 1, ACC_WORD     }, /* 1000 001 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 1, ACC_LONG     }, /* 1000 001 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 1, ACC_SWORD    }, /* 1000 001 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 2, ACC_BYTE     }, /* 1000 010 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 2, ACC_WORD     }, /* 1000 010 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 2, ACC_LONG     }, /* 1000 010 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 2, ACC_WORD     }, /* 1000 010 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 2, ACC_BYTE     }, /* 1000 010 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 2, ACC_WORD     }, /* 1000 010 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 2, ACC_LONG     }, /* 1000 010 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 2, ACC_SWORD    }, /* 1000 010 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 3, ACC_BYTE     }, /* 1000 011 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 3, ACC_WORD     }, /* 1000 011 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 3, ACC_LONG     }, /* 1000 011 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 3, ACC_WORD     }, /* 1000 011 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 3, ACC_BYTE     }, /* 1000 011 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 3, ACC_WORD     }, /* 1000 011 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 3, ACC_LONG     }, /* 1000 011 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 3, ACC_SWORD    }, /* 1000 011 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 4, ACC_BYTE     }, /* 1000 100 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 4, ACC_WORD     }, /* 1000 100 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 4, ACC_LONG     }, /* 1000 100 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 4, ACC_WORD     }, /* 1000 100 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 4, ACC_BYTE     }, /* 1000 100 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 4, ACC_WORD     }, /* 1000 100 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 4, ACC_LONG     }, /* 1000 100 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 4, ACC_SWORD    }, /* 1000 100 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 5, ACC_BYTE     }, /* 1000 101 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 5, ACC_WORD     }, /* 1000 101 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 5, ACC_LONG     }, /* 1000 101 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 5, ACC_WORD     }, /* 1000 101 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 5, ACC_BYTE     }, /* 1000 101 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 5, ACC_WORD     }, /* 1000 101 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 5, ACC_LONG     }, /* 1000 101 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 5, ACC_SWORD    }, /* 1000 101 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 6, ACC_BYTE     }, /* 1000 110 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 6, ACC_WORD     }, /* 1000 110 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 6, ACC_LONG     }, /* 1000 110 00 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 6, ACC_WORD     }, /* 1000 110 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 6, ACC_BYTE     }, /* 1000 110 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 6, ACC_WORD     }, /* 1000 110 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 6, ACC_LONG     }, /* 1000 110 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 6, ACC_SWORD    }, /* 1000 110 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.b"    , 7, ACC_BYTE     }, /* 1000 111 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.w"    , 7, ACC_WORD     }, /* 1000 111 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "or.l"    , 7, ACC_LONG     }, /* 1000 111 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divu.w"  , 7, ACC_WORD     }, /* 1000 111 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1031, "or.b"    , 7, ACC_BYTE     }, /* 1000 111 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1032, "or.w"    , 7, ACC_WORD     }, /* 1000 111 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1028, "or.l"    , 7, ACC_LONG     }, /* 1000 111 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "divs.w"  , 7, ACC_SWORD    }, /* 1000 111 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 0, ACC_BYTE     }, /* 1001 000 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 0, ACC_WORD     }, /* 1001 000 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 0, ACC_LONG     }, /* 1001 000 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  , 8, ACC_WORD     }, /* 1001 000 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 0, ACC_BYTE     }, /* 1001 000 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 0, ACC_WORD     }, /* 1001 000 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 0, ACC_LONG     }, /* 1001 000 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  , 8, ACC_LONG     }, /* 1001 000 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 1, ACC_BYTE     }, /* 1001 001 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 1, ACC_WORD     }, /* 1001 001 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 1, ACC_LONG     }, /* 1001 001 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  , 9, ACC_WORD     }, /* 1001 001 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 1, ACC_BYTE     }, /* 1001 001 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 1, ACC_WORD     }, /* 1001 001 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 1, ACC_LONG     }, /* 1001 001 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  , 9, ACC_LONG     }, /* 1001 001 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 2, ACC_BYTE     }, /* 1001 010 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 2, ACC_WORD     }, /* 1001 010 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 2, ACC_LONG     }, /* 1001 010 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  ,10, ACC_WORD     }, /* 1001 010 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 2, ACC_BYTE     }, /* 1001 010 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 2, ACC_WORD     }, /* 1001 010 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 2, ACC_LONG     }, /* 1001 010 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  ,10, ACC_LONG     }, /* 1001 010 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 3, ACC_BYTE     }, /* 1001 011 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 3, ACC_WORD     }, /* 1001 011 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 3, ACC_LONG     }, /* 1001 011 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  ,11, ACC_WORD     }, /* 1001 011 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 3, ACC_BYTE     }, /* 1001 011 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 3, ACC_WORD     }, /* 1001 011 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 3, ACC_LONG     }, /* 1001 011 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  ,11, ACC_LONG     }, /* 1001 011 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 4, ACC_BYTE     }, /* 1001 100 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 4, ACC_WORD     }, /* 1001 100 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 4, ACC_LONG     }, /* 1001 100 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  ,12, ACC_WORD     }, /* 1001 100 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 4, ACC_BYTE     }, /* 1001 100 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 4, ACC_WORD     }, /* 1001 100 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 4, ACC_LONG     }, /* 1001 100 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  ,12, ACC_LONG     }, /* 1001 100 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 5, ACC_BYTE     }, /* 1001 101 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 5, ACC_WORD     }, /* 1001 101 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 5, ACC_LONG     }, /* 1001 101 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  ,13, ACC_WORD     }, /* 1001 101 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 5, ACC_BYTE     }, /* 1001 101 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 5, ACC_WORD     }, /* 1001 101 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 5, ACC_LONG     }, /* 1001 101 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  ,13, ACC_LONG     }, /* 1001 101 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 6, ACC_BYTE     }, /* 1001 110 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 6, ACC_WORD     }, /* 1001 110 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 6, ACC_LONG     }, /* 1001 110 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  ,14, ACC_WORD     }, /* 1001 110 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 6, ACC_BYTE     }, /* 1001 110 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 6, ACC_WORD     }, /* 1001 110 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 6, ACC_LONG     }, /* 1001 110 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  ,14, ACC_LONG     }, /* 1001 110 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.b"   , 7, ACC_BYTE     }, /* 1001 111 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.w"   , 7, ACC_WORD     }, /* 1001 111 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "sub.l"   , 7, ACC_LONG     }, /* 1001 111 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.w"  ,15, ACC_WORD     }, /* 1001 111 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1052, "sub.b"   , 7, ACC_BYTE     }, /* 1001 111 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1053, "sub.w"   , 7, ACC_WORD     }, /* 1001 111 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1054, "sub.l"   , 7, ACC_LONG     }, /* 1001 111 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "suba.l"  ,15, ACC_LONG     }, /* 1001 111 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 0, ACC_LONG     }, /* 1010 000 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 000 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 1, ACC_LONG     }, /* 1010 001 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 001 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 2, ACC_LONG     }, /* 1010 010 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 010 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 3, ACC_LONG     }, /* 1010 011 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 011 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 4, ACC_LONG     }, /* 1010 100 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 100 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 5, ACC_LONG     }, /* 1010 101 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 101 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 6, ACC_LONG     }, /* 1010 110 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 110 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 100 */
+{ mov3q    , 0xff, 0x0f, 1024, "mov3q"   , 7, ACC_LONG     }, /* 1010 111 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1010 111 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 0, ACC_BYTE     }, /* 1011 000 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 0, ACC_WORD     }, /* 1011 000 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 0, ACC_LONG     }, /* 1011 000 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  , 8, ACC_WORD     }, /* 1011 000 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 0, ACC_BYTE     }, /* 1011 000 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 0, ACC_WORD     }, /* 1011 000 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 0, ACC_LONG     }, /* 1011 000 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  , 8, ACC_LONG     }, /* 1011 000 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 1, ACC_BYTE     }, /* 1011 001 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 1, ACC_WORD     }, /* 1011 001 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 1, ACC_LONG     }, /* 1011 001 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  , 9, ACC_WORD     }, /* 1011 001 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 1, ACC_BYTE     }, /* 1011 001 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 1, ACC_WORD     }, /* 1011 001 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 1, ACC_LONG     }, /* 1011 001 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  , 9, ACC_LONG     }, /* 1011 001 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 2, ACC_BYTE     }, /* 1011 010 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 2, ACC_WORD     }, /* 1011 010 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 2, ACC_LONG     }, /* 1011 010 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  ,10, ACC_WORD     }, /* 1011 010 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 2, ACC_BYTE     }, /* 1011 010 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 2, ACC_WORD     }, /* 1011 010 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 2, ACC_LONG     }, /* 1011 010 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  ,10, ACC_LONG     }, /* 1011 010 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 3, ACC_BYTE     }, /* 1011 011 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 3, ACC_WORD     }, /* 1011 011 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 3, ACC_LONG     }, /* 1011 011 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  ,11, ACC_WORD     }, /* 1011 011 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 3, ACC_BYTE     }, /* 1011 011 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 3, ACC_WORD     }, /* 1011 011 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 3, ACC_LONG     }, /* 1011 011 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  ,11, ACC_LONG     }, /* 1011 011 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 4, ACC_BYTE     }, /* 1011 100 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 4, ACC_WORD     }, /* 1011 100 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 4, ACC_LONG     }, /* 1011 100 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  ,12, ACC_WORD     }, /* 1011 100 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 4, ACC_BYTE     }, /* 1011 100 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 4, ACC_WORD     }, /* 1011 100 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 4, ACC_LONG     }, /* 1011 100 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  ,12, ACC_LONG     }, /* 1011 100 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 5, ACC_BYTE     }, /* 1011 101 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 5, ACC_WORD     }, /* 1011 101 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 5, ACC_LONG     }, /* 1011 101 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  ,13, ACC_WORD     }, /* 1011 101 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 5, ACC_BYTE     }, /* 1011 101 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 5, ACC_WORD     }, /* 1011 101 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 5, ACC_LONG     }, /* 1011 101 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  ,13, ACC_LONG     }, /* 1011 101 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 6, ACC_BYTE     }, /* 1011 110 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 6, ACC_WORD     }, /* 1011 110 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 6, ACC_LONG     }, /* 1011 110 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  ,14, ACC_WORD     }, /* 1011 110 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 6, ACC_BYTE     }, /* 1011 110 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 6, ACC_WORD     }, /* 1011 110 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 6, ACC_LONG     }, /* 1011 110 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  ,14, ACC_LONG     }, /* 1011 110 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.b"   , 7, ACC_BYTE     }, /* 1011 111 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.w"   , 7, ACC_WORD     }, /* 1011 111 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmp.l"   , 7, ACC_LONG     }, /* 1011 111 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.w"  ,15, ACC_WORD     }, /* 1011 111 011 */
+{ Rn_to_EA , 0xfd, 0x03, 1034, "eor.b"   , 7, ACC_BYTE     }, /* 1011 111 100 */
+{ Rn_to_EA , 0xfd, 0x03, 1043, "eor.w"   , 7, ACC_WORD     }, /* 1011 111 101 */
+{ Rn_to_EA , 0xfd, 0x03, 1044, "eor.l"   , 7, ACC_LONG     }, /* 1011 111 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "cmpa.l"  ,15, ACC_LONG     }, /* 1011 111 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 0, ACC_BYTE     }, /* 1100 000 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 0, ACC_WORD     }, /* 1100 000 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 0, ACC_LONG     }, /* 1100 000 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 0, ACC_WORD     }, /* 1100 000 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 0, ACC_BYTE     }, /* 1100 000 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 0, ACC_WORD     }, /* 1100 000 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 0, ACC_LONG     }, /* 1100 000 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 0, ACC_SWORD    }, /* 1100 000 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 1, ACC_BYTE     }, /* 1100 001 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 1, ACC_WORD     }, /* 1100 001 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 1, ACC_LONG     }, /* 1100 001 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 1, ACC_WORD     }, /* 1100 001 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 1, ACC_BYTE     }, /* 1100 001 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 1, ACC_WORD     }, /* 1100 001 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 1, ACC_LONG     }, /* 1100 001 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 1, ACC_SWORD    }, /* 1100 001 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 2, ACC_BYTE     }, /* 1100 010 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 2, ACC_WORD     }, /* 1100 010 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 2, ACC_LONG     }, /* 1100 010 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 2, ACC_WORD     }, /* 1100 010 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 2, ACC_BYTE     }, /* 1100 010 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 2, ACC_WORD     }, /* 1100 010 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 2, ACC_LONG     }, /* 1100 010 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 2, ACC_SWORD    }, /* 1100 010 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 3, ACC_BYTE     }, /* 1100 011 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 3, ACC_WORD     }, /* 1100 011 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 3, ACC_LONG     }, /* 1100 011 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 3, ACC_WORD     }, /* 1100 011 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 3, ACC_BYTE     }, /* 1100 011 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 3, ACC_WORD     }, /* 1100 011 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 3, ACC_LONG     }, /* 1100 011 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 3, ACC_SWORD    }, /* 1100 011 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 4, ACC_BYTE     }, /* 1100 100 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 4, ACC_WORD     }, /* 1100 100 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 4, ACC_LONG     }, /* 1100 100 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 4, ACC_WORD     }, /* 1100 100 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 4, ACC_BYTE     }, /* 1100 100 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 4, ACC_WORD     }, /* 1100 100 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 4, ACC_LONG     }, /* 1100 100 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 4, ACC_SWORD    }, /* 1100 100 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 5, ACC_BYTE     }, /* 1100 101 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 5, ACC_WORD     }, /* 1100 101 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 5, ACC_LONG     }, /* 1100 101 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 5, ACC_WORD     }, /* 1100 101 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 5, ACC_BYTE     }, /* 1100 101 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 5, ACC_WORD     }, /* 1100 101 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 5, ACC_LONG     }, /* 1100 101 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 5, ACC_SWORD    }, /* 1100 101 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 6, ACC_BYTE     }, /* 1100 110 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 6, ACC_WORD     }, /* 1100 110 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 6, ACC_LONG     }, /* 1100 110 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 6, ACC_WORD     }, /* 1100 110 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 6, ACC_BYTE     }, /* 1100 110 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 6, ACC_WORD     }, /* 1100 110 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 6, ACC_LONG     }, /* 1100 110 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 6, ACC_SWORD    }, /* 1100 110 111 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.b"   , 7, ACC_BYTE     }, /* 1100 111 000 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.w"   , 7, ACC_WORD     }, /* 1100 111 001 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "and.l"   , 7, ACC_LONG     }, /* 1100 111 010 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "mulu.w"  , 7, ACC_WORD     }, /* 1100 111 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1035, "and.b"   , 7, ACC_BYTE     }, /* 1100 111 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.w"   , 7, ACC_WORD     }, /* 1100 111 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1036, "and.l"   , 7, ACC_LONG     }, /* 1100 111 110 */
+{ EA_to_Rn , 0xfd, 0x1f, 1024, "muls.w"  , 7, ACC_SWORD    }, /* 1100 111 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 0, ACC_BYTE     }, /* 1101 000 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 0, ACC_WORD     }, /* 1101 000 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 0, ACC_LONG     }, /* 1101 000 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  , 8, ACC_WORD     }, /* 1101 000 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 0, ACC_BYTE     }, /* 1101 000 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 0, ACC_WORD     }, /* 1101 000 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 0, ACC_LONG     }, /* 1101 000 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  , 8, ACC_LONG     }, /* 1101 000 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 1, ACC_BYTE     }, /* 1101 001 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 1, ACC_WORD     }, /* 1101 001 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 1, ACC_LONG     }, /* 1101 001 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  , 9, ACC_WORD     }, /* 1101 001 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 1, ACC_BYTE     }, /* 1101 001 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 1, ACC_WORD     }, /* 1101 001 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 1, ACC_LONG     }, /* 1101 001 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  , 9, ACC_LONG     }, /* 1101 001 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 2, ACC_BYTE     }, /* 1101 010 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 2, ACC_WORD     }, /* 1101 010 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 2, ACC_LONG     }, /* 1101 010 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  ,10, ACC_WORD     }, /* 1101 010 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 2, ACC_BYTE     }, /* 1101 010 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 2, ACC_WORD     }, /* 1101 010 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 2, ACC_LONG     }, /* 1101 010 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  ,10, ACC_LONG     }, /* 1101 010 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 3, ACC_BYTE     }, /* 1101 011 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 3, ACC_WORD     }, /* 1101 011 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 3, ACC_LONG     }, /* 1101 011 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  ,11, ACC_WORD     }, /* 1101 011 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 3, ACC_BYTE     }, /* 1101 011 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 3, ACC_WORD     }, /* 1101 011 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 3, ACC_LONG     }, /* 1101 011 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  ,11, ACC_LONG     }, /* 1101 011 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 4, ACC_BYTE     }, /* 1101 100 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 4, ACC_WORD     }, /* 1101 100 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 4, ACC_LONG     }, /* 1101 100 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  ,12, ACC_WORD     }, /* 1101 100 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 4, ACC_BYTE     }, /* 1101 100 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 4, ACC_WORD     }, /* 1101 100 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 4, ACC_LONG     }, /* 1101 100 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  ,12, ACC_LONG     }, /* 1101 100 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 5, ACC_BYTE     }, /* 1101 101 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 5, ACC_WORD     }, /* 1101 101 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 5, ACC_LONG     }, /* 1101 101 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  ,13, ACC_WORD     }, /* 1101 101 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 5, ACC_BYTE     }, /* 1101 101 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 5, ACC_WORD     }, /* 1101 101 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 5, ACC_LONG     }, /* 1101 101 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  ,13, ACC_LONG     }, /* 1101 101 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 6, ACC_BYTE     }, /* 1101 110 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 6, ACC_WORD     }, /* 1101 110 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 6, ACC_LONG     }, /* 1101 110 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  ,14, ACC_WORD     }, /* 1101 110 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 6, ACC_BYTE     }, /* 1101 110 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 6, ACC_WORD     }, /* 1101 110 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 6, ACC_LONG     }, /* 1101 110 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  ,14, ACC_LONG     }, /* 1101 110 111 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.b"   , 7, ACC_BYTE     }, /* 1101 111 000 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.w"   , 7, ACC_WORD     }, /* 1101 111 001 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "add.l"   , 7, ACC_LONG     }, /* 1101 111 010 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.w"  ,15, ACC_WORD     }, /* 1101 111 011 */
+{ Rn_to_EA , 0xfc, 0x03, 1033, "add.b"   , 7, ACC_BYTE     }, /* 1101 111 100 */
+{ Rn_to_EA , 0xfc, 0x03, 1038, "add.w"   , 7, ACC_WORD     }, /* 1101 111 101 */
+{ Rn_to_EA , 0xfc, 0x03, 1039, "add.l"   , 7, ACC_LONG     }, /* 1101 111 110 */
+{ EA_to_Rn , 0xff, 0x1f, 1024, "adda.l"  ,15, ACC_LONG     }, /* 1101 111 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 8, 0            }, /* 1110 000 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 8, 0            }, /* 1110 000 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 8, 0            }, /* 1110 000 010 */
+{ op1      , 0xfc, 0x03, 1024, "asr.w"   , 0, ACC_WORD     }, /* 1110 000 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 8, 0            }, /* 1110 000 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 8, 0            }, /* 1110 000 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 8, 0            }, /* 1110 000 110 */
+{ op1      , 0xfc, 0x03, 1024, "asl.w"   , 0, ACC_WORD     }, /* 1110 000 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 1, 0            }, /* 1110 001 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 1, 0            }, /* 1110 001 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 1, 0            }, /* 1110 001 010 */
+{ op1      , 0xfc, 0x03, 1024, "lsr.w"   , 0, ACC_WORD     }, /* 1110 001 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 1, 0            }, /* 1110 001 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 1, 0            }, /* 1110 001 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 1, 0            }, /* 1110 001 110 */
+{ op1      , 0xfc, 0x03, 1024, "lsl.w"   , 0, ACC_WORD     }, /* 1110 001 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 2, 0            }, /* 1110 010 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 2, 0            }, /* 1110 010 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 2, 0            }, /* 1110 010 010 */
+{ op1      , 0xfc, 0x03, 1024, "roxr.w"  , 0, ACC_WORD     }, /* 1110 010 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 2, 0            }, /* 1110 010 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 2, 0            }, /* 1110 010 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 2, 0            }, /* 1110 010 110 */
+{ op1      , 0xfc, 0x03, 1024, "roxl.w"  , 0, ACC_WORD     }, /* 1110 010 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 3, 0            }, /* 1110 011 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 3, 0            }, /* 1110 011 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 3, 0            }, /* 1110 011 010 */
+{ op1      , 0xfc, 0x03, 1024, "ror.w"   , 0, ACC_WORD     }, /* 1110 011 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 3, 0            }, /* 1110 011 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 3, 0            }, /* 1110 011 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 3, 0            }, /* 1110 011 110 */
+{ op1      , 0xfc, 0x03, 1024, "rol.w"   , 0, ACC_WORD     }, /* 1110 011 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 4, 0            }, /* 1110 100 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 4, 0            }, /* 1110 100 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 4, 0            }, /* 1110 100 010 */
+{ bitfield , 0xe5, 0x0f, 1024, "bftst"   , SINGLEOP, 0     }, /* 1110 100 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 4, 0            }, /* 1110 100 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 4, 0            }, /* 1110 100 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 4, 0            }, /* 1110 100 110 */
+{ bitfield , 0xe5, 0x0f, 1024, "bfextu"  , DATADEST, 0     }, /* 1110 100 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 5, 0            }, /* 1110 101 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 5, 0            }, /* 1110 101 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 5, 0            }, /* 1110 101 010 */
+{ bitfield , 0xe5, 0x03, 1024, "bfchg"   , SINGLEOP, 0     }, /* 1110 101 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 5, 0            }, /* 1110 101 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 5, 0            }, /* 1110 101 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 5, 0            }, /* 1110 101 110 */
+{ bitfield , 0xe5, 0x0f, 1024, "bfexts"  , DATADEST, 0     }, /* 1110 101 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 6, 0            }, /* 1110 110 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 6, 0            }, /* 1110 110 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 6, 0            }, /* 1110 110 010 */
+{ bitfield , 0xe5, 0x03, 1024, "bfclr"   , SINGLEOP, 0     }, /* 1110 110 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 6, 0            }, /* 1110 110 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 6, 0            }, /* 1110 110 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 6, 0            }, /* 1110 110 110 */
+{ bitfield , 0xe5, 0x0f, 1024, "bfffo"   , DATADEST, 0     }, /* 1110 110 111 */
+{ shiftreg , 0xff, 0xff, 1024, "r.b"     , 7, 0            }, /* 1110 111 000 */
+{ shiftreg , 0xff, 0xff, 1024, "r.w"     , 7, 0            }, /* 1110 111 001 */
+{ shiftreg , 0xff, 0xff, 1024, "r.l"     , 7, 0            }, /* 1110 111 010 */
+{ bitfield , 0xe5, 0x03, 1024, "bfset"   , SINGLEOP, 0     }, /* 1110 111 011 */
+{ shiftreg , 0xff, 0xff, 1024, "l.b"     , 7, 0            }, /* 1110 111 100 */
+{ shiftreg , 0xff, 0xff, 1024, "l.w"     , 7, 0            }, /* 1110 111 101 */
+{ shiftreg , 0xff, 0xff, 1024, "l.l"     , 7, 0            }, /* 1110 111 110 */
+{ bitfield , 0xe5, 0x03, 1024, "bfins"   , DATASRC, 0      }, /* 1110 111 111 */
+
+{ mmu30    , 0xe5, 0x03, 1024, 0         , 7, 0            }, /* 1111 000 000 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 001 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 010 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 011 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 100 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 101 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 110 */   
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 000 111 */   
+/* FPU opcode encodings */
+{ fpu      , 0xff, 0xff, 1024, 0         , 1, 0            }, /* 1111 001 000 */
+{ fscc     , 0xfd, 0x03, 1047, "fs"      , 1, 0            }, /* 1111 001 001 */
+{ fbranch  , 0xff, 0x00, 1024, "fb"      , 0, ACC_CODE     }, /* 1111 001 010 */
+{ fbranch  , 0xff, 0x00, 1024, "fb"      , 1, ACC_CODE     }, /* 1111 001 011 */
+{ op1      , 0xf4, 0x03, 1024, "fsave"   , 0, ACC_LONG     }, /* 1111 001 100 */
+{ op1      , 0xec, 0x0f, 1024, "frestore", 0, ACC_LONG     }, /* 1111 001 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1111 001 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 0, 0            }, /* 1111 001 111 */
+
+/* Opcodes for user-definable coprocessors */
+{ cache    , 0xee, 0xff, 1024, 0         , 0, 0            }, /* 1111 010 000 */
+{ cache    , 0xee, 0xff, 1024, 0         , 1, 0            }, /* 1111 010 001 */
+{ cache    , 0xee, 0xff, 1024, 0         , 2, 0            }, /* 1111 010 010 */
+{ cache    , 0xee, 0xff, 1024, 0         , 3, 0            }, /* 1111 010 011 */
+{ pflush40 , 0x0f, 0xff, 1024, "pflush"  , 0, 0            }, /* 1111 010 100 */
+{ ptest40  , 0x22, 0xff, 1024, "ptest"   , 7, 0            }, /* 1111 010 101 */
+{ plpa60   , 0x02, 0x00, 1024, "plpaw"   , 7, 0            }, /* 1111 010 110 */
+{ plpa60   , 0x02, 0x00, 1024, "plpar"   , 7, 0            }, /* 1111 010 111 */
+{ move16   , 0x1f, 0xff, 1024, "move16"  , 7, 0            }, /* 1111 011 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 011 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 100 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 101 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 110 111 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 000 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 001 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 010 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 011 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 100 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 101 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 110 */
+{ invalid  , 0xff, 0xff, 1024, 0         , 7, 0            }, /* 1111 111 111 */
+
+/* Here are the chained routines for handling doubly-defined opcodes */
+
+{ invalid  , 0xff, 0xff,    0, 0         , 0, 0            }, /* 1024 */
+{ illegal  , 0x80, 0x10, 1024, "illegal" , 0, 0            }, /* 1025 */
+{ srccr    , 0x80, 0x10, 1024, 0         , 0, 0            }, /* 1026 */
+{ op1_end  , 0x03, 0x00, 1024, "rtm"     , 0, 0            }, /* 1027 */
+{ op2_bcdx , 0x03, 0x00, 1024, "unpk"    , ADJUST, 0       }, /* 1028 */
+{ op1      , 0x01, 0x00, 1049, "swap"    , 0, ACC_LONG     }, /* 1029 */
+{ op1      , 0x01, 0x00, 1024, "ext.w"   , 0, ACC_WORD     }, /* 1030 */
+{ op2_bcdx , 0x03, 0x00, 1024, "sbcd"    , NO_ADJ, 0       }, /* 1031 */
+{ op2_bcdx , 0x03, 0x00, 1024, "pack"    , ADJUST, 0       }, /* 1032 */
+{ op2_bcdx , 0x03, 0x00, 1024, "addx.b"  , NO_ADJ, 0       }, /* 1033 */
+{ cmpm     , 0x02, 0xff, 1024, "cmpm.b"  , 0, 0            }, /* 1034 */
+{ op2_bcdx , 0x03, 0x00, 1024, "abcd.b"  , NO_ADJ, 0       }, /* 1035 */
+{ exg      , 0x03, 0x00, 1024, "exg"     , 0, 0            }, /* 1036 */
+{ movep    , 0x02, 0x00, 1024, "movep"   , 0, 0            }, /* 1037 */
+{ op2_bcdx , 0x03, 0x00, 1024, "addx.w"  , NO_ADJ, 0       }, /* 1038 */
+{ op2_bcdx , 0x03, 0x00, 1024, "addx.l"  , NO_ADJ, 0       }, /* 1039 */
+{ cas2     , 0x80, 0x10, 1024, "cas2.b"  , 0, ACC_BYTE     }, /* 1040 */
+{ cas2     , 0x80, 0x10, 1024, "cas2.w"  , 0, ACC_WORD     }, /* 1041 */
+{ cas2     , 0x80, 0x10, 1024, "cas2.l"  , 0, ACC_LONG     }, /* 1042 */
+{ cmpm     , 0x02, 0xff, 1024, "cmpm.w"  , 0, 0            }, /* 1043 */
+{ cmpm     , 0x02, 0xff, 1024, "cmpm.l"  , 0, 0            }, /* 1044 */
+{ trapcc   , 0x80, 0x1c, 1024, "trap"    , 0, 0            }, /* 1045 */
+{ scc      , 0xfd, 0x03, 1045, "s"       , 0, ACC_BYTE     }, /* 1046 */
+{ fdbranch , 0x02, 0x00, 1048, "fdb"     , 0, 0            }, /* 1047 */
+{ ftrapcc  , 0x80, 0x1c, 1024, "ftrap"   , 0, 0            }, /* 1048 */
+{ bkpt     , 0x02, 0xff, 1024, "bkpt"    , 0, 0            }, /* 1049 */    
+{ op1      , 0x01, 0x00, 1024, "ext.l"   , 0, ACC_LONG     }, /* 1050 */
+{ op1      , 0x01, 0x00, 1024, "extb.l"  , 0, ACC_LONG     }, /* 1051 */
+{ op2_bcdx , 0x03, 0x00, 1024, "subx.b"  , NO_ADJ, 0       }, /* 1052 */
+{ op2_bcdx , 0x03, 0x00, 1024, "subx.w"  , NO_ADJ, 0       }, /* 1053 */
+{ op2_bcdx , 0x03, 0x00, 1024, "subx.l"  , NO_ADJ, 0       }, /* 1054 */
+{ link_l   , 0x02, 0x00, 1024, "link.l"  , 0, 0            }, /* 1055 */
+/* ColdFire chains */
+{ op1      , 0x03, 0x00, 1024, "bitrev"  , 0, ACC_LONG     }, /* 1056 */
+{ op1      , 0x03, 0x00, 1024, "byterev" , 0, ACC_LONG     }, /* 1057 */
+{ op1      , 0x03, 0x00, 1024, "ff1"     , 0, ACC_LONG     }, /* 1058 */
+{ op1      , 0x03, 0x00, 1024, "sats"    , 0, ACC_SLONG    }  /* 1059 */
+};
diff --git a/cputest/adis/opcodes_fpu.c b/cputest/adis/opcodes_fpu.c
new file mode 100644 (file)
index 0000000..f688101
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Change history
+ * $Log:       fpu_opcodes.c,v $
+ * Revision 3.0  93/09/24  17:53:57  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.1  93/07/18  22:55:54  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.0  93/07/01  11:53:57  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.6  93/06/16  20:27:22  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * 
+ * Revision 1.5  93/06/03  20:27:05  Martin_Apel
+ * 
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: fpu_opcodes.c,v 3.0 93/09/24 17:53:57 Martin_Apel Exp $"; */
+
+struct opcode_sub_entry fpu_opcode_table [] =
+{
+/* *handler,  *mnemonic, param, access */
+
+{ std_fpu  , "fmove"  ,       0, 0 },        /* 000 0000 */
+{ std_fpu  , "fint"   , SNG_ALL, 0 },        /* 000 0001 */
+{ std_fpu  , "fsinh"  , SNG_ALL, 0 },        /* 000 0010 */
+{ std_fpu  , "fintrz" , SNG_ALL, 0 },        /* 000 0011 */
+{ std_fpu  , "fsqrt"  , SNG_ALL, 0 },        /* 000 0100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 000 0101 */
+{ std_fpu  , "flognp1", SNG_ALL, 0 },        /* 000 0110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 000 0111 */
+{ std_fpu  , "fetoxm1", SNG_ALL, 0 },        /* 000 1000 */
+{ std_fpu  , "ftanh"  , SNG_ALL, 0 },        /* 000 1001 */
+{ std_fpu  , "fatan"  , SNG_ALL, 0 },        /* 000 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 000 1011 */
+{ std_fpu  , "fasin"  , SNG_ALL, 0 },        /* 000 1100 */
+{ std_fpu  , "fatanh" , SNG_ALL, 0 },        /* 000 1101 */
+{ std_fpu  , "fsin"   , SNG_ALL, 0 },        /* 000 1110 */
+{ std_fpu  , "ftan"   , SNG_ALL, 0 },        /* 000 1111 */
+{ std_fpu  , "fetox"  , SNG_ALL, 0 },        /* 001 0000 */
+{ std_fpu  , "ftwotox", SNG_ALL, 0 },        /* 001 0001 */
+{ std_fpu  , "ftentox", SNG_ALL, 0 },        /* 001 0010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 001 0011 */
+{ std_fpu  , "flogn"  , SNG_ALL, 0 },        /* 001 0100 */
+{ std_fpu  , "flog10" , SNG_ALL, 0 },        /* 001 0101 */
+{ std_fpu  , "flog2"  , SNG_ALL, 0 },        /* 001 0110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 001 0111 */
+{ std_fpu  , "fabs"   , SNG_ALL, 0 },        /* 001 1000 */
+{ std_fpu  , "fcosh"  , SNG_ALL, 0 },        /* 001 1001 */
+{ std_fpu  , "fneg"   , SNG_ALL, 0 },        /* 001 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 001 1011 */
+{ std_fpu  , "facos"  , SNG_ALL, 0 },        /* 001 1100 */
+{ std_fpu  , "fcos"   , SNG_ALL, 0 },        /* 001 1101 */
+{ std_fpu  , "fgetexp", SNG_ALL, 0 },        /* 001 1110 */
+{ std_fpu  , "fgetman", SNG_ALL, 0 },        /* 001 1111 */
+{ std_fpu  , "fdiv"   ,       0, 0 },        /* 010 0000 */
+{ std_fpu  , "fmod"   ,       0, 0 },        /* 010 0001 */
+{ std_fpu  , "fadd"   ,       0, 0 },        /* 010 0010 */
+{ std_fpu  , "fmul"   ,       0, 0 },        /* 010 0011 */
+{ std_fpu  , "fsgldiv",       0, 0 },        /* 010 0100 */
+{ std_fpu  , "frem"   ,       0, 0 },        /* 010 0101 */
+{ std_fpu  , "fscale" ,       0, 0 },        /* 010 0110 */
+{ std_fpu  , "fsglmul",       0, 0 },        /* 010 0111 */
+{ std_fpu  , "fsub"   ,       0, 0 },        /* 010 1000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1011 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 010 1111 */
+{ fsincos  , "fsincos",       0, 0 },        /* 011 0000 */
+{ fsincos  , "fsincos",       1, 0 },        /* 011 0001 */
+{ fsincos  , "fsincos",       2, 0 },        /* 011 0010 */
+{ fsincos  , "fsincos",       3, 0 },        /* 011 0011 */
+{ fsincos  , "fsincos",       4, 0 },        /* 011 0100 */
+{ fsincos  , "fsincos",       5, 0 },        /* 011 0101 */
+{ fsincos  , "fsincos",       6, 0 },        /* 011 0110 */
+{ fsincos  , "fsincos",       7, 0 },        /* 011 0111 */
+{ std_fpu  , "fcmp"   ,       0, 0 },        /* 011 1000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 011 1001 */
+{ ftst     , "ftst"   ,       0, 0 },        /* 011 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 011 1011 */
+{ invalid2 ,  0       ,       0, 0 },        /* 011 1100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 011 1101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 011 1110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 011 1111 */
+
+{ std_fpu  , "fsmove" ,       0, 0 },        /* 100 0000 */
+{ std_fpu  , "fssqrt" , SNG_ALL, 0 },        /* 100 0001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 0010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 0011 */
+{ std_fpu  , "fdmove" ,       0, 0 },        /* 100 0100 */
+{ std_fpu  , "fdsqrt" , SNG_ALL, 0 },        /* 100 0101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 0110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 0111 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1011 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 100 1111 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0011 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 0111 */
+{ std_fpu  , "fsabs"  , SNG_ALL, 0 },        /* 101 1000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 1001 */
+{ std_fpu  , "fsneg"  , SNG_ALL, 0 },        /* 101 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 1011 */
+{ std_fpu  , "fdabs"  , SNG_ALL, 0 },        /* 101 1100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 1101 */
+{ std_fpu  , "fdneg"  , SNG_ALL, 0 },        /* 101 1110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 101 1111 */
+{ std_fpu  , "fsdiv"  ,       0, 0 },        /* 110 0000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 0001 */
+{ std_fpu  , "fsadd"  ,       0, 0 },        /* 110 0010 */
+{ std_fpu  , "fsmul"  ,       0, 0 },        /* 110 0011 */
+{ std_fpu  , "fddiv"  ,       0, 0 },        /* 110 0100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 0101 */
+{ std_fpu  , "fdadd"  ,       0, 0 },        /* 110 0110 */
+{ std_fpu  , "fdmul"  ,       0, 0 },        /* 110 0111 */
+{ std_fpu  , "fssub"  ,       0, 0 },        /* 110 1000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 1001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 1011 */
+{ std_fpu  , "fdsub"  ,       0, 0 },        /* 110 1100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 1101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 1110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 110 1111 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0011 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0110 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 0111 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1000 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1001 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1010 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1011 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1100 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1101 */
+{ invalid2 ,  0       ,       0, 0 },        /* 111 1110 */
+{ invalid2 ,  0       ,       0, 0 }         /* 111 1111 */
+};
+
+char *xfer_size [] = { ".l",
+                       ".s",
+                       ".x",
+                       ".p",
+                       ".w",
+                       ".d",
+                       ".b",
+                       ".p",  };
+
+UWORD sizes [] = { ACC_LONG   | ACC_DATA,
+                   ACC_LONG   | ACC_DATA,
+                   ACC_EXTEND | ACC_DATA,
+                   ACC_EXTEND | ACC_DATA,
+                   ACC_WORD   | ACC_DATA,
+                   ACC_DOUBLE | ACC_DATA,
+                   ACC_BYTE   | ACC_DATA,
+                   ACC_EXTEND | ACC_DATA };
+
+char *fpu_conditions [] = {
+  "f",
+  "eq",
+  "ogt",
+  "oge",
+  "olt",
+  "ole",
+  "ogl",
+  "or",
+  "un",        /* 8 */
+  "ueq",
+  "ugt",
+  "uge",
+  "ult",
+  "ule",
+  "ne",
+  "t",
+  "sf",        /* 16 */
+  "seq",
+  "gt",
+  "ge",
+  "lt",
+  "le",
+  "gl",
+  "gle",
+  "ngle",      /* 24 */
+  "ngl",
+  "nle",
+  "nlt",
+  "nge",
+  "ngt",
+  "sne",
+  "st"
+};
diff --git a/cputest/adis/opcodes_mmu.c b/cputest/adis/opcodes_mmu.c
new file mode 100644 (file)
index 0000000..7b33034
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Change history
+ * $Log:       mmu_opcodes.c,v $
+ * Revision 3.0  93/09/24  17:54:10  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.2  93/07/18  22:56:14  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.1  93/07/08  20:47:50  Martin_Apel
+ * Bug fix: Replaced illegal with pmove30
+ * 
+ * Revision 2.0  93/07/01  11:54:18  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.1  93/06/19  12:11:42  Martin_Apel
+ * Initial revision
+ * 
+ */
+
+#include "defs.h"
+
+/* static char rcsid [] = "$Id: mmu_opcodes.c,v 3.0 93/09/24 17:54:10 Martin_Apel Exp $"; */
+
+/* Table for the bits 14 to 10 of the second word of mmu opcodes */
+
+struct opcode_sub_entry mmu_opcode_table [] =
+{
+/* *handler, *mnemonic,   param, access */
+
+{ invalid2 , 0        ,       0, 0 },        /* 0 0000 */
+{ invalid2 , 0        ,       0, 0 },        /* 0 0001 */ 
+{ pmove30  , "pmove"  ,     TT0, 0 },        /* 0 0010 */ 
+{ pmove30  , "pmove"  ,     TT1, 0 },        /* 0 0011 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 0 0100 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 0 0101 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 0 0110 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 0 0111 */ 
+{ pfl_or_ld, "pflush" ,       0, 0 },        /* 0 1000 */ 
+{ pflush30 , "pflush" ,       1, 0 },        /* 0 1001 */ 
+{ pflush30 , "pflush" ,       2, 0 },        /* 0 1010 */ 
+{ pflush30 , "pflush" ,       3, 0 },        /* 0 1011 */ 
+{ pflush30 , "pflush" ,       4, 0 },        /* 0 1100 */ 
+{ pflush30 , "pflush" ,       5, 0 },        /* 0 1101 */ 
+{ pflush30 , "pflush" ,       6, 0 },        /* 0 1110 */ 
+{ pflush30 , "pflush" ,       7, 0 },        /* 0 1111 */ 
+{ pmove30  , "pmove"  ,      TC, 0 },        /* 1 0000 */ 
+{ invalid2 ,  0       ,       0, 0 },        /* 1 0001 */ 
+{ pmove30  , "pmove"  ,     SRP, 0 },        /* 1 0010 */ 
+{ pmove30  , "pmove"  ,     CRP, 0 },        /* 1 0011 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 0100 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 0101 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 0110 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 0111 */ 
+{ pmove30  , "pmove"  ,   MMUSR, 0 },        /* 1 1000 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 1001 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 1010 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 1011 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 1100 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 1101 */ 
+{ invalid2 , 0        ,       0, 0 },        /* 1 1110 */ 
+{ invalid2 , 0        ,       0, 0 }         /* 1 1111 */ 
+};
diff --git a/cputest/adis/string_recog.h b/cputest/adis/string_recog.h
new file mode 100644 (file)
index 0000000..87d414a
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * Change history
+ * $Log:       string_recog.h,v $
+ * Revision 3.0  93/09/24  17:54:41  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.1  93/07/18  22:57:12  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.0  93/07/01  11:55:11  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.4  93/06/03  20:31:25  Martin_Apel
+ * 
+ * 
+ */
+
+/* $Id: string_recog.h,v 3.0 93/09/24 17:54:41 Martin_Apel Exp $ */
+
+#define C_PRINT   0x01  /* printable character including german umlauts */
+#define C_NAME    0x02  /* character is valid in a C variable name */
+#define C_NORM    0x04  /* common/normal character */
+#define C_NUM     0x08  /* character is a decimal number 0-9 */
+#define C_HEX     0x10  /* character is a hexadecimal number 0-9,A-F,a-f */
+#define C_PATH    0x20  /* character is valid in a path and file name */
+#define C_ALL     0x80  /* all valid printable or control characters */
+
+#define IS_PRINTABLE(c) (c_table[c] & C_PRINT)
+#define IS_NAME(c)      (c_table[c] & C_NAME)
+#define IS_COMMON(c)    (c_table[c] & C_NORM)
+#define IS_VALID(c)     (c_table[c] & C_ALL)
+#define IS_NUM(c)       (c_table[c] & C_NUM)
+#define IS_HEX(c)       (c_table[c] & C_HEX)
+#define IS_PATH(c)      (c_table[c] & C_PATH)
+
+static const UBYTE c_table [256] =
+  {
+  0,                                                          /* $0 EOS */
+  0,                                                          /* $1 */
+  0,                                                          /* $2 */
+  0,                                                          /* $3 */
+  0,                                                          /* $4 */
+  0,                                                          /* $5 */
+  0,                                                          /* $6 */
+  C_ALL,                                                      /* $7 bell */
+  C_ALL,                                                      /* $8 BS */
+  C_ALL | C_NORM,                                             /* $9 TAB */
+  C_ALL | C_NORM,                                             /* $A LF */
+  0,                                                          /* $B */
+  C_ALL,                                                      /* $C FF */
+  C_ALL | C_NORM,                                             /* $D CR */
+  0,                                                          /* $E */
+  0,                                                          /* $F */
+
+  0,                                                          /* $10 */
+  0,                                                          /* $11 */
+  0,                                                          /* $12 */
+  0,                                                          /* $13 */
+  0,                                                          /* $14 */
+  0,                                                          /* $15 */
+  0,                                                          /* $16 */
+  0,                                                          /* $17 */
+  0,                                                          /* $18 */
+  0,                                                          /* $19 */
+  0,                                                          /* $1A */
+  C_ALL,                                                      /* $1B ESC */
+  0,                                                          /* $1C */
+  0,                                                          /* $1D */
+  0,                                                          /* $1E */
+  0,                                                          /* $1F */
+
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $20 SPACE */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $21 ! */
+  C_ALL | C_PRINT | C_NORM,                                   /* $22 " */
+  C_ALL | C_PRINT | C_NORM,                                   /* $23 # */
+  C_ALL | C_PRINT | C_NORM,                                   /* $24 $ */
+  C_ALL | C_PRINT | C_NORM,                                   /* $25 % */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $26 & */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $27 ' */
+  C_ALL | C_PRINT | C_NORM,                                   /* $28 ( */
+  C_ALL | C_PRINT | C_NORM,                                   /* $29 ) */
+  C_ALL | C_PRINT | C_NORM,                                   /* $2A * */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $2B + */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $2C , */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $2D - */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $2E . */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $2F / */
+
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $30 0 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $31 1 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $32 2 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $33 3 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $34 4 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $35 5 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $36 6 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $37 7 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $38 8 */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_NUM | C_HEX | C_PATH, /* $39 9 */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $3A : */
+  C_ALL | C_PRINT | C_NORM,                                   /* $3B ; */
+  C_ALL | C_PRINT | C_NORM,                                   /* $3C < */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $3D = */
+  C_ALL | C_PRINT | C_NORM,                                   /* $3E > */
+  C_ALL | C_PRINT | C_NORM,                                   /* $3F ? */
+
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $40 @ */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $41 A */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $42 B */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $43 C */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $44 D */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $45 E */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $46 F */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $47 G */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $48 H */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $49 I */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $4A J */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $4B K */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $4C L */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $4D M */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $4E N */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $4F O */
+
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $50 P */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $51 Q */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $52 R */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $53 S */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $54 T */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $55 U */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $56 V */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $57 W */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $58 X */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $59 Y */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $5A Z */
+  C_ALL | C_PRINT | C_NORM,                                   /* $5B [ */
+  C_ALL | C_PRINT | C_NORM,                                   /* $5C \ */
+  C_ALL | C_PRINT | C_NORM,                                   /* $5D ] */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $5E ^ */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $5F _ */
+
+  C_ALL | C_PRINT | C_NORM,                                   /* $60 ` */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $61 a */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $62 b */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $63 c */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $64 d */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $65 e */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_HEX | C_PATH,         /* $66 f */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $67 g */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $68 h */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $69 i */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $6A j */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $6B k */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $6C l */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $6D m */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $6E n */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $6F o */
+
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $70 p */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $71 q */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $72 r */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $73 s */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $74 t */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $75 u */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $76 v */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $77 w */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $78 x */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $79 y */
+  C_ALL | C_PRINT | C_NAME | C_NORM | C_PATH,                 /* $7A z */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $7B { */
+  C_ALL | C_PRINT | C_NORM,                                   /* $7C | */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $7D } */
+  C_ALL | C_PRINT | C_NORM,                                   /* $7E ~ */
+  C_ALL,                                                      /* $7F DEL */
+
+  0,                                                          /* $80 */
+  0,                                                          /* $81 */
+  0,                                                          /* $82 */
+  0,                                                          /* $83 */
+  0,                                                          /* $84 */
+  0,                                                          /* $85 */
+  0,                                                          /* $86 */
+  0,                                                          /* $87 */
+  0,                                                          /* $88 */
+  0,                                                          /* $89 */
+  0,                                                          /* $8A */
+  0,                                                          /* $8B */
+  0,                                                          /* $8C */
+  0,                                                          /* $8D */
+  0,                                                          /* $8E */
+  0,                                                          /* $8F */
+
+  0,                                                          /* $90 */
+  0,                                                          /* $91 */
+  0,                                                          /* $92 */
+  0,                                                          /* $93 */
+  0,                                                          /* $94 */
+  0,                                                          /* $95 */
+  0,                                                          /* $96 */
+  0,                                                          /* $97 */
+  0,                                                          /* $98 */
+  0,                                                          /* $99 */
+  0,                                                          /* $9A */
+  0,                                                          /* $9B */
+  0,                                                          /* $9C */
+  0,                                                          /* $9D */
+  0,                                                          /* $9E */
+  0,                                                          /* $9F */
+
+  0,                                                          /* $A0 */
+  0,                                                          /* $A1 */
+  0,                                                          /* $A2 */
+  0,                                                          /* $A3 */
+  0,                                                          /* $A4 */
+  0,                                                          /* $A5 */
+  0,                                                          /* $A6 */
+  0,                                                          /* $A7 */
+  0,                                                          /* $A8 */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $A9 Â© */
+  0,                                                          /* $AA */
+  0,                                                          /* $AB */
+  0,                                                          /* $AC */
+  0,                                                          /* $AD */
+  0,                                                          /* $AE */
+  0,                                                          /* $AF */
+
+  0,                                                          /* $B0 */
+  0,                                                          /* $B1 */
+  0,                                                          /* $B2 */
+  0,                                                          /* $B3 */
+  0,                                                          /* $B4 */
+  0,                                                          /* $B5 */
+  0,                                                          /* $B6 */
+  0,                                                          /* $B7 */
+  0,                                                          /* $B8 */
+  0,                                                          /* $B9 */
+  0,                                                          /* $BA */
+  0,                                                          /* $BB */
+  0,                                                          /* $BC */
+  0,                                                          /* $BD */
+  0,                                                          /* $BE */
+  0,                                                          /* $BF */
+
+  0,                                                          /* $C0 */
+  0,                                                          /* $C1 */
+  0,                                                          /* $C2 */
+  0,                                                          /* $C3 */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $C4 Ã„ */
+  0,                                                          /* $C5 */
+  0,                                                          /* $C6 */
+  0,                                                          /* $C7 */
+  0,                                                          /* $C8 */
+  0,                                                          /* $C9 */
+  0,                                                          /* $CA */
+  0,                                                          /* $CB */
+  0,                                                          /* $CC */
+  0,                                                          /* $CD */
+  0,                                                          /* $CE */
+  0,                                                          /* $CF */
+
+  0,                                                          /* $D0 */
+  0,                                                          /* $D1 */
+  0,                                                          /* $D2 */
+  0,                                                          /* $D3 */
+  0,                                                          /* $D4 */
+  0,                                                          /* $D5 */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $D6 Ã– */
+  0,                                                          /* $D7 */
+  0,                                                          /* $D8 */
+  0,                                                          /* $D9 */
+  0,                                                          /* $DA */
+  0,                                                          /* $DB */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $DC Ãœ */
+  0,                                                          /* $DD */
+  0,                                                          /* $DE */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $DF ÃŸ */
+
+  0,                                                          /* $E0 */
+  0,                                                          /* $E1 */
+  0,                                                          /* $E2 */
+  0,                                                          /* $E3 */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $E4 Ã¤ */
+  0,                                                          /* $E5 */
+  0,                                                          /* $E6 */
+  0,                                                          /* $E7 */
+  0,                                                          /* $E8 */
+  0,                                                          /* $E9 */
+  0,                                                          /* $EA */
+  0,                                                          /* $EB */
+  0,                                                          /* $EC */
+  0,                                                          /* $ED */
+  0,                                                          /* $EE */
+  0,                                                          /* $EF */
+
+  0,                                                          /* $F0 */
+  0,                                                          /* $F1 */
+  0,                                                          /* $F2 */
+  0,                                                          /* $F3 */
+  0,                                                          /* $F4 */
+  0,                                                          /* $F5 */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $F6 Ã¶ */
+  0,                                                          /* $F7 */
+  0,                                                          /* $F8 */
+  0,                                                          /* $F9 */
+  0,                                                          /* $FA */
+  0,                                                          /* $FB */
+  C_ALL | C_PRINT | C_NORM | C_PATH,                          /* $FC Ã¼ */
+  0,                                                          /* $FD */
+  0,                                                          /* $FE */
+  0                                                           /* $FF */
+  };
diff --git a/cputest/adis/util.c b/cputest/adis/util.c
new file mode 100644 (file)
index 0000000..75654c8
--- /dev/null
@@ -0,0 +1,999 @@
+/*
+ * Change history
+ * $Log:       util.c,v $
+ *
+ * Revision 3.1  09/10/15  Matt_Hey
+ * New: col_put(), add_str(), str_len(). Many other changes. 
+ * Addressing modes changed to new style, lower case
+ *
+ * Revision 3.0  93/09/24  17:54:29  Martin_Apel
+ * New feature: Added extra 68040 FPU opcodes
+ * 
+ * Revision 2.3  93/07/18  22:56:58  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 2.2  93/07/10  13:02:35  Martin_Apel
+ * Major mod.: Added full jump table support. Seems to work quite well
+ * 
+ * Revision 2.1  93/07/08  22:29:31  Martin_Apel
+ * 
+ * Minor mod.: Displacements below 4 used with pc indirect indexed are
+ *             not entered into the symbol table anymore
+ * 
+ * Revision 2.0  93/07/01  11:54:56  Martin_Apel
+ * *** empty log message ***
+ * 
+ * Revision 1.17  93/07/01  11:45:00  Martin_Apel
+ * Minor mod.: Removed $-sign from labels
+ * Minor mod.: Prepared for tabs instead of spaces
+ * 
+ * Revision 1.16  93/06/16  20:31:31  Martin_Apel
+ * Minor mod.: Removed #ifdef FPU_VERSION and #ifdef MACHINE68020
+ * 
+ * Revision 1.15  93/06/04  11:56:35  Martin_Apel
+ * New feature: Added -ln option for generation of ascending label numbers
+ * 
+ * Revision 1.14  93/06/03  20:30:17  Martin_Apel
+ * Minor mod.: Additional linefeed generation for end instructions has been
+ *             moved to format_line
+ * New feature: Added -a switch to generate comments for file offsets
+ * 
+ * Revision 1.13  93/05/27  20:50:48  Martin_Apel
+ * Bug fix: Register list was misinterpreted for MOVEM / FMOVEM
+ *          instructions.
+ * 
+ */
+
+#include "defs.h"
+#include "string_recog.h"
+#include <ctype.h>
+
+/* static char rcsid [] =  "$Id: util.c,v 3.1 09/10/15 Martin_Apel Exp $"; */
+
+/**********************************************************************/
+/*      A few routines doing string handling such as formatting       */
+/*        a hex value, formatting the register list for MOVEM         */
+/*              instructions, different address modes...              */
+/*        sprintf would have been much easier but sloooow !!!         */
+/**********************************************************************/
+
+const char hex_chars [] = "0123456789abcdef";  /* for format() functions */
+
+/**************************************************************************/
+
+char *str_cpy (char *dest, const char *src)
+
+/* str_cpy() returns new dest (end of str), strcpy() returns old dest */
+{
+while (*dest++ = *src++);
+return (dest - 1);
+}
+
+/**************************************************************************/
+
+char *str_cat (char *dest, const char *src)
+
+/* str_cat() returns new dest (end of str), strcat() returns old dest */
+{
+while (*dest)
+  dest++;
+while(*dest++ = *src++);
+return (dest - 1);
+}
+
+/**************************************************************************/
+
+BOOL is_str (char *maybe_string, uint max_len)
+
+{
+register uchar *tmp_str;
+uchar *last_char;
+
+tmp_str = (uchar*) maybe_string;
+last_char = tmp_str + max_len;
+while (IS_VALID (*tmp_str) && (tmp_str < last_char))
+  tmp_str++;
+if ((*tmp_str != 0) || ((char*)tmp_str == maybe_string))  /* single 0 char is not a string */
+  return (FALSE);
+return (TRUE);
+}
+
+/**************************************************************************/
+
+int str_len (char *maybe_string, uint max_len)
+
+/* str_len() returns string length or 0 if not a valid string */
+{
+register uchar *tmp_str;
+uchar *last_char;
+
+tmp_str = (uchar*) maybe_string;
+last_char = tmp_str + max_len;
+while (IS_VALID (*tmp_str) && (tmp_str < last_char))
+  tmp_str++;
+
+if (*tmp_str == 0)
+  return ((char*)tmp_str - maybe_string);
+return (0);
+}
+
+/**************************************************************************/
+
+void emit (char *string)
+
+/* fputs a string */
+{
+#ifdef DEBUG
+if (out == NULL)
+  {
+  fprintf (stderr, "ERROR: Attempt to write to closed file in emit()\n");
+  ExitADis ();
+  }
+#endif
+
+if (fputs (string, out) == EOF)
+  {
+  fprintf (stderr, "ERROR: Writing output file\n");
+  ExitADis ();
+  }
+}
+
+/**************************************************************************/
+
+void col_emit (char *string)
+
+/* fputs leading OPCODE_COL blanks followed by string */
+{
+
+#ifdef DEBUG
+if (out == NULL)
+  {
+  fprintf (stderr, "ERROR: Attempt to write to closed file in col_emit()\n");
+  ExitADis ();
+  }
+#endif
+
+if (fputs (spaces, out) == EOF)
+  {
+  fprintf (stderr, "ERROR: Writing output file\n");
+  ExitADis ();
+  }
+if (fputs (string, out) == EOF)
+  {
+  fprintf (stderr, "ERROR: Writing output file\n");
+  ExitADis ();
+  }
+}
+
+/**************************************************************************/
+
+char *format_line (char *to, BOOL commented, int instr_words)
+
+/* format opcode, src and dest to to */
+{
+char *tmp_str;
+register int i;
+register char reg_space_char = space_char;
+
+tmp_str = to;
+i = OPCODE_COL;
+do
+  {
+  *to++ = reg_space_char;
+  i--;
+  }
+while (i > 0);
+to = str_cpy (to, opcode);
+
+if (!(src [0] == 0 && dest [0] == 0))
+  {
+  i = PARAM_COL - (to - tmp_str);
+  do
+    {
+      *to++ = reg_space_char;
+      i--;
+    }
+  while (i > 0);
+  if (dest [0] == 0)
+    to = str_cpy (to, src);
+  else if (src [0] == 0)
+    to = str_cpy (to, dest);
+  else
+    {
+    to = str_cpy (to, src);
+    *to++ = ',';
+    to = str_cpy (to, dest);
+    }
+  }
+
+if (commented && comment)
+  {
+  ULONG offset;
+
+  i = COMMENT_COL - (to - tmp_str);
+  do
+    {
+    *to++ = reg_space_char;
+    i--;
+    }
+  while (i > 0);
+  *to++ = ';';
+
+  if ((comment & 0x8) == 8)   /* btst #3 */
+    {
+    ULONG flags_l;
+
+    *to++ = ' ';
+    flags_l = *(flags + (current_ref - first_ref));
+    if (flags_l & FLAG_BYTE)
+      *to++ = 'b';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_WORD)
+      *to++ = 'w';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_LONG)
+      *to++ = 'l';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_SIGNED)
+      *to++ = 's';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_RELOC)
+      *to++ = 'R';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_STRING)
+      *to++ = 'S';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_TABLE)
+      *to++ = 'T';
+    else
+      *to++ = '-';
+    if (flags_l & FLAG_CODE)
+      *to++ = 'C';
+    else
+      *to++ = '-';
+    }
+  if (!(comment & 0x06))  /* comment=0 or comment=1 */
+    {
+    /* relocation offset */
+    offset = current_ref;
+    }
+  else if ((comment & 0x2) == 2)  /* btst #1 */
+    {
+    /* hunk offset */
+    offset = current_ref - first_ref;
+    }
+  else
+    {
+    /* file offset */
+    offset = current_ref - first_ref + *(hunk_offset + current_hunk);
+    }
+  *to++ = ' ';
+  to = format_ulx_no_dollar (to, offset);
+  if (EVEN (comment))
+    {
+    if (instr_words)
+      {
+      *to++ = ' ';
+      *to++ = ':';
+      for (i = 0; i < instr_words; i++)
+        {
+        *to++ = ' ';
+        to = format_ulx_digits (to, *(code + i), 4L);
+        }
+      }
+    }
+  }
+#if 0
+*to++ = 0x0a;  /* lf=0x0a */
+if (instr_end)  /* extra LF after routines looks nicer */
+  *to++ = 0x0a;  /* lf=0x0a */
+#endif
+*to = 0;
+return (to);
+}
+
+/**************************************************************************/
+
+char *format_ulx (char *to, ULONG val)
+
+/* Converts a ULONG (or UWORD) to a hex string. Returns ptr to EOS. */
+{
+
+if (val <= 9)
+  {
+  *to++ = (char)(val + '0');
+  *to = 0;
+  return (to);
+  }
+else
+  {
+  char stack [8],
+       *sp;
+
+  sp = stack;
+  do
+    {
+    *sp++ = val & 0xf;       /* MOD 16 */
+    val = val >> 4;          /* DIV 16 */
+    }
+  while (val != 0);
+  *to++ = '$';
+  do
+    *to++ = hex_chars [*(--sp)];
+  while (sp != stack);
+  *to = 0;
+  return (to);
+  }
+}
+
+/**************************************************************************/
+
+char *format_lx (char *to, ULONG val)
+
+/* Converts a long to a hex string. Returns ptr to EOS. */
+{
+
+if ((LONG)val < 0)
+  {
+  val = 0-val;
+  *to++ = '-';
+  }
+
+if (val <= 9)
+  {
+  *to++ = (char)(val + '0');
+  *to = 0;
+  return (to);
+  }
+else
+  {
+  char stack [8],
+       *sp;
+
+  sp = stack;
+  do
+    {
+    *sp++ = val & 0xf;       /* MOD 16 */
+    val = val >> 4;          /* DIV 16 */
+    }
+  while (val != 0);
+  *to++ = '$';
+  do
+    *to++ = hex_chars [*(--sp)];
+  while (sp != stack);
+  *to = 0;
+  return (to);
+  }
+}
+
+/**************************************************************************/
+
+char *format_ulx_no_dollar (char *to, ULONG val)
+
+/* Converts a ULONG (or UWORD) to a hex string. Returns ptr to EOS.
+   The same as format_ulx but without the dollar sign. */
+{
+char stack [8],
+     *sp;
+
+sp = stack;
+do
+  {
+  *sp++ = val & 0xf;       /* MOD 16 */
+  val = val >> 4;          /* DIV 16 */
+  }
+while (val != 0);
+do
+  *to++ = hex_chars [*(--sp)];
+while (sp != stack);
+
+*to = 0;
+return (to);
+}
+
+/**************************************************************************/
+
+/* Currently unused
+char *format_lx_no_dollar (char *to, ULONG val)
+
+// Converts a long to a hex string. Returns ptr to EOS.
+// The same as format_lx but without the dollar sign
+{
+char stack [8],
+     *sp;
+
+if ((LONG)val < 0)
+  {
+  val = -val;
+  *to++ = '-';
+  }
+
+sp = stack;
+do
+  {
+  *sp++ = val & 0xf;       // MOD 16
+  val = val >> 4;          // DIV 16
+  }
+while (val != 0);
+do
+  *to++ = hex_chars [*(--sp)];
+while (sp != stack);
+
+*to = 0;
+return (to);
+}
+*/
+
+/**************************************************************************/
+
+char *format_ulx_digits (char *to, ULONG val, uint digits)
+
+/* Convert val to a hex string of (up to 8) digits. Returns ptr to EOS.
+   No dollar sign. Leading zeros included.
+     digits = 4 for a UWORD
+     digits = 8 for a ULONG
+*/
+{
+char stack [32],
+     *sp;
+
+sp = stack;
+do
+  {
+  *sp++ = val & 0xf;       /* MOD 16 */
+  val = val >> 4;          /* DIV 16 */
+  digits--;
+  }
+while (digits != 0);
+do
+  *to++ = hex_chars [*(--sp)];
+while (sp != stack);
+
+*to = 0;
+return (to);
+}
+
+/**************************************************************************/
+
+void format_reg_list (char *to, ushort list, BOOL incr_list, ushort reglist_offset)
+
+{
+register int i;
+register long mylist;                 /* list in order a7-a0/d7-d0 */
+short last_set;
+BOOL regs_used;
+
+
+if (!incr_list)
+  {
+  mylist = 0;
+  for (i = 0; i < 16; i++)
+    {
+    if (list & (1 << i))
+      mylist |= 1 << (15 - i);
+    }
+  }
+else
+  mylist = list;
+
+last_set = -1;
+regs_used = FALSE;
+for (i = 0; i < 17; i++)
+  {
+  if ((mylist & (1 << i)) && last_set == -1)
+    {
+    if (regs_used)
+      *to++ = '/';
+    to = str_cpy (to, reg_names [i + reglist_offset]);
+    last_set = i;
+    regs_used = TRUE;
+    }
+  else if (!(mylist & (1 << i)))
+    {
+    if (last_set == i - 1)
+      last_set = -1;
+    else if (last_set != -1)
+      {
+      *to++ = '-';
+      to = str_cpy (to, reg_names [i - 1 + reglist_offset]);
+      last_set = -1;
+      }
+    }
+  if (i == 7 && (mylist & 0x180) == 0x180)
+    {
+    if (last_set != 7) 
+      /* d7 and a0 both used and still in a list */
+      {
+      *to++ = '-';
+      to = str_cpy (to, reg_names [7 + reglist_offset]);
+      }
+    last_set = -1;
+    }      
+  }
+}
+
+/**************************************************************************/
+
+char *immed (char *to, ULONG val)
+
+{
+/* e.g. #$17 */
+
+*to++ = '#';
+return (format_ulx (to, val));
+}
+
+/**************************************************************************/
+
+void indirect (char *to, ushort reg_num)
+
+{
+/* e.g. (a0) */
+
+*to++ = '(';
+to = str_cpy (to, reg_names [reg_num]);
+*to++ = ')';
+*to = 0;
+}
+
+/**************************************************************************/
+
+void pre_dec (char *to, ushort reg_num)
+
+{
+/* e.g. -(a0) */
+
+*to++ = '-';
+*to++ = '(';
+to = str_cpy (to, reg_names [reg_num]);
+*to++ = ')';
+*to = 0;
+}
+
+/**************************************************************************/
+
+void post_inc (char *to, ushort reg_num)
+
+{
+/* e.g. (a0)+ */
+
+*to++ = '(';
+to = str_cpy (to, reg_names [reg_num]);
+*to++ = ')';
+*to++ = '+';
+*to = 0;
+}
+
+/**************************************************************************/
+
+void disp_an (char *to, ushort reg_num, WORD disp)
+
+{
+/* e.g. 4(a0) or (4,a0) */
+
+if (old_style)
+  {
+  to = format_x (to, disp);
+  *to++ = '(';
+  }
+else
+  {
+  *to++ = '(';
+  to = format_x (to, disp);
+  *to++ = ',';
+  }
+to = str_cpy (to, reg_names [reg_num]);
+*to++ = ')';
+*to = 0;
+}
+
+/**************************************************************************/
+
+void disp_an_indexed (char *to, ushort an, BYTE disp, ushort index_reg, 
+                             ushort scale, ushort size)
+
+{
+/* e.g. 4(a0,d0.w*4) or (4,a0,d0.w*4) */
+/* address register indirect with index (8 bit displacement) */
+/* the displacement, address register, and index register are mandantory */
+
+if (!old_style)
+  *to++ = '(';
+
+if (!(disp == 0 && optimize))
+  to = format_x (to, (WORD)disp);
+
+if (old_style)
+  *to++ = '(';
+else if (!(disp == 0 && optimize))
+  *to++ = ',';
+
+to = str_cpy (to, reg_names [an]);
+*to++ = ',';
+to = str_cpy (to, reg_names [index_reg]);
+*to++ = '.';
+if (size == 4)
+  *to++ = 'l';
+else
+  *to++ = 'w';
+if (scale != 1)
+  {
+  *to++ = '*';
+  *to++ = scale + '0';
+  }
+*to++ = ')';
+*to = 0;
+}
+
+/**************************************************************************/
+
+void disp_pc_indexed (char *to, ULONG ref, BYTE disp, ushort index_reg, 
+                             ushort scale, ushort size)
+
+{
+/* e.g. 4(pc,d0.w*4) or (4,pc,d0.w*4) */
+/* pc indirect with index (8 bit displacement) */
+/* the displacement, pc, and index register are mandantory */
+
+if (!old_style)
+  *to++ = '(';
+
+if (!((*code & 0xffc0) == 0x4ec0))  /* not jmp */
+  to = gen_label_ref (to, ref);
+else if (!(disp == 0 && optimize))
+  to = format_x (to, (WORD)disp);
+
+if (old_style)
+  *to++ = '(';
+else if (!(disp == 0 && optimize))
+  *to++ = ',';
+
+to = str_cpy (to, reg_names [PC]);
+*to++ = ',';
+to = str_cpy (to, reg_names [index_reg]);
+*to++ = '.';
+if (size == 4)
+  *to++ = 'l';
+else
+  *to++ = 'w';
+if (scale != 1)
+  {
+  *to++ = '*';
+  *to++ = scale + '0';
+  }
+*to++ = ')';
+*to = 0;
+}
+
+/**************************************************************************/
+
+uint full_extension (char *to, UWORD *instr_ext, ushort mode, ushort reg)
+
+{
+/* address register indirect with index (base displacement) */
+/* the displacement, address register and index register are all optional */
+
+/*  15  14 13 12   11   10 9  8   7   6    5 4    3  2 1 0 */
+/* D/A  Register  W/L  Scale  1  BS  IS  BD size  0  I/IS  */
+
+/* D/A is Index register type %0=Dn, %1=An */
+/* W/L is Word/Longword index size %0=sign extended word, %1=longword */ 
+/* Scale is Scale factor %00=1, %01=2, %10=4, %11=8 */
+/* BS is Base Register Suppress %0=add base register, %1=suppress */
+/* IS is Index Suppress %0=evaluate & add index operand, %1=suppress */
+/* BD size is Base Displacement size %00=reserved, %01=null, %10=word, %11=long */
+/* I/IS is Index/Indirect Select
+/*
+select = (no_index_reg >> 3) | (*(instr_ext) & 0x0007);
+switch (select)
+  {
+  case 0x0: // %0000 No memory indirect action
+  case 0x1: // %0001 Indirect Preindexed with null od
+  case 0x2: // %0010 Indirect Preindexed with word od
+  case 0x3: // %0011 Indirect Preindexed with long od
+  case 0x4: // %0100 Reserved
+  case 0x5: // %0101 Indirect Postindexed with null od
+  case 0x6: // %0110 Indirect Postindexed with word od
+  case 0x7: // %0111 Indirect Postindexed with long od
+
+  // index register suppressed
+  case 0x8: // %1000 No memory indirect action
+  case 0x9: // %1001 Memory indirect with null od
+  case 0xa: // %1010 Memory indirect with word od
+  case 0xb: // %1011 Memory indirect with long od
+  case 0xc: // %1100 Reserved
+  case 0xd: // %1101 Reserved
+  case 0xe: // %1110 Reserved
+  case 0xf: // %1111 Reserved
+  }
+*/
+
+int bd_size,
+    od_size;
+UWORD full_ext_w,
+      scale,
+      post_indexed,
+      no_index_reg,
+      no_base_reg;
+WORD *next_instr_ext;
+
+full_ext_w = *instr_ext;
+next_instr_ext = (WORD*)instr_ext + 1;
+
+no_index_reg = (full_ext_w & 0x0040);  /*  %1000000, bit #6 */
+
+/* check for validity of instr word */
+if ((full_ext_w & 0x0008) || !(full_ext_w & 0x0030) ||
+    (full_ext_w & 0x0007) == 4 || ((full_ext_w & 0x0007) > 4 && no_index_reg))
+  {
+  instr_bad = TRUE;
+  return (0);
+  }
+
+no_base_reg = (full_ext_w & 0x0080);   /* %10000000, bit #7 */
+post_indexed = (full_ext_w & 0x0004);  /*      %100, bit #2 */
+bd_size = ((full_ext_w >> 4) & 0x0003) - 1; /* -1=invalid 0=NULL, 1=word, 2=longword */
+od_size = (full_ext_w & 0x0003) - 1;  /* -1=invalid, 0=NULL, 1=word, 2=longword */
+
+if (!(no_index_reg && no_base_reg && od_size < 0))
+  {
+  *to++ = '(';
+  if (od_size >= 0)
+    *to++ = '[';
+  }
+
+if (bd_size == 1)  /* .w? */
+  {
+  if (mode == 7 && !no_base_reg)  /* pc relative && pc not suppressed? */
+    {
+    ULONG b_offset = current_ref + ((instr_ext - code)  << 1);
+    if (pass2)
+      enter_ref (b_offset + *(next_instr_ext++), NULL, ACC_UNKNOWN);
+    else
+      to = gen_label_ref (to, b_offset + *(next_instr_ext++));
+    }
+  else
+    {
+    to = format_x (to, *(next_instr_ext++));
+    if (!optimize)
+      {
+      *to++ = '.';
+      *to++ = 'w';
+      }
+    }
+  }
+else if (bd_size == 2)  /* .l? */
+  {
+  ULONG b_offset = current_ref + (((UWORD*)instr_ext - code) << 1);
+  if (FLAGS_RELOC (b_offset + 2))  /* relocated absolute (to a label) */
+    {
+    if (pass2)
+      enter_ref (*((LONG*)(next_instr_ext)), NULL, ACC_UNKNOWN);
+    else
+      to = gen_label_ref (to, *((LONG*)(next_instr_ext)));
+    }
+  else if (mode == 7 && !no_base_reg)  /* pc relative && pc not suppressed? */
+    {
+    if (pass2)
+      enter_ref (b_offset + *((LONG*)(next_instr_ext)), NULL, ACC_UNKNOWN);
+    else
+      to = gen_label_ref (to, b_offset + *((LONG*)(next_instr_ext)));
+    }
+  else
+    {
+    to = format_lx (to, *((LONG*)(next_instr_ext)));
+    if (!optimize)
+      {
+      *to++ = '.';
+      *to++ = 'l';
+      }
+    }
+  next_instr_ext += 2;
+  }
+else if (bd_size == 0 && no_base_reg && no_index_reg)  /* absolute with NULL bd */
+  *to++ = '0';
+
+if (!no_base_reg) /* base register? */
+  {
+  if (bd_size > 0)
+    *to++ = ',';
+  if (mode == 7)  /* pc relative? */
+    reg = 8;
+  to = str_cpy (to, reg_names [reg + 8]);  
+  }
+
+if (!no_index_reg)
+  {
+  if (post_indexed)
+    *to++ = ']';
+  if (bd_size != 0 || !no_base_reg)
+    *to++ = ',';
+  to = str_cpy (to, reg_names [full_ext_w >> 12]);
+  *to++ = '.';
+  if (full_ext_w & 0x0800)
+    *to++ = 'l';
+  else
+    *to++ = 'w';
+  scale = 1 << ((full_ext_w & 0x0600) >> 9);
+  if (scale != 1)
+    {
+    *to++ = '*';
+    *to++ = scale + '0';
+    }
+  }
+
+if (!post_indexed && od_size >= 0)
+  *to++ = ']';
+
+if (od_size == 1)  /* .w? */
+  {
+  *to++ = ',';
+  to = format_x (to, *(next_instr_ext++));
+  if (!optimize)
+    {
+    *to++ = '.';
+    *to++ = 'w';
+    }
+  }
+else if (od_size == 2)  /* .l? */
+  {
+  *to++ = ',';
+  to = format_lx (to, *((LONG*)(next_instr_ext)));
+  if (!optimize)
+    {
+    *to++ = '.';
+    *to++ = 'l';
+    }
+  next_instr_ext += 2;
+  }
+
+if (!(no_index_reg && no_base_reg && od_size < 0))
+  *to++ = ')';
+*to = 0;
+
+return ((uint)((UWORD*)next_instr_ext - instr_ext));
+}
+
+/**************************************************************************/
+
+char *gen_xref (char *to, ULONG address)
+
+{
+to = str_cpy (to, "XREF ");
+to = gen_label_ref (to, address);
+*to++ = 0x0a;  /* lf=$0a */
+*to = 0;
+return (to);
+}
+
+/**************************************************************************/
+
+char *gen_label_ref (char *to, ULONG ref)
+
+/* generates a label reference and returns new dest (end of str) */
+{
+char *label;
+UWORD access;
+
+if (find_ref (ref, &label, &access) && label != 0)
+  {
+  to = str_cpy (to, label);
+  return (to);
+  }
+to = str_cpy (to, "lab_");
+to = format_ux_no_dollar (to, ref);
+return (to);
+}
+
+/**************************************************************************/
+
+char *gen_label (char *to, ULONG ref)
+
+/* generates a label if needed and returns new dest (end of str) */
+{
+char *label;
+UWORD access;
+
+if (find_ref (ref, &label, &access))
+  {
+  if (label == NULL)
+    {
+    to = str_cpy (to, "lab_");
+    to = format_ux_no_dollar (to, ref);
+    }
+  else
+    to = str_cpy (to, label);
+  *to++ = ':';
+  *to++ = 0x0a;  /* lf=$0a */
+  }
+*to = 0;
+return (to);
+}
+
+/**************************************************************************/
+
+void assign_label_names (void)
+
+/**********************************************************************/
+/*   Assigns each label an ascending number instead of its address    */
+/**********************************************************************/
+{
+uint label_count = 1;
+ULONG ref = 0;
+UWORD access;
+char *old_name;
+char label_name [16];
+
+while ((ref = next_ref (ref, total_size, &access)) != total_size)
+  {
+  find_ref (ref, &old_name, &access);
+  if (old_name == NULL)
+    {
+    format_ux_no_dollar (str_cpy (label_name, "lab_"), label_count++);
+    enter_ref (ref, label_name, access);
+    }
+  }
+}
+
+
+void ExitADis(void)
+{
+}
+void enter_ref(ULONG ref, char *name, UWORD access_type)
+{
+}
+BOOL find_ref(ULONG ref, char **name, UWORD *access_type)
+{
+       return FALSE;
+}
+void enter_jmptab(ULONG start, ULONG offset)
+{
+}
+ULONG next_ref(ULONG from, ULONG to, UWORD *access_type)
+{
+       return 0;
+}
+
+uint disasm_instr(UWORD *instr, char *out)
+
+/**********************************************************************/
+/*    Returns number of 16 bit words disassembled                     */
+/**********************************************************************/
+
+{
+       struct opcode_entry *op;
+       uint size = 0;
+
+       set_pass3;
+
+       opcode[0] = src[0] = dest[0] = 0;
+       instr_bad = FALSE; /* global variable TRUE when unknown or corrupt instr is found */
+       instr_end = FALSE; /* global variable TRUE at rts, bra, jmp, etc. */
+       code = instr;      /* global variable */
+
+       for (op = &(opcode_table[(instr[0]) >> 6]);
+               size == 0;
+               op = &(opcode_table[op->chain]))
+       {
+               /* Test for validity of ea_mode */
+               if (op->modes & (1 << MODE_NUM(*instr)))
+               {
+                       if ((MODE_NUM(*instr) == 7) && !(op->submodes & (1 << REG_NUM(*instr))))
+                               continue;
+
+                       if (pass3 && op->mnemonic != 0)
+                       {
+                               str_cpy(opcode, op->mnemonic);
+                       }
+                       size = (*op->handler) (op);
+               }
+       }
+       format_line(out, FALSE, 0);
+       return (size);
+}
index fbe8bf15c1ecbae3bf91a42e4a0daf2837a886e6..70a59add5a3806469ee16a67605e602f6ff6a530 100644 (file)
@@ -315,6 +315,7 @@ _exceptionfpu:
        movem.l d0-d7/a0-a6,(a0)
        move.l (sp)+,8*4(a0)
 
+       move.l sp,S_EXCFRAME(a0)
        move.w (sp)+,S_SR+2(a0)
        move.l (sp)+,S_PC(a0)
        move.w (sp),d0
index 8274d408b866cf5ec2fee67b9f6e60bb3ea8a01d..8c9b758fdc02bf70f7d7efda553dc8f1790dce08 100644 (file)
@@ -9,7 +9,7 @@ cpu=68020
 cpu_address_space=32
 
 ; FPU model (empty string or 0, 68881, 68882, 68040, 68060)
-; Enable only when testing FPU. Enabled FPU mode will slow down execution.
+; Enable only when testing FPU. Enabled FPU mode will slow down native test execution even when not testing FPU instructions.
 fpu=
 
 ; Write generated instructions to standard output. Always disabled in "all" mode.
@@ -18,18 +18,18 @@ verbose=1
 ; Where to generate test files
 path=data/
 
-; Low address space limits (0x0000 to 0x8000 is complete space)
+; Low address space limits. Real hardware must have RAM in this space. Comment out to disable.
 test_low_memory_start=0x0000
 test_low_memory_end=0x8000
 
-; High address space limits (0x00ff8000 to 0x01000000 is complete space)
+; High address space limits (0x00ff8000 to 0x01000000 is complete space). Comment out to disable.
 ;test_high_memory_start=0x00ff8000
 ;test_high_memory_end=0x01000000
 
-; ROM high address space
+; ROM high address space. High memory is only used for read tests.
 high_rom=D:\amiga\roms\Kickstart v3.1 rev 40.63 (1993)(Commodore)(A500-A600-A2000)[!].rom
 
-; main test memory start and size (real hardware must have RAM in same address space)
+; main test memory start and size (real hardware must have RAM in this address space)
 test_memory_start=0x780000
 test_memory_size=0x080000
 
@@ -37,11 +37,11 @@ test_memory_size=0x080000
 ; 0 = do not generate address errors
 ; 1 = include address errors
 ; 2 = only generate test instructions that generate address errors
-feature_exception3_data=1
+feature_exception3_data=0
 
 ; test branches to odd addresses
-; same as above
-feature_exception3_instruction=1
+; same options as above
+feature_exception3_instruction=0
 
 ; SR extra mask.
 ; 0x8000 = T1
@@ -55,7 +55,7 @@ feature_sr_mask=0x0000
 
 ; generate loop test: label: <test instruction> dbf dn,label
 ; value: 0 = disabled, >0 = number of loops
-feature_loop_mode=10
+feature_loop_mode=0
 feature_loop_mode_register=7
 
 ; 68020+ addressing modes (this makes test files much larger if other addressing modes are also enabled)
@@ -69,7 +69,7 @@ feature_full_extension_format=0
 feature_addressing_modes_src=
 feature_addressing_modes_dst=
 
-; mnemonics separated by comma or all.
-; all = generate all. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l
-mode=not.b
-
+; mnemonics separated by comma or all/fall.
+; all = generate all CPU tests. tst = generate tst.b, tst.w and tst.l. tst.l = generate only tst.l
+; fall = generate all FPU tests.
+mode=chk2.b
index 359f7789defdf59dbca568e7caa70af9f5cd5915..f338f7f51d97ffd8002badbfc7d3af277730e51b 100644 (file)
@@ -54,6 +54,8 @@ static uae_u8 *opcode_memory;
 static uae_u32 opcode_memory_addr;
 static uae_u8 *low_memory;
 static uae_u8 *high_memory;
+static uae_u32 low_memory_size;
+static uae_u32 high_memory_size;
 static uae_u8 *test_memory;
 static uae_u32 test_memory_addr;
 static uae_u32 test_memory_size;
@@ -75,15 +77,15 @@ static uae_u32 cpustatearraynew[] = {
        0x00000000, // MSP
 };
 
-static uae_u8 low_memory_temp[32768];
-static uae_u8 high_memory_temp[32768];
-static uae_u8 low_memory_back[32768];
-static uae_u8 high_memory_back[32768];
+static uae_u8 *low_memory_temp;
+static uae_u8 *high_memory_temp;
+static uae_u8 *low_memory_back;
+static uae_u8 *high_memory_back;
 
 static uae_u32 vbr[256];
        
 static char inst_name[16+1];
-#ifdef _MSC_VER
+#ifndef M68K
 static char outbuffer[40000];
 #else
 static char outbuffer[4000];
@@ -97,7 +99,7 @@ static int quit;
 static uae_u8 ccr_mask;
 static uae_u32 addressing_mask = 0x00ffffff;
 
-#ifdef _MSC_VER
+#ifndef M68K
 
 #define xmemcpy memcpy
 
@@ -203,15 +205,15 @@ static void start_test(void)
        if (test_active)
                return;
 
-#ifndef _MSC_VER
+#ifdef M68K
        if (lmem_rom > 0) {
-               if (memcmp(low_memory, low_memory_temp, 32768)) {
+               if (memcmp(low_memory, low_memory_temp, low_memory_size)) {
                        printf("Low memory ROM mismatch!\n");
                        exit(0);
                }
        }
        if (hmem_rom > 0) {
-               if (memcmp(high_memory, high_memory_temp, 32768)) {
+               if (memcmp(high_memory, high_memory_temp, high_memory_size)) {
                        printf("High memory ROM mismatch!\n");
                        exit(0);
                }
@@ -222,13 +224,13 @@ static void start_test(void)
 
        enable_data = tosuper(0);
 
-       memcpy(low_memory_back, low_memory, 32768);
+       memcpy(low_memory_back, low_memory, low_memory_size);
        if (!hmem_rom)
-               memcpy(high_memory_back, high_memory, 32768);
+               memcpy(high_memory_back, high_memory, high_memory_size);
 
-       memcpy(low_memory, low_memory_temp, 32768);
+       memcpy(low_memory, low_memory_temp, low_memory_size);
        if (!hmem_rom)
-               memcpy(high_memory, high_memory_temp, 32768);
+               memcpy(high_memory, high_memory_temp, high_memory_size);
 
        if (cpu_lvl == 0) {
                uae_u32 *p = (uae_u32 *)vbr_zero;
@@ -253,9 +255,9 @@ static void end_test(void)
                return;
        test_active = 0;
 
-       memcpy(low_memory, low_memory_back, 32768);
+       memcpy(low_memory, low_memory_back, low_memory_size);
        if (!hmem_rom)
-               memcpy(high_memory, high_memory_back, 32768);
+               memcpy(high_memory, high_memory_back, high_memory_size);
 
        if (cpu_lvl > 0) {
                setvbr(oldvbr);
@@ -303,11 +305,22 @@ static void pl(uae_u8 *p, uae_u32 v)
        p[2] = v >>  8;
        p[3] = v >>  0;
 }
+static void pw(uae_u8 *p, uae_u32 v)
+{
+       p[0] = v >> 8;
+       p[1] = v >> 0;
+}
+
 static uae_u32 gl(uae_u8 *p)
 {
        return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
 }
 
+static uae_u16 gw(uae_u8 *p)
+{
+       return (p[0] << 8) | (p[1] << 0);
+}
+
 static uae_u8 *restore_fpvalue(uae_u8 *p, struct fpureg *fp)
 {
        uae_u8 v = *p++;
@@ -317,12 +330,13 @@ static uae_u8 *restore_fpvalue(uae_u8 *p, struct fpureg *fp)
                endinfo();
                exit(0);
        }
-       fp->exp = (p[0] << 8) | p[1];
+       fp->exp = gw(p);
        p += 2;
        fp->m[0] = gl(p);
        p += 4;
        fp->m[1] = gl(p);
        p += 4;
+       fp->dummy = 0;
        return p;
 }
 
@@ -398,7 +412,7 @@ static uae_u8 *restore_rel(uae_u8 *p, uae_u32 *vp, int nocheck)
                        val |= *p++;
                        v = val;
                        if (!nocheck) {
-                               if ((val & addressing_mask) < 0x8000) {
+                               if ((val & addressing_mask) < low_memory_size) {
                                        ; // low memory
                                } else if ((val & ~addressing_mask) == ~addressing_mask && val >= 0xfff80000) {
                                        ; // high memory
@@ -462,20 +476,30 @@ static uae_u8 *get_memory_addr(uae_u8 *p, uae_u8 **addrp)
                        val |= (*p++) << 16;
                        val |= (*p++) << 8;
                        val |= *p++;
-                       if (val < test_memory_addr || val >= test_memory_addr + test_memory_size) {
+                       if (val < low_memory_size) {
+#ifndef M68K
+                               uae_u8 *addr = low_memory + val;
+#else
+                               uae_u8 *addr = (uae_u8 *)val;
+#endif
+                               validate_mode(p[0], CT_MEMWRITE);
+                               *addrp = addr;
+                               return p;
+                       } else if (val >= test_memory_addr && val < test_memory_addr + test_memory_size) {
+#ifndef M68K
+                               uae_u8 *addr = test_memory + (val - test_memory_addr);
+#else
+                               uae_u8 *addr = (uae_u8 *)val;
+#endif
+                               validate_mode(p[0], CT_MEMWRITE);
+                               *addrp = addr;
+                               return p;
+                       } else {
                                end_test();
                                printf("get_memory_addr CT_ABSOLUTE_LONG outside of test memory! %08x\n", val);
                                endinfo();
                                exit(0);
                        }
-#ifdef _MSC_VER
-                       uae_u8 *addr = test_memory + (val - test_memory_addr);
-#else
-                       uae_u8 *addr = (uae_u8 *)val;
-#endif
-                       validate_mode(p[0], CT_MEMWRITE);
-                       *addrp = addr;
-                       return p;
                }
                case CT_RELATIVE_START_WORD:
                {
@@ -660,7 +684,7 @@ static uae_u8 *restore_data(uae_u8 *p)
 int    Disass68k(long addr, char *labelBuffer, char *opcodeBuffer, char *operandBuffer, char *commentBuffer);
 void Disasm_SetCPUType(int CPU, int FPU);
 
-static uae_u16 test_sr;
+static uae_u16 test_sr, test_ccrignoremask;
 static uae_u32 test_fpsr, test_fpcr;
 
 static void addinfo(void)
@@ -683,11 +707,27 @@ static void addinfo(void)
        strcat(outbp, " ");
        outbp += strlen(outbp);
 
+       uae_u16 disasm_instr(uae_u16 *, char *);
+#ifndef M68K
+       uae_u16 swapped[16];
+       for (int i = 0; i < 16; i++) {
+               swapped[i] = (opcode_memory[i * 2 + 0] << 8) | (opcode_memory[i * 2 + 1] << 0);
+       }
+       disasm_instr((uae_u16*)swapped, outbp);
+#else
+       disasm_instr((uae_u16 *)opcode_memory, outbp);
+#endif
+       outbp += strlen(outbp);
+       *outbp++ = '\n';
+       *outbp = 0;
+
+#if 0
        Disasm_SetCPUType(0, 0);
        char buf1[80], buf2[80], buf3[80], buf4[80];
        Disass68k((long)opcode_memory, buf1, buf2, buf3, buf4);
        sprintf(outbp, "%s %s\n", buf2, buf3);
        outbp += strlen(outbp);
+#endif
 }
 
 struct srbit
@@ -755,7 +795,7 @@ static void out_regs(struct registers *r, int before)
                void *f2 = &test_regs.fpuregs[i];
                sprintf(outbp, "FP%d:%c%04x-%08lx%08lx %f",
                        i,
-                       memcmp(f1, f2, 12) ? '*' : ' ',
+                       memcmp(f1, f2, sizeof(struct fpureg)) ? '*' : ' ',
                        f->exp, f->m[0], f->m[1],
                        *((long double*)f));
                outbp += strlen(outbp);
@@ -791,6 +831,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum)
        uae_u8 *sp = (uae_u8*)regs->excframe;
        uae_u32 v;
        uae_u8 excdatalen = *p++;
+       int size;
 
        if (!excdatalen)
                return p;
@@ -842,7 +883,7 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum)
                                pl(exc + 8, v);
                                exclen = 12;
                                break;
-                       case 8:
+                       case 4:
                                v = opcode_memory_addr;
                                p = restore_rel_ordered(p, &v);
                                pl(exc + 8, v);
@@ -851,6 +892,12 @@ static uae_u8 *validate_exception(struct registers *regs, uae_u8 *p, int excnum)
                                pl(exc + 12, v);
                                exclen = 16;
                                break;
+                       case 0x0a:
+                               v = 0;
+                               p = restore_value(p, &v, &size);
+                               pw(exc + 0x0a, v);
+                               exclen = 0x0c;
+                               break;
                        default:
                                end_test();
                                printf("Unknown frame %04x\n", frame);
@@ -896,7 +943,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        regs_changed[i] = 1;
                }
        }
-       if (last_registers.sr != test_regs.sr) {
+       if ((last_registers.sr & test_ccrignoremask) != (test_regs.sr & test_ccrignoremask)) {
                sr_changed = 1;
        }
        if (last_registers.pc != test_regs.pc) {
@@ -904,7 +951,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
        }
        if (fpu_model) {
                for (int i = 0; i < 8; i++) {
-                       if (memcmp(&last_registers.fpuregs[i], &test_regs.fpuregs[i], 12)) {
+                       if (memcmp(&last_registers.fpuregs[i], &test_regs.fpuregs[i], sizeof(struct fpureg))) {
                                regs_fpuchanged[i] = 1;
                        }
                }
@@ -969,7 +1016,8 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        break;
                }
                int mode = v & CT_DATA_MASK;
-               if (mode < CT_AREG + 8) {
+
+               if (mode < CT_AREG + 8 && (v & CT_SIZE_MASK) != CT_SIZE_FPU) {
                        uae_u32 val = last_registers.regs[mode];
                        int size;
                        p = restore_value(p, &val, &size);
@@ -983,14 +1031,31 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        }
                        regs_changed[mode] = 0;
                        last_registers.regs[mode] = val;
+               } else if (mode < CT_AREG && (v & CT_SIZE_MASK) == CT_SIZE_FPU) {
+                       struct fpureg val;
+                       p = restore_fpvalue(p, &val);
+                       if (memcmp(&val, &test_regs.fpuregs[mode], sizeof(struct fpureg)) && !ignore_errors) {
+                               addinfo();
+                               if (dooutput) {
+                                       sprintf(outbp, "FP%d: expected %04x-%08lx%08lx but got %04x-%08lx%08lx\n", mode,
+                                               val.exp, val.m[0], val.m[1],
+                                               test_regs.fpuregs[mode].exp, test_regs.fpuregs[mode].m[0], test_regs.fpuregs[mode].m[1]);
+                                       outbp += strlen(outbp);
+                               }
+                               errors++;
+                       }
+                       regs_fpuchanged[mode] = 0;
+                       memcpy(&last_registers.fpuregs[mode], &val, sizeof(struct fpureg));
                } else if (mode == CT_SR) {
                        uae_u32 val = last_registers.sr;
                        int size;
+                       // High 16 bit: ignore mask, low 16 bit: SR/CCR
                        p = restore_value(p, &val, &size);
-                       if ((val & sr_undefined_mask) != (test_regs.sr & sr_undefined_mask) && !ignore_errors && !ignore_sr) {
+                       test_ccrignoremask = ~(val >> 16);
+                       if ((val & (sr_undefined_mask | test_ccrignoremask)) != (test_regs.sr & (sr_undefined_mask | test_ccrignoremask)) && !ignore_errors && !ignore_sr) {
                                addinfo();
                                if (dooutput) {
-                                       sprintf(outbp, "SR: expected %04x -> %04x but got %04x\n", test_sr, val, test_regs.sr);
+                                       sprintf(outbp, "SR: expected %04x -> %04x but got %04x\n", test_sr, val & 0xffff, test_regs.sr & 0xffff);
                                        outbp += strlen(outbp);
                                }
                                errors++;
@@ -1114,7 +1179,7 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        if (sr_changed) {
                                addinfo();
                                if (dooutput) {
-                                       sprintf(outbp, "SR: modified %04x -> %04x but expected no modifications\n", last_registers.sr, test_regs.sr);
+                                       sprintf(outbp, "SR: modified %04x -> %04x but expected no modifications\n", last_registers.sr & 0xffff, test_regs.sr & 0xffff);
                                        outbp += strlen(outbp);
                                }
                                errors++;
@@ -1124,8 +1189,9 @@ static uae_u8 *validate_test(uae_u8 *p, int ignore_errors, int ignore_sr)
                        if (regs_fpuchanged[i]) {
                                addinfo();
                                if (dooutput) {
-                                       sprintf(outbp, "FP%d: modified %f -> %f but expected no modifications\n", i,
-                                               *((long double *)(&last_registers.fpuregs[i])), *((long double *)(&test_regs.fpuregs[i])));
+                                       sprintf(outbp, "FP%d: modified %04x-%08lx%08lx -> %04x-%08lx%08lx but expected no modifications\n", i,
+                                               last_registers.fpuregs[i].exp, last_registers.fpuregs[i].m[0], last_registers.fpuregs[i].m[1],
+                                               test_regs.fpuregs[i].exp, test_regs.fpuregs[i].m[0], test_regs.fpuregs[i].m[1]);
                                        outbp += strlen(outbp);
                                }
                                errors++;
@@ -1197,11 +1263,12 @@ static void process_test(uae_u8 *p)
 
        start_test();
 
+       test_ccrignoremask = 0xffff;
        ahcnt = 0;
 
        for (;;) {
 
-#ifdef _MSC_VER
+#ifndef M68K
                outbp = outbuffer;
 #endif
 
@@ -1492,25 +1559,23 @@ static char path[256];
 
 int main(int argc, char *argv[])
 {
-       int size;
        char opcode[16];
        int stop_on_error = 1;
 
        atexit(freestuff);
 
-#ifdef _MSC_VER
+#ifndef M68K
 
-       char *params[] = { "", "or.w", "", NULL };
+       char *params[] = { "", "unpk", "", NULL };
        argv = params;
        argc = 3;
 
        strcpy(path, "C:\\projects\\winuae\\src\\cputest\\data\\");
 
-       low_memory = calloc(1, 32768);
-       high_memory = calloc(1, 32768);
        vbr_zero = calloc(1, 1024);
 
-       cpu_lvl = 0;
+       cpu_lvl = 2;
+
 #else
 
 #define _stricmp stricmp
@@ -1524,6 +1589,7 @@ int main(int argc, char *argv[])
        high_memory = (uae_u8 *)0xffff8000;
 
        cpu_lvl = get_cpu_model();
+
 #endif
 
        if (argc < 2) {
@@ -1558,10 +1624,27 @@ int main(int argc, char *argv[])
                }
        }
 
-       size = 32768;
-       load_file(path, "lmem.dat", low_memory_temp, &size);
-       size = 32768;
-       load_file(path, "hmem.dat", high_memory_temp, &size);
+       low_memory_size = -1;
+       low_memory_temp = load_file(path, "lmem.dat", NULL, &low_memory_size);
+       high_memory_size = -1;
+       high_memory_temp = load_file(path, "hmem.dat", NULL, &high_memory_size);
+
+       if (low_memory_size < 0 || !low_memory_temp) {
+               printf("Couldn't allocate low memory\n");
+               return 0;
+       }
+       if (high_memory_size < 0 || !high_memory_temp) {
+               printf("Couldn't allocate low memory\n");
+               return 0;
+       }
+
+#ifndef M68K
+       low_memory = calloc(1, low_memory_size);
+       high_memory = calloc(1, high_memory_size);
+#endif
+
+       low_memory_back = calloc(1, low_memory_size);
+       high_memory_back = calloc(1, high_memory_size);
 
        if (!_stricmp(opcode, "all")) {
                DIR *d = opendir(path);
@@ -1604,12 +1687,17 @@ int main(int argc, char *argv[])
 
                int first = 0;
                if (argc >= 3) {
+                       first = -1;
                        for (int i = 0; i < diroff; i += MAX_FILE_LEN) {
                                if (!_stricmp(dirs + i, argv[2])) {
                                        first = i;
                                        break;
                                }
                        }
+                       if (first < 0) {
+                               printf("Couldn't find '%s'\n", argv[2]);
+                               return 0;
+                       }
                }
                for (int i = first; i < diroff; i += MAX_FILE_LEN) {
                        if (test_mnemo(path, dirs + i)) {
@@ -1623,4 +1711,6 @@ int main(int argc, char *argv[])
        } else {
                test_mnemo(path, opcode);
        }
+
+       return 0;
 }
index 75cb52a145398cf4c963f255d65681edd1298267..ed34c98030e8ddf9c7adface063f3ee34d1ec6ae 100644 (file)
@@ -5,10 +5,12 @@ NOWTIME := "\"$(shell date "+%T")\""
 CC=/opt/amiga/bin/m68k-amigaos-gcc
 AS=/opt/amiga/bin/m68k-amigaos-as
 
-CFLAGS = -mcrt=nix13 -O2 -m68000 -fomit-frame-pointer -msmall-code -msoft-float -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME) -DAMIGA
+CFLAGS = -mcrt=nix13 -O2 -m68000 -fomit-frame-pointer -msmall-code -msoft-float -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME) -DAMIGA -DM68K
 LINK_CFLAGS = -mcrt=nix13 -lm -s
 
-OBJS = main.o 68kDisass.o asm.o amiga.o
+OBJS = main.o asm.o amiga.o \
+       decode_ea.o globals.o opcode_handler_cpu.o opcode_handler_fpu.o \
+       opcode_handler_mmu.o opcodes_cpu.o opcodes_fpu.o opcodes_mmu.o util.o
 
 all: $(OBJS)
        $(CC) $(LINK_CFLAGS) -o cputest $^
@@ -16,8 +18,32 @@ all: $(OBJS)
 main.o: main.c
        $(CC) $(CFLAGS) -I. -c -o $@ main.c
 
-68kDisass.o: main.c
-       $(CC) $(CFLAGS) -I. -c -o $@ 68kDisass.c
+decode_ea.o: adis/decode_ea.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/decode_ea.c
+
+globals.o: adis/globals.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/globals.c
+
+opcode_handler_cpu.o: adis/opcode_handler_cpu.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/opcode_handler_cpu.c
+
+opcode_handler_fpu.o: adis/opcode_handler_fpu.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/opcode_handler_fpu.c
+
+opcode_handler_mmu.o: adis/opcode_handler_mmu.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/opcode_handler_mmu.c
+
+opcodes_cpu.o: adis/opcodes_cpu.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/opcodes_cpu.c
+
+opcodes_fpu.o: adis/opcodes_fpu.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/opcodes_fpu.c
+
+opcodes_mmu.o: adis/opcodes_mmu.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/opcodes_mmu.c
+
+util.o: adis/util.c
+       $(CC) $(CFLAGS) -I. -c -o $@ adis/util.c
 
 asm.o: asm.S
        $(AS) -m68020  -o $@ asm.S
index 1ef0dd647f497b565b31b57cbbd01a9b8a55b482..5b03799c2966829052f03bd0ecef883e618e50a1 100644 (file)
@@ -6,6 +6,8 @@
 #include "memory.h"
 #include "newcpu.h"
 #include "fpp.h"
+#include "mmu_common.h"
+#include "cpummu030.h"
 
 void my_trim(TCHAR *s)
 {
@@ -97,4 +99,14 @@ void mmu_tt_modified(void)
 uae_u16 REGPARAM2 mmu_set_tc(uae_u16 tc)
 {
        return 0;
-}
\ No newline at end of file
+}
+
+uae_u16 mmu030_state[3];
+int mmu030_opcode;
+int mmu030_idx;
+uae_u32 mmu030_disp_store[2];
+uae_u32 mmu030_fmovem_store[2];
+uae_u32 mm030_stageb_address;
+struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS + 1];
+
+uae_u32 mmu040_move16[4];
index 63ba604bf7e9aa06491ad65ad5faeb21e1525003..af73887cecac42a861c711418a0d9fbc573d9c40 100644 (file)
@@ -339,6 +339,7 @@ uaecptr ShowEA (void *f, uaecptr pc, uae_u16 opcode, int reg, amodes mode, words
                mode = immi;
        }
 
+       buffer[0] = 0;
        switch (mode){
        case Dreg:
                _stprintf (buffer, _T("D%d"), reg);
@@ -1678,6 +1679,7 @@ void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cn
                } else if (lookup->mnemo == i_CAS) {
                        TCHAR *p = instrname + _tcslen(instrname);
                        _stprintf(p, _T("D%d,D%d,"), extra & 7, (extra >> 6) & 7);
+                       pc += 2;
                        pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, deaddr, safemode);
                } else if (lookup->mnemo == i_CAS2) {
                        TCHAR *p = instrname + _tcslen(instrname);
@@ -1820,6 +1822,17 @@ void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cn
                        pc += 2;
                        _tcscat(instrname, _T(","));
                        pc = ShowEA(NULL, pc, opcode, 0, imm1, sz_word, instrname, &deaddr2, safemode);
+               } else if (lookup->mnemo == i_FTRAPcc) {
+                       pc = ShowEA(NULL, pc, opcode, dp->dreg, dp->dmode, dp->size, instrname, &seaddr2, safemode);
+                       int mode = opcode & 7;
+                       pc += 2;
+                       if (mode == 2) {
+                               _tcscat(instrname, _T(","));
+                               pc = ShowEA(NULL, pc, opcode, 0, imm1, sz_word, instrname, NULL, safemode);
+                       } else if (mode == 3) {
+                               _tcscat(instrname, _T(","));
+                               pc = ShowEA(NULL, pc, opcode, 0, imm1, sz_long, instrname, NULL, safemode);
+                       }
                } else if (lookup->mnemo == i_FPP) {
                        TCHAR *p;
                        int ins = extra & 0x3f;
diff --git a/fpp.cpp b/fpp.cpp
index 3372f60d0385bafa42090f403d87ea4433f4eb82..603ed1c645dfda247687c935f486d11fddb8f551 100644 (file)
--- a/fpp.cpp
+++ b/fpp.cpp
@@ -677,12 +677,12 @@ uae_u32 fpp_get_fpsr (void)
        return regs.fpsr & 0x0ffffff8;
 }
 
-static uae_u32 fpp_get_fpcr(void)
+uae_u32 fpp_get_fpcr(void)
 {
        return regs.fpcr & (currprefs.fpu_model == 68040 ? 0xffff : 0xfff0);
 }
 
-static void fpp_set_fpcr (uae_u32 val)
+void fpp_set_fpcr (uae_u32 val)
 {
        fpp_set_mode(val);
        regs.fpcr = val & 0xffff;
@@ -702,7 +702,7 @@ static void fpset (fpdata *fpd, uae_s32 val)
        fpp_from_int(fpd, val);
 }
 
-static void fpp_set_fpsr (uae_u32 val)
+void fpp_set_fpsr (uae_u32 val)
 {
        regs.fpsr = val;
 
@@ -721,6 +721,16 @@ static void fpp_set_fpsr (uae_u32 val)
 #endif
 }
 
+void fpp_set_fpiar(uae_u32 val)
+{
+       regs.fpiar = val;
+}
+
+uae_u32 fpp_get_fpiar(void)
+{
+       return regs.fpiar;
+}
+
 bool fpu_get_constant(fpdata *fpd, int cr)
 {
        uae_u32 f[3] = { 0, 0, 0 };
@@ -2822,18 +2832,18 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                                }
                                if (extra & 0x2000) {
                                        if (extra & 0x1000)
-                                               m68k_dreg (regs, opcode & 7) = fpp_get_fpcr();
+                                               m68k_dreg(regs, opcode & 7) = fpp_get_fpcr();
                                        if (extra & 0x0800)
-                                               m68k_dreg (regs, opcode & 7) = fpp_get_fpsr();
+                                               m68k_dreg(regs, opcode & 7) = fpp_get_fpsr();
                                        if ((extra & 0x0400) || !bits)
-                                               m68k_dreg (regs, opcode & 7) = regs.fpiar;
+                                               m68k_dreg(regs, opcode & 7) = fpp_get_fpiar();
                                } else {
                                        if (extra & 0x1000)
                                                fpp_set_fpcr(m68k_dreg (regs, opcode & 7));
                                        if (extra & 0x0800)
                                                fpp_set_fpsr(m68k_dreg (regs, opcode & 7));
                                        if ((extra & 0x0400) || !bits)
-                                               regs.fpiar = m68k_dreg (regs, opcode & 7);
+                                               fpp_set_fpiar(m68k_dreg (regs, opcode & 7));
                                }
                        } else if ((opcode & 0x38) == 0x08) {
                                // An
@@ -2876,7 +2886,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                                        if (extra & 0x0800)
                                                fpp_set_fpsr(ext[1]);
                                        if (extra & 0x0400)
-                                               regs.fpiar = ext[2];
+                                               fpp_set_fpiar(ext[2]);
                                } else {
                                        // immediate as destination
                                        fpu_noinst (opcode, pc);
@@ -2917,7 +2927,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                                        ad += 4;
                                }
                                if (extra & 0x0400) {
-                                       x_cp_put_long(ad, regs.fpiar);
+                                       x_cp_put_long(ad, fpp_get_fpiar());
                                        ad += 4;
                                }
                                ad -= incr;
@@ -2955,7 +2965,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                                        ad += 4;
                                }
                                if (extra & 0x0400) {
-                                       regs.fpiar = x_cp_get_long (ad);
+                                       fpp_set_fpiar(x_cp_get_long (ad));
                                        ad += 4;
                                }
                                if ((opcode & 0x38) == 0x18)
@@ -3202,12 +3212,12 @@ void fpu_reset (void)
        use_long_double = false;
 #endif
 
-       regs.fpiar = 0;
        regs.fpu_exp_state = 0;
        regs.fp_unimp_pend = 0;
        get_features();
        fpp_set_fpcr (0);
        fpp_set_fpsr (0);
+       fpp_set_fpiar (0);
        fpux_restore (NULL);
        // reset precision
        fpp_set_mode(0x00000080 | 0x00000010);
index 73da02b3946ff5bb5d2086848b5f55511194d9de..aab7748217a0f108faf64cbd634b623fc71e3a25 100644 (file)
@@ -18,7 +18,7 @@
 * Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt
 */
 
-#define CPU_TESTER 0
+#define CPU_TESTER 1
 
 #include "sysconfig.h"
 #include "sysdeps.h"
@@ -1989,13 +1989,13 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        term ();
                                if (store_dir) {
-                                       printf ("\t%s (%sa + 2, %s);\n", dstw, to, from);
+                                       printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from);
                                        check_ipl_again();
-                                       printf ("%s (%sa, %s >> 16);\n", dstw, to, from);
+                                       printf ("%s (%sa, %s >> 16);\n", dstwx, to, from);
                                } else {
-                                       printf ("\t%s (%sa, %s >> 16);\n", dstw, to, from);
+                                       printf ("\t%s (%sa, %s >> 16);\n", dstwx, to, from);
                                        check_ipl_again();
-                                       printf ("\t%s (%sa + 2, %s);\n", dstw, to, from);
+                                       printf ("\t%s (%sa + 2, %s);\n", dstwx, to, from);
                                }
                                count_write += 2;
                                break;
@@ -2033,21 +2033,21 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz
                        switch (size) {
                        case sz_byte:
                                insn_n_cycles += 4;
-                               printf ("\t%s (%sa, %s);\n", dstb, to, from);
+                               printf ("\t%s (%sa, %s);\n", dstbx, to, from);
                                count_write++;
                                break;
                        case sz_word:
                                insn_n_cycles += 4;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        term ();
-                               printf ("\t%s (%sa, %s);\n", dstw, to, from);
+                               printf ("\t%s (%sa, %s);\n", dstwx, to, from);
                                count_write++;
                                break;
                        case sz_long:
                                insn_n_cycles += 8;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        term ();
-                               printf ("\t%s (%sa, %s);\n", dstl, to, from);
+                               printf ("\t%s (%sa, %s);\n", dstlx, to, from);
                                count_write += 2;
                                break;
                        default:
@@ -3407,6 +3407,8 @@ static void gen_opcode (unsigned int opcode)
                if (cpu_level >= xBCD_KEEPS_V_FLAG) {
                        if (next_cpu_level < xBCD_KEEPS_V_FLAG)
                                next_cpu_level = xBCD_KEEPS_V_FLAG - 1;
+                       if (cpu_level >= xBCD_KEEPS_V_FLAG && cpu_level < xBCD_KEEPS_N_FLAG)
+                               printf("\tSET_VFLG(0);\n");
                } else {
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
                }
@@ -3493,7 +3495,7 @@ static void gen_opcode (unsigned int opcode)
                printf ("\tif (cflg) newv += 0x60;\n");
                printf ("\tSET_CFLG (cflg);\n");
                duplicate_carry (0);
-               /* Manual says bits NV are undefined though a real 68030 doesn't change V and 68040/060 don't change both */
+               /* Manual says bits NV are undefined though a real 68030 clears V and 68040/060 don't change both */
                if (cpu_level >= xBCD_KEEPS_N_FLAG) {
                        if (next_cpu_level < xBCD_KEEPS_N_FLAG)
                                next_cpu_level = xBCD_KEEPS_N_FLAG - 1;
@@ -3504,6 +3506,8 @@ static void gen_opcode (unsigned int opcode)
                if (cpu_level >= xBCD_KEEPS_V_FLAG) {
                        if (next_cpu_level < xBCD_KEEPS_V_FLAG)
                                next_cpu_level = xBCD_KEEPS_V_FLAG - 1;
+                       if (cpu_level >= xBCD_KEEPS_V_FLAG && cpu_level < xBCD_KEEPS_N_FLAG)
+                               printf("\tSET_VFLG(0);\n");
                } else {
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
                }
@@ -3560,6 +3564,8 @@ static void gen_opcode (unsigned int opcode)
                if (cpu_level >= xBCD_KEEPS_V_FLAG) {
                        if (next_cpu_level < xBCD_KEEPS_V_FLAG)
                                next_cpu_level = xBCD_KEEPS_V_FLAG - 1;
+                       if (cpu_level >= xBCD_KEEPS_V_FLAG && cpu_level < xBCD_KEEPS_N_FLAG)
+                               printf("\tSET_VFLG(0);\n");
                } else {
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
                }
@@ -4680,18 +4686,18 @@ bccl_not68020:
                genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                sync_m68k_pc ();
                addcycles000 (4);
-               printf("\tsetchkundefinedflags(src, dst);\n");
                printf("\tif ((uae_s32)dst < 0) {\n");
-               printf("\t\tSET_NFLG (1);\n");
+               printf("\t\tsetchkundefinedflags(src, dst, %d);\n", curi->size);
                printf("\t\tException_cpu(6);\n");
                printf("\t\tgoto %s;\n", endlabelstr);
                printf("\t}\n");
                addcycles000 (2);
                printf("\tif (dst > src) {\n");
-               printf("\t\tSET_NFLG (0);\n");
+               printf("\t\tsetchkundefinedflags(src, dst, %d);\n", curi->size);
                printf("\t\tException_cpu(6);\n");
                printf("\t\tgoto %s;\n", endlabelstr);
                printf("\t}\n");
+               printf("\tsetchkundefinedflags(src, dst, %d);\n", curi->size);
                fill_prefetch_next ();
                need_endlabel = 1;
                break;
@@ -4699,7 +4705,7 @@ bccl_not68020:
                genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                fill_prefetch_0 ();
-               printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
+               printf ("\t{uae_u32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
                switch (curi->size) {
                case sz_byte:
                        printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb);
@@ -4715,9 +4721,12 @@ bccl_not68020:
                default:
                        term ();
                }
-               printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
-               printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
-               printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr);
+               printf("\tsetchk2undefinedflags(lower, upper, reg, (extra & 0x8000) ? %d : 2);\n", curi->size);
+               printf("\tupper -= lower;\n");
+               printf("\treg -= lower;\n");
+               printf("\tSET_ZFLG (upper == reg || 0 == reg);\n");
+               printf("\tSET_CFLG_ALWAYS (reg > upper);\n");
+               printf("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr);
                need_endlabel = 1;
                break;
 
@@ -5269,11 +5278,11 @@ bccl_not68020:
                                int old_m68k_pc_total = m68k_pc_total;
                                old_brace_level = n_braces;
                                start_brace ();
-                               printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
                                genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                                tail_ce020_done = false;
                                returntail(false);
                                did_prefetch = 0;
+                               printf("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
                                genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst");
                                sync_m68k_pc();
                                pop_braces(old_brace_level);
@@ -5428,20 +5437,18 @@ bccl_not68020:
                break;
        case i_PACK:
                if (curi->smode == Dreg) {
-                       printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0));
-                       printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
+                       printf("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0));
+                       printf("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
                } else {
                        printf ("\tuae_u16 val;\n");
                        addmmufixup ("srcreg");
-                       printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
-                       printf ("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff);\n", srcb);
-                       printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
-                       printf ("\tval = val | ((uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff) << 8);\n", srcb);
-                       printf ("\tval += %s;\n", gen_nextiword(0));
+                       printf("\tm68k_areg (regs, srcreg) -= 2;\n");
+                       printf("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)));\n", srcw);
+                       printf("\tval += %s;\n", gen_nextiword(0));
                        addmmufixup ("dstreg");
-                       printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
+                       printf("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
                        gen_set_fault_pc (false, false);
-                       printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb);
+                       printf("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb);
                }
                break;
        case i_UNPK:
@@ -5457,17 +5464,9 @@ bccl_not68020:
                        printf ("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff);\n", srcb);
                        printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
                        addmmufixup ("dstreg");
-                       if (cpu_level >= 2) {
-                               printf ("\tm68k_areg (regs, dstreg) -= 2 * areg_byteinc[dstreg];\n");
-                               printf ("\t%s (m68k_areg (regs, dstreg) + areg_byteinc[dstreg], val);\n", dstb);
-                               printf ("\t%s (m68k_areg (regs, dstreg), val >> 8);\n", dstb);
-                       } else {
-                               printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
-                               printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb);
-                               printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
-                               gen_set_fault_pc (false, false);
-                               printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb);
-                       }
+                       printf("\tm68k_areg (regs, dstreg) -= 2;\n");
+                       gen_set_fault_pc(false, false);
+                       printf("\t%s (m68k_areg (regs, dstreg), val);\n", dstw);
                }
                break;
        case i_TAS:
index 49eaa34856e08383e0c237e1bec16678cea1a56b..2fbc49eada8cb320c6c53bf9dff3b00ded3de626 100644 (file)
@@ -25,6 +25,13 @@ extern void fpsr_set_exception(uae_u32 exception);
 extern void fpu_modechange(void);
 extern void fpu_clearstatus(void);
 
+extern void fpp_set_fpcr(uae_u32 val);
+extern void fpp_set_fpsr(uae_u32 val);
+extern void fpp_set_fpiar(uae_u32 val);
+extern uae_u32 fpp_get_fpsr(void);
+extern uae_u32 fpp_get_fpcr(void);
+extern uae_u32 fpp_get_fpiar(void);
+
 #if defined(CPU_i386) || defined(CPU_x86_64)
 extern void init_fpucw_x87(void);
 #ifdef MSVC_LONG_DOUBLE
index ab3f61c1a9b16fad784b2170dc3582047a01906f..ebdc18a54c6b450eb64d650131abe876842ac7f6 100644 (file)
@@ -680,7 +680,8 @@ extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor);
 extern void divbyzero_special(bool issigned, uae_s32 dst);
 extern void setdivuoverflowflags(uae_u32 dividend, uae_u16 divisor);
 extern void setdivsoverflowflags(uae_s32 dividend, uae_s16 divisor);
-extern void setchkundefinedflags(uae_s16 src, uae_s16 dst);
+extern void setchkundefinedflags(uae_s32 src, uae_s32 dst, int size);
+extern void setchk2undefinedflags(uae_u32 lower, uae_u32 upper, uae_u32 val, int size);
 extern void protect_roms (bool);
 extern void unprotect_maprom (void);
 extern bool is_hardreset(void);
index 84516cce25ec057ef3e8275a81c6f4709dabcd5a..33bf3bd86d38c870dc4fa38e7f133a7b48793e2d 100644 (file)
@@ -2816,7 +2816,7 @@ static void Exception_normal (int nr)
                        if (currprefs.cpu_model >= 68040) {
                                if (nr == 2) {
                                        if (currprefs.mmu_model) {
-                                               // 68040 mmu bus error
+                                               // 68040/060 mmu bus error
                                                for (i = 0 ; i < 7 ; i++) {
                                                        m68k_areg (regs, 7) -= 4;
                                                        x_put_long (m68k_areg (regs, 7), 0);
@@ -2890,61 +2890,26 @@ static void Exception_normal (int nr)
                                        }
 
                                } else {
-                                       m68k_areg (regs, 7) -= 4;
-                                       x_put_long (m68k_areg (regs, 7), last_fault_for_exception_3);
-                                       m68k_areg (regs, 7) -= 2;
-                                       x_put_word (m68k_areg (regs, 7), 0x2000 + vector_nr * 4);
+                                       // 68040/060 odd PC address error
+                                       Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x02);
+                                       used_exception_build_stack_frame = true;
                                }
                        } else if (currprefs.cpu_model >= 68020) {
-                               // 68020/030 address error
+                               // 68020/030 odd PC address error (partially implemented only)
                                uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
                                ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40;
                                ssw |= 0x20;
-                               for (i = 0 ; i < 36; i++) {
-                                       m68k_areg (regs, 7) -= 2;
-                                       x_put_word (m68k_areg (regs, 7), 0);
-                               }
-                               m68k_areg (regs, 7) -= 4;
-                               x_put_long (m68k_areg (regs, 7), last_fault_for_exception_3);
-                               m68k_areg (regs, 7) -= 2;
-                               x_put_word (m68k_areg (regs, 7), 0);
-                               m68k_areg (regs, 7) -= 2;
-                               x_put_word (m68k_areg (regs, 7), 0);
-                               m68k_areg (regs, 7) -= 2;
-                               x_put_word (m68k_areg (regs, 7), 0);
-                               m68k_areg (regs, 7) -= 2;
-                               x_put_word (m68k_areg (regs, 7), ssw);
-                               m68k_areg (regs, 7) -= 2;
-                               x_put_word (m68k_areg (regs, 7), 0xb000 + vector_nr * 4);
+                               regs.mmu_fault_addr = last_fault_for_exception_3;
+                               Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x0a);
+                               used_exception_build_stack_frame = true;
                        } else {
                                // 68010 address error (partially implemented only)
                                uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
                                ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100;
                                ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000;
-                               for (i = 0; i < 15; i++) {
-                                       m68k_areg(regs, 7) -= 2;
-                                       x_put_word(m68k_areg(regs, 7), 0);
-                               }
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0); // version
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), last_op_for_exception_3); // instruction input buffer
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0); // unused
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0); // data input buffer
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0); // unused
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0); // data output buffer
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0); // unused
-                               m68k_areg(regs, 7) -= 4;
-                               x_put_long(m68k_areg(regs, 7), last_addr_for_exception_3); // fault addr
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), ssw); // ssw
-                               m68k_areg(regs, 7) -= 2;
-                               x_put_word(m68k_areg(regs, 7), 0x8000 + vector_nr * 4);
+                               regs.mmu_fault_addr = last_addr_for_exception_3;
+                               Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x08);
+                               used_exception_build_stack_frame = true;
                        }
                        write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, regs.instruction_pc, currpc, get_long_debug (regs.vbr + 4 * vector_nr));
                } else if (regs.m && interrupt) { /* M + Interrupt */
@@ -2970,7 +2935,7 @@ static void Exception_normal (int nr)
                add_approximate_exception_cycles(nr);
                nextpc = m68k_getpc ();
                if (nr == 2 || nr == 3) {
-                       // 68000 address error
+                       // 68000 bus error/address error
                        uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
                        mode |= last_writeaccess_for_exception_3 ? 0 : 16;
                        mode |= last_notinstruction_for_exception_3 ? 8 : 0;
index c29c69c3ba140453ee5c329bb0c3661f8be2c6f0..bbce3b5b29f699b9f796fce2ac774007e56d10f4 100644 (file)
@@ -762,7 +762,7 @@ int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor)
 /* DIV divide by zero
  *
  * 68000 Signed: NVC=0 Z=1. Unsigned: VC=0 N=(dst>>16)<0 Z=(dst>>16)==0
- * 68020 and 68030: Signed: Z=1 NVC=0. Unsigned: V=1, N=(dst>>16)<0 Z=(dst>>16)==0, C=0.
+ * 68020 and 68030: Signed: Z=1 NC=0. V=? (sometimes random!) Unsigned: V=1, N=(dst>>16)<0 Z=(dst>>16)==0, C=0.
  * 68040/68060 C=0.
  *
  */
@@ -858,14 +858,66 @@ void setdivsoverflowflags(uae_s32 dividend, uae_s16 divisor)
 /*
  * CHK.W undefined flags
  *
- * 68000: CV=0, Z if dst==0.
+ * 68000: CV=0. Z: dst==0. N: dst < 0. !N: dst > src.
+ * 68020: Z: dst==0. N: dst < 0. V: src-dst overflow. C: if dst < 0: (dst > src || src >= 0), if dst > src: (src >= 0).
  *
  */
-void setchkundefinedflags(uae_s16 src, uae_s16 dst)
+void setchkundefinedflags(uae_s32 src, uae_s32 dst, int size)
 {
        CLEAR_CZNV();
-       if (dst == 0)
-               SET_ZFLG(1);
+       if (currprefs.cpu_model < 68020) {
+               if (dst == 0)
+                       SET_ZFLG(1);
+               if (dst < 0)
+                       SET_NFLG(1);
+               else if (dst > src)
+                       SET_NFLG(0);
+       } else if (currprefs.cpu_model == 68020 || currprefs.cpu_model == 68030) {
+               if (dst == 0)
+                       SET_ZFLG(1);
+               SET_NFLG(dst < 0);
+               if (dst < 0 || dst > src) {
+                       if (size == sz_word) {
+                               int flgs = ((uae_s16)(dst)) < 0;
+                                       int flgo = ((uae_s16)(src)) < 0;
+                                       uae_s16 val = (uae_s16)src - (uae_s16)dst;
+                                       int flgn = val < 0;
+                                       SET_VFLG((flgs ^ flgo) & (flgn ^ flgo));
+                       } else {
+                               int flgs = dst < 0;
+                                       int flgo = src < 0;
+                                       uae_s32 val = src - dst;
+                               int flgn = val < 0;
+                               SET_VFLG((flgs ^ flgo) & (flgn ^ flgo));
+                       }
+                       if (dst < 0) {
+                               SET_CFLG(dst > src || src >= 0);
+                       } else {
+                               SET_CFLG(src >= 0);
+                       }
+               }
+       }
+}
+
+void setchk2undefinedflags(uae_u32 lower, uae_u32 upper, uae_u32 val, int size)
+{
+       uae_u32 nmask;
+       if (size == sz_byte)
+               nmask = 0x80;
+       else if (size == sz_word)
+               nmask = 0x8000;
+       else
+               nmask = 0x80000000;
+
+       SET_NFLG(0);
+       if ((upper & nmask) && val > upper) {
+               SET_NFLG(1);
+       } else if (!(upper & nmask) && val > upper && val < nmask) {
+               SET_NFLG(1);
+       } else if (val < lower) {
+               SET_NFLG(1);
+       }
+       SET_VFLG(0);
 }
 
 #ifndef CPUEMU_68000_ONLY
@@ -896,6 +948,14 @@ STATIC_INLINE int div_unsigned (uae_u32 src_hi, uae_u32 src_lo, uae_u32 div, uae
 }
 #endif
 
+static void divl_overflow(void)
+{
+       SET_VFLG(1);
+       SET_NFLG(1);
+       SET_CFLG(0);
+       SET_ZFLG(0);
+}
+
 bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
 {
        if ((extra & 0x400) && currprefs.int_no_unimplemented && currprefs.cpu_model == 68060) {
@@ -903,7 +963,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
                return false;
        }
        if (src == 0) {
-               Exception_cpu (5);
+               Exception_cpu(5);
                return false;
        }
 #if defined (uae_s64)
@@ -918,18 +978,14 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
                }
 
                if ((uae_u64)a == 0x8000000000000000UL && src == ~0u) {
-                       SET_VFLG (1);
-                       SET_NFLG (1);
-                       SET_CFLG (0);
+                       divl_overflow();
                } else {
                        rem = a % (uae_s64)(uae_s32)src;
                        quot = a / (uae_s64)(uae_s32)src;
                        if ((quot & UVAL64 (0xffffffff80000000)) != 0
                                && (quot & UVAL64 (0xffffffff80000000)) != UVAL64 (0xffffffff80000000))
                        {
-                               SET_VFLG (1);
-                               SET_NFLG (1);
-                               SET_CFLG (0);
+                               divl_overflow();
                        } else {
                                if (((uae_s32)rem < 0) != ((uae_s64)a < 0)) rem = -rem;
                                SET_VFLG (0);
@@ -952,9 +1008,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
                rem = a % (uae_u64)src;
                quot = a / (uae_u64)src;
                if (quot > 0xffffffffu) {
-                       SET_VFLG (1);
-                       SET_NFLG (1);
-                       SET_CFLG (0);
+                       divl_overflow();
                } else {
                        SET_VFLG (0);
                        SET_CFLG (0);
@@ -986,9 +1040,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
                if ((uae_s32)src < 0) src = -src;
                if (div_unsigned (hi, lo, src, &quot, &rem) ||
                        (sign & 0x80000000) ? quot > 0x80000000 : quot > 0x7fffffff) {
-                               SET_VFLG (1);
-                               SET_NFLG (1);
-                               SET_CFLG (0);
+                               divl_overflow();
                } else {
                        if (sign & 0x80000000) quot = -quot;
                        if (((uae_s32)rem < 0) != (save_high < 0)) rem = -rem;
@@ -1009,9 +1061,7 @@ bool m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
                        hi = (uae_u32)m68k_dreg (regs, extra & 7);
                }
                if (div_unsigned (hi, lo, src, &quot, &rem)) {
-                       SET_VFLG (1);
-                       SET_NFLG (1);
-                       SET_CFLG (0);
+                       divl_overflow();
                } else {
                        SET_VFLG (0);
                        SET_CFLG (0);
@@ -1188,7 +1238,13 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                m68k_areg(regs, 7) -= 4;
                x_put_long(m68k_areg(regs, 7), regs.fp_ea);
                break;
-#ifndef CPU_TESTER
+       case 0x4: // floating point unimplemented stack frame (68LC040, 68EC040)
+               // or 68060 bus access fault stack frame
+               m68k_areg(regs, 7) -= 4;
+               x_put_long(m68k_areg(regs, 7), ssw);
+               m68k_areg(regs, 7) -= 4;
+               x_put_long(m68k_areg(regs, 7), oldpc);
+               break;
        case 0x7: // access error stack frame (68040)
 
                for (i = 3; i >= 0; i--) {
@@ -1225,7 +1281,30 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                m68k_areg(regs, 7) -= 4;
                x_put_long(m68k_areg(regs, 7), regs.mmu_effective_addr);
                break;
-#endif
+       case 0x8: // address error (68010)
+               for (i = 0; i < 15; i++) {
+                       m68k_areg(regs, 7) -= 2;
+                       x_put_word(m68k_areg(regs, 7), 0);
+               }
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), 0); // version
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), regs.opcode); // instruction input buffer
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), 0); // unused
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), 0); // data input buffer
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), 0); // unused
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), 0); // data output buffer
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), 0); // unused
+               m68k_areg(regs, 7) -= 4;
+               x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // fault addr
+               m68k_areg(regs, 7) -= 2;
+               x_put_word(m68k_areg(regs, 7), ssw); // ssw
+               break;
        case 0x9: // coprocessor mid-instruction stack frame (68020, 68030)
                m68k_areg(regs, 7) -= 4;
                x_put_long(m68k_areg(regs, 7), regs.fp_ea);
@@ -1234,17 +1313,6 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                m68k_areg(regs, 7) -= 4;
                x_put_long(m68k_areg(regs, 7), oldpc);
                break;
-       case 0x8: // bus and address error stack frame (68010)
-               write_log(_T("Exception stack frame format %X not implemented\n"), format);
-               return;
-       case 0x4: // floating point unimplemented stack frame (68LC040, 68EC040)
-               // or 68060 bus access fault stack frame
-               m68k_areg(regs, 7) -= 4;
-               x_put_long(m68k_areg(regs, 7), ssw);
-               m68k_areg(regs, 7) -= 4;
-               x_put_long(m68k_areg(regs, 7), oldpc);
-               break;
-#ifndef CPU_TESTER
        case 0xB: // long bus cycle fault stack frame (68020, 68030)
                // Store state information to internal register space
 #if MMU030_DEBUG
@@ -1343,7 +1411,6 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
                m68k_areg(regs, 7) -= 2;
                x_put_word(m68k_areg(regs, 7), regs.wb2_address); // = mmu030_state[1]);
                break;
-#endif
        default:
                write_log(_T("Unknown exception stack frame format: %X\n"), format);
                return;
index 0f0b21e82aaab3b2ebb6920cd49aec1f60f0fb26..eb9f1856a4e5e833fc7b25c02937655be37616e1 100644 (file)
@@ -128,7 +128,6 @@ struct mnemolookup lookuptab[] = {
        { i_FScc, _T("FScc"), NULL, 0 },
        { i_FTRAPcc, _T("FTRAPcc"), NULL, 0 },
        { i_FBcc, _T("FBcc"), NULL, 0 },
-       { i_FBcc, _T("FBcc"), NULL, 0 },
        { i_FSAVE, _T("FSAVE"), NULL, 0 },
        { i_FRESTORE, _T("FRESTORE"), NULL, 0 },