]> git.sesse.net Git - pistorm/blobdiff - m68k_in.c
introducing CPU state paramter 2
[pistorm] / m68k_in.c
index cf0eb18184cedc38b2a4028b56baef45c8e73336..7c36327a378b191c967e6d16461c03563703c85b 100644 (file)
--- a/m68k_in.c
+++ b/m68k_in.c
@@ -112,7 +112,9 @@ M68KMAKE_PROTOTYPE_FOOTER
 /* Build the opcode handler table */
 void m68ki_build_opcode_table(void);
 
-extern void (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
+struct m68ki_cpu_core;
+
+extern void (*m68ki_instruction_jump_table[0x10000])(struct m68ki_cpu_core *state); /* opcode handler jump table */
 extern unsigned char m68ki_cycles[][0x10000];
 
 
@@ -136,13 +138,13 @@ M68KMAKE_TABLE_HEADER
 
 #define NUM_CPU_TYPES 5
 
-void  (*m68ki_instruction_jump_table[0x10000])(void); /* opcode handler jump table */
+void  (*m68ki_instruction_jump_table[0x10000])(m68ki_cpu_core *state); /* opcode handler jump table */
 unsigned char m68ki_cycles[NUM_CPU_TYPES][0x10000]; /* Cycles used by CPU type */
 
 /* This is used to generate the opcode handler jump table */
 typedef struct
 {
-       void (*opcode_handler)(void);        /* handler function */
+       void (*opcode_handler)(m68ki_cpu_core *state);        /* handler function */
        unsigned int  mask;                  /* mask on opcode */
        unsigned int  match;                 /* what to match after masking */
        unsigned char cycles[NUM_CPU_TYPES]; /* cycles each cpu type takes */
@@ -281,9 +283,10 @@ M68KMAKE_OPCODE_HANDLER_HEADER
 
 #include <stdio.h>
 #include "m68kcpu.h"
-extern void m68040_fpu_op0(void);
-extern void m68040_fpu_op1(void);
-extern void m68881_mmu_ops();
+extern void m68040_fpu_op0(m68ki_cpu_core *state);
+extern void m68040_fpu_op1(m68ki_cpu_core *state);
+extern void m68851_mmu_ops(m68ki_cpu_core *state);
+extern void m68881_ftrap(m68ki_cpu_core *state);
 
 /* ======================================================================== */
 /* ========================= INSTRUCTION HANDLERS ========================= */
@@ -561,6 +564,7 @@ cpdbcc    32  .     .     1111...001001...  ..........  . . U U .   .   .   4
 cpgen     32  .     .     1111...000......  ..........  . . U U .   .   .   4   4   .  unemulated
 cpscc     32  .     .     1111...001......  ..........  . . U U .   .   .   4   4   .  unemulated
 cptrapcc  32  .     .     1111...001111...  ..........  . . U U .   .   .   4   4   .  unemulated
+ftrapcc   32  .     .     1111001001111...  ..........  . . U U .   .   .   4   4   .
 dbt       16  .     .     0101000011001...  ..........  U U U U U  12  12   6   6   6
 dbf       16  .     .     0101000111001...  ..........  U U U U U  12  12   6   6   6
 dbcc      16  .     .     0101....11001...  ..........  U U U U U  12  12   6   6   6
@@ -769,7 +773,8 @@ pack      16  mm    ay7   1000...101001111  ..........  . . U U U   .   .  13  1
 pack      16  mm    axy7  1000111101001111  ..........  . . U U U   .   .  13  13  13
 pack      16  mm    .     1000...101001...  ..........  . . U U U   .   .  13  13  13
 pea       32  .     .     0100100001......  A..DXWLdx.  U U U U U   6   6   5   5   5
-pflush    32  .     .     1111010100011000  ..........  . . . . S   .   .   .   .   4   TODO: correct timing
+pflusha   32  .     .     1111010100011...  ..........  . . . . S   .   .   .   .   4   TODO: correct timing
+pflushan  32  .     .     1111010100010...  ..........  . . . . S   .   .   .   .   4   TODO: correct timing
 pmmu      32  .     .     1111000.........  ..........  . . S S S   .   .   8   8   8
 reset      0  .     .     0100111001110000  ..........  S S S S S   0   0   0   0   0
 ror        8  s     .     1110...000011...  ..........  U U U U U   6   6   8   8   8
@@ -915,9 +920,10 @@ M68KMAKE_OP(1111, 0, ., .)
 
 M68KMAKE_OP(040fpu0, 32, ., .)
 {
-       if(CPU_TYPE_IS_030_PLUS(CPU_TYPE))
+//     printf("FPU 040fpu0 HAS_FPU=%d\n",!!HAS_FPU);
+       if(HAS_FPU)
        {
-               m68040_fpu_op0();
+               void m68040_fpu_op0(m68ki_cpu_core *state);
                return;
        }
        m68ki_exception_1111();
@@ -926,9 +932,10 @@ M68KMAKE_OP(040fpu0, 32, ., .)
 
 M68KMAKE_OP(040fpu1, 32, ., .)
 {
-       if(CPU_TYPE_IS_030_PLUS(CPU_TYPE))
+//     printf("FPU 040fpu1 HAS_FPU=%d\n",!!HAS_FPU);
+       if(HAS_FPU)
        {
-               m68040_fpu_op1();
+               void m68040_fpu_op1(m68ki_cpu_core *state);
                return;
        }
        m68ki_exception_1111();
@@ -942,13 +949,14 @@ M68KMAKE_OP(abcd, 8, rr, .)
        uint src = DY;
        uint dst = *r_dst;
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
-
-       FLAG_V = ~res; /* Undefined V behavior */
+       uint corf = 0;
 
        if(res > 9)
-               res += 6;
+               corf = 6;
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
+       FLAG_V = ~res; /* Undefined V behavior */
+       res += corf;
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;
        if(FLAG_C)
                res -= 0xa0;
 
@@ -964,17 +972,18 @@ M68KMAKE_OP(abcd, 8, rr, .)
 
 M68KMAKE_OP(abcd, 8, mm, ax7)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
-
-       FLAG_V = ~res; /* Undefined V behavior */
+       uint corf = 0;
 
        if(res > 9)
-               res += 6;
+               corf = 6;
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
+       FLAG_V = ~res; /* Undefined V behavior */
+       res += corf;
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;
        if(FLAG_C)
                res -= 0xa0;
 
@@ -990,17 +999,18 @@ M68KMAKE_OP(abcd, 8, mm, ax7)
 
 M68KMAKE_OP(abcd, 8, mm, ay7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
-
-       FLAG_V = ~res; /* Undefined V behavior */
+       uint corf = 0;
 
        if(res > 9)
-               res += 6;
+               corf = 6;
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
+       FLAG_V = ~res; /* Undefined V behavior */
+       res += corf;
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;
        if(FLAG_C)
                res -= 0xa0;
 
@@ -1016,17 +1026,18 @@ M68KMAKE_OP(abcd, 8, mm, ay7)
 
 M68KMAKE_OP(abcd, 8, mm, axy7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
-
-       FLAG_V = ~res; /* Undefined V behavior */
+       uint corf = 0;
 
        if(res > 9)
-               res += 6;
+               corf = 6;
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
+       FLAG_V = ~res; /* Undefined V behavior */
+       res += corf;
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;
        if(FLAG_C)
                res -= 0xa0;
 
@@ -1042,17 +1053,18 @@ M68KMAKE_OP(abcd, 8, mm, axy7)
 
 M68KMAKE_OP(abcd, 8, mm, .)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
-
-       FLAG_V = ~res; /* Undefined V behavior */
+       uint corf = 0;
 
        if(res > 9)
-               res += 6;
+               corf = 6;
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
+       FLAG_V = ~res; /* Undefined V behavior */
+       res  += corf;
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;
        if(FLAG_C)
                res -= 0xa0;
 
@@ -1295,7 +1307,7 @@ M68KMAKE_OP(adda, 32, ., .)
 M68KMAKE_OP(addi, 8, ., d)
 {
        uint* r_dst = &DY;
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint dst = MASK_OUT_ABOVE_8(*r_dst);
        uint res = src + dst;
 
@@ -1310,7 +1322,7 @@ M68KMAKE_OP(addi, 8, ., d)
 
 M68KMAKE_OP(addi, 8, ., .)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint dst = m68ki_read_8(ea);
        uint res = src + dst;
@@ -1327,7 +1339,7 @@ M68KMAKE_OP(addi, 8, ., .)
 M68KMAKE_OP(addi, 16, ., d)
 {
        uint* r_dst = &DY;
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint dst = MASK_OUT_ABOVE_16(*r_dst);
        uint res = src + dst;
 
@@ -1342,7 +1354,7 @@ M68KMAKE_OP(addi, 16, ., d)
 
 M68KMAKE_OP(addi, 16, ., .)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint dst = m68ki_read_16(ea);
        uint res = src + dst;
@@ -1359,7 +1371,7 @@ M68KMAKE_OP(addi, 16, ., .)
 M68KMAKE_OP(addi, 32, ., d)
 {
        uint* r_dst = &DY;
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint dst = *r_dst;
        uint res = src + dst;
 
@@ -1374,7 +1386,7 @@ M68KMAKE_OP(addi, 32, ., d)
 
 M68KMAKE_OP(addi, 32, ., .)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint dst = m68ki_read_32(ea);
        uint res = src + dst;
@@ -1557,7 +1569,7 @@ M68KMAKE_OP(addx, 32, rr, .)
 
 M68KMAKE_OP(addx, 8, mm, ax7)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = src + dst + XFLAG_AS_1();
@@ -1575,7 +1587,7 @@ M68KMAKE_OP(addx, 8, mm, ax7)
 
 M68KMAKE_OP(addx, 8, mm, ay7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = src + dst + XFLAG_AS_1();
@@ -1593,7 +1605,7 @@ M68KMAKE_OP(addx, 8, mm, ay7)
 
 M68KMAKE_OP(addx, 8, mm, axy7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = src + dst + XFLAG_AS_1();
@@ -1611,7 +1623,7 @@ M68KMAKE_OP(addx, 8, mm, axy7)
 
 M68KMAKE_OP(addx, 8, mm, .)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = src + dst + XFLAG_AS_1();
@@ -1629,7 +1641,7 @@ M68KMAKE_OP(addx, 8, mm, .)
 
 M68KMAKE_OP(addx, 16, mm, .)
 {
-       uint src = OPER_AY_PD_16();
+       uint src = OPER_AY_PD_16(state);
        uint ea  = EA_AX_PD_16();
        uint dst = m68ki_read_16(ea);
        uint res = src + dst + XFLAG_AS_1();
@@ -1647,7 +1659,7 @@ M68KMAKE_OP(addx, 16, mm, .)
 
 M68KMAKE_OP(addx, 32, mm, .)
 {
-       uint src = OPER_AY_PD_32();
+       uint src = OPER_AY_PD_32(state);
        uint ea  = EA_AX_PD_32();
        uint dst = m68ki_read_32(ea);
        uint res = src + dst + XFLAG_AS_1();
@@ -1767,7 +1779,7 @@ M68KMAKE_OP(and, 32, re, .)
 
 M68KMAKE_OP(andi, 8, ., d)
 {
-       FLAG_Z = MASK_OUT_ABOVE_8(DY &= (OPER_I_8() | 0xffffff00));
+       FLAG_Z = MASK_OUT_ABOVE_8(DY &= (OPER_I_8(state) | 0xffffff00));
 
        FLAG_N = NFLAG_8(FLAG_Z);
        FLAG_C = CFLAG_CLEAR;
@@ -1777,7 +1789,7 @@ M68KMAKE_OP(andi, 8, ., d)
 
 M68KMAKE_OP(andi, 8, ., .)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint res = src & m68ki_read_8(ea);
 
@@ -1792,7 +1804,7 @@ M68KMAKE_OP(andi, 8, ., .)
 
 M68KMAKE_OP(andi, 16, ., d)
 {
-       FLAG_Z = MASK_OUT_ABOVE_16(DY &= (OPER_I_16() | 0xffff0000));
+       FLAG_Z = MASK_OUT_ABOVE_16(DY &= (OPER_I_16(state) | 0xffff0000));
 
        FLAG_N = NFLAG_16(FLAG_Z);
        FLAG_C = CFLAG_CLEAR;
@@ -1802,7 +1814,7 @@ M68KMAKE_OP(andi, 16, ., d)
 
 M68KMAKE_OP(andi, 16, ., .)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint res = src & m68ki_read_16(ea);
 
@@ -1817,7 +1829,7 @@ M68KMAKE_OP(andi, 16, ., .)
 
 M68KMAKE_OP(andi, 32, ., d)
 {
-       FLAG_Z = DY &= (OPER_I_32());
+       FLAG_Z = DY &= (OPER_I_32(state));
 
        FLAG_N = NFLAG_32(FLAG_Z);
        FLAG_C = CFLAG_CLEAR;
@@ -1827,7 +1839,7 @@ M68KMAKE_OP(andi, 32, ., d)
 
 M68KMAKE_OP(andi, 32, ., .)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint res = src & m68ki_read_32(ea);
 
@@ -1842,7 +1854,7 @@ M68KMAKE_OP(andi, 32, ., .)
 
 M68KMAKE_OP(andi, 16, toc, .)
 {
-       m68ki_set_ccr(m68ki_get_ccr() & OPER_I_8());
+       m68ki_set_ccr(m68ki_get_ccr() & OPER_I_8(state));
 }
 
 
@@ -1850,9 +1862,9 @@ M68KMAKE_OP(andi, 16, tos, .)
 {
        if(FLAG_S)
        {
-               uint src = OPER_I_16();
+               uint src = OPER_I_16(state);
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
-               m68ki_set_sr(m68ki_get_sr() & src);
+               m68ki_set_sr(state, m68ki_get_sr() & src);
                return;
        }
        m68ki_exception_privilege_violation();
@@ -2302,7 +2314,7 @@ M68KMAKE_OP(bcc, 16, ., .)
 {
        if(M68KMAKE_CC)
        {
-               uint offset = OPER_I_16();
+               uint offset = OPER_I_16(state);
                REG_PC -= 2;
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                m68ki_branch_16(offset);
@@ -2319,7 +2331,7 @@ M68KMAKE_OP(bcc, 32, ., .)
        {
                if(M68KMAKE_CC)
                {
-                       uint offset = OPER_I_32();
+                       uint offset = OPER_I_32(state);
                        REG_PC -= 4;
                        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                        m68ki_branch_32(offset);
@@ -2365,7 +2377,7 @@ M68KMAKE_OP(bchg, 8, r, .)
 M68KMAKE_OP(bchg, 32, s, d)
 {
        uint* r_dst = &DY;
-       uint mask = 1 << (OPER_I_8() & 0x1f);
+       uint mask = 1 << (OPER_I_8(state) & 0x1f);
 
        FLAG_Z = *r_dst & mask;
        *r_dst ^= mask;
@@ -2374,7 +2386,7 @@ M68KMAKE_OP(bchg, 32, s, d)
 
 M68KMAKE_OP(bchg, 8, s, .)
 {
-       uint mask = 1 << (OPER_I_8() & 7);
+       uint mask = 1 << (OPER_I_8(state) & 7);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint src = m68ki_read_8(ea);
 
@@ -2407,7 +2419,7 @@ M68KMAKE_OP(bclr, 8, r, .)
 M68KMAKE_OP(bclr, 32, s, d)
 {
        uint* r_dst = &DY;
-       uint mask = 1 << (OPER_I_8() & 0x1f);
+       uint mask = 1 << (OPER_I_8(state) & 0x1f);
 
        FLAG_Z = *r_dst & mask;
        *r_dst &= ~mask;
@@ -2416,7 +2428,7 @@ M68KMAKE_OP(bclr, 32, s, d)
 
 M68KMAKE_OP(bclr, 8, s, .)
 {
-       uint mask = 1 << (OPER_I_8() & 7);
+       uint mask = 1 << (OPER_I_8(state) & 7);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint src = m68ki_read_8(ea);
 
@@ -2429,7 +2441,7 @@ M68KMAKE_OP(bfchg, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint* data = &DY;
@@ -2464,7 +2476,7 @@ M68KMAKE_OP(bfchg, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint mask_base;
@@ -2503,7 +2515,7 @@ M68KMAKE_OP(bfchg, 32, ., .)
 
                if((width + offset) > 32)
                {
-                       mask_byte = MASK_OUT_ABOVE_8(mask_base);
+                       mask_byte = MASK_OUT_ABOVE_8(mask_base) << (8-offset);
                        data_byte = m68ki_read_8(ea+4);
                        FLAG_Z |= (data_byte & mask_byte);
                        m68ki_write_8(ea+4, data_byte ^ mask_byte);
@@ -2518,7 +2530,7 @@ M68KMAKE_OP(bfclr, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint* data = &DY;
@@ -2555,7 +2567,7 @@ M68KMAKE_OP(bfclr, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint mask_base;
@@ -2594,7 +2606,7 @@ M68KMAKE_OP(bfclr, 32, ., .)
 
                if((width + offset) > 32)
                {
-                       mask_byte = MASK_OUT_ABOVE_8(mask_base);
+                       mask_byte = MASK_OUT_ABOVE_8(mask_base) << (8-offset);
                        data_byte = m68ki_read_8(ea+4);
                        FLAG_Z |= (data_byte & mask_byte);
                        m68ki_write_8(ea+4, data_byte & ~mask_byte);
@@ -2609,7 +2621,7 @@ M68KMAKE_OP(bfexts, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint64 data = DY;
@@ -2643,7 +2655,7 @@ M68KMAKE_OP(bfexts, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint data;
@@ -2655,17 +2667,20 @@ M68KMAKE_OP(bfexts, 32, ., .)
                if(BIT_5(word2))
                        width = REG_D[width&7];
 
-               /* Offset is signed so we have to use ugly math =( */
-               ea += offset / 8;
-               offset %= 8;
-               if(offset < 0)
-               {
-                       offset += 8;
-                       ea--;
+               if(BIT_B(word2))  {
+                       /* Offset is signed so we have to use ugly math =( */
+                       ea += offset / 8;
+                       offset %= 8;
+                       if(offset < 0)
+                       {
+                               offset += 8;
+                               ea--;
+                       }
                }
                width = ((width-1) & 31) + 1;
 
-               data = m68ki_read_32(ea);
+               data = (offset+width) < 8 ? (m68ki_read_8(ea) << 24) :
+                       (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea);
 
                data = MASK_OUT_ABOVE_32(data<<offset);
 
@@ -2691,7 +2706,7 @@ M68KMAKE_OP(bfextu, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint64 data = DY;
@@ -2725,7 +2740,7 @@ M68KMAKE_OP(bfextu, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint data;
@@ -2737,17 +2752,20 @@ M68KMAKE_OP(bfextu, 32, ., .)
                if(BIT_5(word2))
                        width = REG_D[width&7];
 
-               /* Offset is signed so we have to use ugly math =( */
-               ea += offset / 8;
-               offset %= 8;
-               if(offset < 0)
-               {
-                       offset += 8;
-                       ea--;
+               if(BIT_B(word2)) {
+                       /* Offset is signed so we have to use ugly math =( */
+                       ea += offset / 8;
+                       offset %= 8;
+                       if(offset < 0)
+                       {
+                               offset += 8;
+                               ea--;
+                       }
                }
                width = ((width-1) & 31) + 1;
 
-               data = m68ki_read_32(ea);
+       data = (offset+width) < 8 ? (m68ki_read_8(ea) << 24) :
+                       (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea);
                data = MASK_OUT_ABOVE_32(data<<offset);
 
                if((offset+width) > 32)
@@ -2772,7 +2790,7 @@ M68KMAKE_OP(bfffo, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint64 data = DY;
@@ -2810,7 +2828,7 @@ M68KMAKE_OP(bfffo, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                sint local_offset;
                uint width = word2;
@@ -2834,7 +2852,7 @@ M68KMAKE_OP(bfffo, 32, ., .)
                }
                width = ((width-1) & 31) + 1;
 
-               data = m68ki_read_32(ea);
+               data = (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea);
                data = MASK_OUT_ABOVE_32(data<<local_offset);
 
                if((local_offset+width) > 32)
@@ -2862,7 +2880,7 @@ M68KMAKE_OP(bfins, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint* data = &DY;
@@ -2904,7 +2922,7 @@ M68KMAKE_OP(bfins, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint insert_base = REG_D[(word2>>12)&7];
@@ -2923,13 +2941,15 @@ M68KMAKE_OP(bfins, 32, ., .)
                if(BIT_5(word2))
                        width = REG_D[width&7];
 
-               /* Offset is signed so we have to use ugly math =( */
-               ea += offset / 8;
-               offset %= 8;
-               if(offset < 0)
-               {
-                       offset += 8;
-                       ea--;
+               if(BIT_B(word2)) {
+                       /* Offset is signed so we have to use ugly math =( */
+                       ea += offset / 8;
+                       offset %= 8;
+                       if(offset < 0)
+                       {
+                               offset += 8;
+                               ea--;
+                       }
                }
                width = ((width-1) & 31) + 1;
 
@@ -2941,11 +2961,18 @@ M68KMAKE_OP(bfins, 32, ., .)
                FLAG_Z = insert_base;
                insert_long = insert_base >> offset;
 
-               data_long = m68ki_read_32(ea);
+               data_long = (offset+width) < 8 ? (m68ki_read_8(ea) << 24) :
+                               (offset+width) < 16 ? (m68ki_read_16(ea) << 16) : m68ki_read_32(ea);
                FLAG_V = VFLAG_CLEAR;
                FLAG_C = CFLAG_CLEAR;
 
-               m68ki_write_32(ea, (data_long & ~mask_long) | insert_long);
+               if((width + offset) < 8) {
+                       m68ki_write_8(ea, ((data_long & ~mask_long) | insert_long) >> 24);
+               } else if((width + offset) < 16) {
+                       m68ki_write_16(ea, ((data_long & ~mask_long) | insert_long) >> 16);
+               } else {
+                       m68ki_write_32(ea, (data_long & ~mask_long) | insert_long);
+               }
 
                if((width + offset) > 32)
                {
@@ -2965,7 +2992,7 @@ M68KMAKE_OP(bfset, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint* data = &DY;
@@ -3002,7 +3029,7 @@ M68KMAKE_OP(bfset, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint mask_base;
@@ -3057,7 +3084,7 @@ M68KMAKE_OP(bftst, 32, ., d)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint offset = (word2>>6)&31;
                uint width = word2;
                uint* data = &DY;
@@ -3092,7 +3119,7 @@ M68KMAKE_OP(bftst, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                sint offset = (word2>>6)&31;
                uint width = word2;
                uint mask_base;
@@ -3141,6 +3168,7 @@ M68KMAKE_OP(bftst, 32, ., .)
 
 M68KMAKE_OP(bkpt, 0, ., .)
 {
+// TODO: review this...
        if(CPU_TYPE_IS_010_PLUS(CPU_TYPE))
        {
                m68ki_bkpt_ack(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE) ? REG_IR & 7 : 0);      /* auto-disable (see m68kcpu.h) */
@@ -3153,19 +3181,21 @@ M68KMAKE_OP(bra, 8, ., .)
 {
        m68ki_trace_t0();                                  /* auto-disable (see m68kcpu.h) */
        m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR));
-       if(REG_PC == REG_PPC)
-               USE_ALL_CYCLES();
+// TODO: review this...
+//     if(REG_PC == REG_PPC)
+//             USE_ALL_CYCLES();
 }
 
 
 M68KMAKE_OP(bra, 16, ., .)
 {
-       uint offset = OPER_I_16();
+       uint offset = OPER_I_16(state);
        REG_PC -= 2;
        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
        m68ki_branch_16(offset);
-       if(REG_PC == REG_PPC)
-               USE_ALL_CYCLES();
+// TODO: review this...
+//     if(REG_PC == REG_PPC)
+//             USE_ALL_CYCLES();
 }
 
 
@@ -3173,20 +3203,23 @@ M68KMAKE_OP(bra, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint offset = OPER_I_32();
+               uint offset = OPER_I_32(state);
                REG_PC -= 4;
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                m68ki_branch_32(offset);
-               if(REG_PC == REG_PPC)
-                       USE_ALL_CYCLES();
+// TODO: review this...
+//             if(REG_PC == REG_PPC)
+//                     USE_ALL_CYCLES();
                return;
        }
        else
        {
-               m68ki_trace_t0();                                  /* auto-disable (see m68kcpu.h) */
-               m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR));
-               if(REG_PC == REG_PPC)
-                       USE_ALL_CYCLES();
+// TODO: review this...
+               m68ki_exception_illegal();
+//             m68ki_trace_t0();                                  /* auto-disable (see m68kcpu.h) */
+//             m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR));
+//             if(REG_PC == REG_PPC)
+//                     USE_ALL_CYCLES();
        }
 }
 
@@ -3215,7 +3248,7 @@ M68KMAKE_OP(bset, 8, r, .)
 M68KMAKE_OP(bset, 32, s, d)
 {
        uint* r_dst = &DY;
-       uint mask = 1 << (OPER_I_8() & 0x1f);
+       uint mask = 1 << (OPER_I_8(state) & 0x1f);
 
        FLAG_Z = *r_dst & mask;
        *r_dst |= mask;
@@ -3224,7 +3257,7 @@ M68KMAKE_OP(bset, 32, s, d)
 
 M68KMAKE_OP(bset, 8, s, .)
 {
-       uint mask = 1 << (OPER_I_8() & 7);
+       uint mask = 1 << (OPER_I_8(state) & 7);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint src = m68ki_read_8(ea);
 
@@ -3243,7 +3276,7 @@ M68KMAKE_OP(bsr, 8, ., .)
 
 M68KMAKE_OP(bsr, 16, ., .)
 {
-       uint offset = OPER_I_16();
+       uint offset = OPER_I_16(state);
        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
        m68ki_push_32(REG_PC);
        REG_PC -= 2;
@@ -3255,7 +3288,7 @@ M68KMAKE_OP(bsr, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint offset = OPER_I_32();
+               uint offset = OPER_I_32(state);
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                m68ki_push_32(REG_PC);
                REG_PC -= 4;
@@ -3264,9 +3297,11 @@ M68KMAKE_OP(bsr, 32, ., .)
        }
        else
        {
-               m68ki_trace_t0();                                  /* auto-disable (see m68kcpu.h) */
-               m68ki_push_32(REG_PC);
-               m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR));
+// TODO: review this...
+               m68ki_exception_illegal();
+//             m68ki_trace_t0();                                  /* auto-disable (see m68kcpu.h) */
+//             m68ki_push_32(REG_PC);
+//             m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR));
        }
 }
 
@@ -3285,13 +3320,13 @@ M68KMAKE_OP(btst, 8, r, .)
 
 M68KMAKE_OP(btst, 32, s, d)
 {
-       FLAG_Z = DY & (1 << (OPER_I_8() & 0x1f));
+       FLAG_Z = DY & (1 << (OPER_I_8(state) & 0x1f));
 }
 
 
 M68KMAKE_OP(btst, 8, s, .)
 {
-       uint bit = OPER_I_8() & 7;
+       uint bit = OPER_I_8(state) & 7;
 
        FLAG_Z = M68KMAKE_GET_OPER_AY_8 & (1 << bit);
 }
@@ -3309,7 +3344,7 @@ M68KMAKE_OP(callm, 32, ., .)
 (void)ea;      /* just to avoid an 'unused variable' warning */
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
                return;
        }
        m68ki_exception_illegal();
@@ -3320,7 +3355,7 @@ M68KMAKE_OP(cas, 8, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint ea = M68KMAKE_GET_EA_AY_8;
                uint dest = m68ki_read_8(ea);
                uint* compare = &REG_D[word2 & 7];
@@ -3349,7 +3384,7 @@ M68KMAKE_OP(cas, 16, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint ea = M68KMAKE_GET_EA_AY_16;
                uint dest = m68ki_read_16(ea);
                uint* compare = &REG_D[word2 & 7];
@@ -3378,7 +3413,7 @@ M68KMAKE_OP(cas, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint ea = M68KMAKE_GET_EA_AY_32;
                uint dest = m68ki_read_32(ea);
                uint* compare = &REG_D[word2 & 7];
@@ -3407,7 +3442,7 @@ M68KMAKE_OP(cas2, 16, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_32();
+               uint word2 = OPER_I_32(state);
                uint* compare1 = &REG_D[(word2 >> 16) & 7];
                uint ea1 = REG_DA[(word2 >> 28) & 15];
                uint dest1 = m68ki_read_16(ea1);
@@ -3452,7 +3487,7 @@ M68KMAKE_OP(cas2, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_32();
+               uint word2 = OPER_I_32(state);
                uint* compare1 = &REG_D[(word2 >> 16) & 7];
                uint ea1 = REG_DA[(word2 >> 28) & 15];
                uint dest1 = m68ki_read_32(ea1);
@@ -3579,25 +3614,33 @@ M68KMAKE_OP(chk2cmp2, 8, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15]&0xff;
+               uint word2 = OPER_I_16(state);
+               sint compare = REG_DA[(word2 >> 12) & 15];
+               if(!BIT_F(word2))
+                       compare &= 0xff;
+
                uint ea = EA_PCDI_8();
                sint lower_bound = m68ki_read_pcrel_8(ea);
                sint upper_bound = m68ki_read_pcrel_8(ea + 1);
 
-               if(!BIT_F(word2))
-                       compare = (int32)(int8)compare;
-      
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x80) {
+                       lower_bound = (int32)(int8)lower_bound;
+                       upper_bound = (int32)(int8)upper_bound;
+
+                       if(!BIT_F(word2))
+                               compare = (int32)(int8)compare;
+               }
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
                return;
        }
 
-      
+
        m68ki_exception_illegal();
 }
 
@@ -3606,17 +3649,25 @@ M68KMAKE_OP(chk2cmp2, 8, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15]&0xff;
+               uint word2 = OPER_I_16(state);
+               sint compare = REG_DA[(word2 >> 12) & 15];
+               if(!BIT_F(word2))
+                       compare &= 0xff;
+
                uint ea = EA_PCIX_8();
                sint lower_bound = m68ki_read_pcrel_8(ea);
                sint upper_bound = m68ki_read_pcrel_8(ea + 1);
 
-               if(!BIT_F(word2))
-                       compare = (int32)(int8)compare;
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||, faster operation short circuits
+               if (lower_bound & 0x80) {
+                       lower_bound = (int32)(int8)lower_bound;
+                       upper_bound = (int32)(int8)upper_bound;
+
+                       if(!BIT_F(word2))
+                               compare = (int32)(int8)compare;
+               }
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
@@ -3631,18 +3682,26 @@ M68KMAKE_OP(chk2cmp2, 8, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15]&0xff;
+               uint word2 = OPER_I_16(state);
+               sint compare = REG_DA[(word2 >> 12) & 15];
+               if(!BIT_F(word2))
+                       compare &= 0xff;
+
                uint ea = M68KMAKE_GET_EA_AY_8;
                sint lower_bound = (int8)m68ki_read_8(ea);
                sint upper_bound = (int8)m68ki_read_8(ea + 1);
 
-               if(!BIT_F(word2))
-                       compare = (int32)(int8)compare;
-      
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x80) {
+                       lower_bound = (int32)(int8)lower_bound;
+                       upper_bound = (int32)(int8)upper_bound;
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
+                       if(!BIT_F(word2))
+                               compare = (int32)(int8)compare;
+               }
+
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
@@ -3656,17 +3715,26 @@ M68KMAKE_OP(chk2cmp2, 16, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15]&0xffff;
+               uint word2 = OPER_I_16(state);
+               sint compare = REG_DA[(word2 >> 12) & 15];
+               if(!BIT_F(word2))
+                       compare &= 0xffff;
+
                uint ea = EA_PCDI_16();
                sint lower_bound = (int16)m68ki_read_pcrel_16(ea);
                sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2);
 
-               if(!BIT_F(word2))
-                       compare = (int32)(int16)compare;
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x8000) {
+                       lower_bound = (int32)(int16)lower_bound;
+                       upper_bound = (int32)(int16)upper_bound;
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
+                       if(!BIT_F(word2))
+                               compare = (int32)(int16)compare;
+               }
+
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
@@ -3680,17 +3748,26 @@ M68KMAKE_OP(chk2cmp2, 16, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15]&0xffff;
+               uint word2 = OPER_I_16(state);
+               sint compare = REG_DA[(word2 >> 12) & 15];
+               if(!BIT_F(word2))
+                       compare &= 0xffff;
+
                uint ea = EA_PCIX_16();
                sint lower_bound = (int16)m68ki_read_pcrel_16(ea);
                sint upper_bound = (int16)m68ki_read_pcrel_16(ea + 2);
 
-               if(!BIT_F(word2))
-                       compare = (int32)(int16)compare;
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x8000) {
+                       lower_bound = (int32)(int16)lower_bound;
+                       upper_bound = (int32)(int16)upper_bound;
+
+                       if(!BIT_F(word2))
+                               compare = (int32)(int16)compare;
+               }
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
@@ -3704,17 +3781,26 @@ M68KMAKE_OP(chk2cmp2, 16, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15]&0xffff;
+               uint word2 = OPER_I_16(state);
+               sint compare = REG_DA[(word2 >> 12) & 15];
+               if(!BIT_F(word2))
+                       compare &= 0xffff;
+
                uint ea = M68KMAKE_GET_EA_AY_16;
                sint lower_bound = (int16)m68ki_read_16(ea);
                sint upper_bound = (int16)m68ki_read_16(ea + 2);
 
-               if(!BIT_F(word2))
-                       compare = (int32)(int16)compare;
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x8000) {
+                       lower_bound = (int32)(int16)lower_bound;
+                       upper_bound = (int32)(int16)upper_bound;
+
+                       if(!BIT_F(word2))
+                               compare = (int32)(int16)compare;
+               }
 
-        FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
@@ -3728,16 +3814,22 @@ M68KMAKE_OP(chk2cmp2, 32, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15];
-               uint ea = EA_PCDI_32();
-               sint lower_bound = m68ki_read_pcrel_32(ea);
-               sint upper_bound = m68ki_read_pcrel_32(ea + 4);
+               uint32 word2 = OPER_I_16(state);
+               sint64 compare = REG_DA[(word2 >> 12) & 15];
+               uint32 ea = EA_PCDI_32();
+               sint64 lower_bound = m68ki_read_pcrel_32(ea);
+               sint64 upper_bound = m68ki_read_pcrel_32(ea + 4);
+
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x80000000) {
+                       lower_bound = (int64)(int32)lower_bound;
+                       upper_bound = (int64)(int32)upper_bound;
+                       compare = (int64)(int32)compare;
+               }
 
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
-    
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
                return;
@@ -3750,16 +3842,22 @@ M68KMAKE_OP(chk2cmp2, 32, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
-               sint compare = REG_DA[(word2 >> 12) & 15];
-               uint ea = EA_PCIX_32();
-               sint lower_bound = m68ki_read_32(ea);
-               sint upper_bound = m68ki_read_32(ea + 4);
+               uint32 word2 = OPER_I_16(state);
+               sint64 compare = REG_DA[(word2 >> 12) & 15];
+               uint32 ea = EA_PCIX_32();
+               sint64 lower_bound = m68ki_read_32(ea);
+               sint64 upper_bound = m68ki_read_32(ea + 4);
+
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x80000000) {
+                       lower_bound = (int64)(int32)lower_bound;
+                       upper_bound = (int64)(int32)upper_bound;
+                       compare = (int64)(int32)compare;
+               }
 
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
-    FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
-    
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
                return;
@@ -3771,18 +3869,23 @@ M68KMAKE_OP(chk2cmp2, 32, ., pcix)
 M68KMAKE_OP(chk2cmp2, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
-       {   
-               uint word2 = OPER_I_16();
-               // JFF changed the logic. chk2/cmp2 uses signed values, not unsigned
-               sint compare = REG_DA[(word2 >> 12) & 15];
-               uint ea = M68KMAKE_GET_EA_AY_32;
-               sint lower_bound = m68ki_read_32(ea);
-               sint upper_bound = m68ki_read_32(ea + 4);
+       {
+               uint32 word2 = OPER_I_16(state);
+               sint64 compare = REG_DA[(word2 >> 12) & 15];
+               uint32 ea = M68KMAKE_GET_EA_AY_32;
+               sint64 lower_bound = m68ki_read_32(ea);
+               sint64 upper_bound = m68ki_read_32(ea + 4);
+
+               // for signed compare, the arithmetically smaller value is the lower bound
+               if (lower_bound & 0x80000000) {
+                       lower_bound = (int64)(int32)lower_bound;
+                       upper_bound = (int64)(int32)upper_bound;
+                       compare = (int64)(int32)compare;
+               }
 
-               FLAG_Z = !((upper_bound==compare) || (lower_bound==compare));  // JFF: | => ||
+               FLAG_C = (compare >= lower_bound && compare <= upper_bound) ? CFLAG_CLEAR : CFLAG_SET;
+               FLAG_Z = ((upper_bound == compare) || (lower_bound == compare)) ? 0 : 1;
 
-        FLAG_C = (lower_bound <= upper_bound ? compare < lower_bound || compare > upper_bound : compare > upper_bound || compare < lower_bound) << 8;
-    
                if(COND_CS() && BIT_B(word2))
                                m68ki_exception_trap(EXCEPTION_CHK);
                return;
@@ -3804,7 +3907,11 @@ M68KMAKE_OP(clr, 8, ., d)
 
 M68KMAKE_OP(clr, 8, ., .)
 {
-       m68ki_write_8(M68KMAKE_GET_EA_AY_8, 0);
+       uint32 ea = M68KMAKE_GET_EA_AY_8;
+
+       if(CPU_TYPE_IS_000(CPU_TYPE))
+               m68ki_read_8(ea);   /* the 68000 does a dummy read, the value is discarded */
+       m68ki_write_8(ea, 0);
 
        FLAG_N = NFLAG_CLEAR;
        FLAG_V = VFLAG_CLEAR;
@@ -3826,7 +3933,11 @@ M68KMAKE_OP(clr, 16, ., d)
 
 M68KMAKE_OP(clr, 16, ., .)
 {
-       m68ki_write_16(M68KMAKE_GET_EA_AY_16, 0);
+       uint32 ea = M68KMAKE_GET_EA_AY_16;
+
+       if(CPU_TYPE_IS_000(CPU_TYPE))
+               m68ki_read_16(ea);  /* the 68000 does a dummy read, the value is discarded */
+       m68ki_write_16(ea, 0);
 
        FLAG_N = NFLAG_CLEAR;
        FLAG_V = VFLAG_CLEAR;
@@ -3848,7 +3959,11 @@ M68KMAKE_OP(clr, 32, ., d)
 
 M68KMAKE_OP(clr, 32, ., .)
 {
-       m68ki_write_32(M68KMAKE_GET_EA_AY_32, 0);
+       uint32 ea = M68KMAKE_GET_EA_AY_32;
+
+       if(CPU_TYPE_IS_000(CPU_TYPE))
+               m68ki_read_32(ea);  /* the 68000 does a dummy read, the value is discarded */
+       m68ki_write_32(ea, 0);
 
        FLAG_N = NFLAG_CLEAR;
        FLAG_V = VFLAG_CLEAR;
@@ -4041,7 +4156,7 @@ M68KMAKE_OP(cmpa, 32, ., .)
 
 M68KMAKE_OP(cmpi, 8, ., d)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint dst = MASK_OUT_ABOVE_8(DY);
        uint res = dst - src;
 
@@ -4054,7 +4169,7 @@ M68KMAKE_OP(cmpi, 8, ., d)
 
 M68KMAKE_OP(cmpi, 8, ., .)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint dst = M68KMAKE_GET_OPER_AY_8;
        uint res = dst - src;
 
@@ -4069,8 +4184,8 @@ M68KMAKE_OP(cmpi, 8, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_I_8();
-               uint dst = OPER_PCDI_8();
+               uint src = OPER_I_8(state);
+               uint dst = OPER_PCDI_8(state);
                uint res = dst - src;
 
                FLAG_N = NFLAG_8(res);
@@ -4087,8 +4202,8 @@ M68KMAKE_OP(cmpi, 8, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_I_8();
-               uint dst = OPER_PCIX_8();
+               uint src = OPER_I_8(state);
+               uint dst = OPER_PCIX_8(state);
                uint res = dst - src;
 
                FLAG_N = NFLAG_8(res);
@@ -4103,7 +4218,7 @@ M68KMAKE_OP(cmpi, 8, ., pcix)
 
 M68KMAKE_OP(cmpi, 16, ., d)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint dst = MASK_OUT_ABOVE_16(DY);
        uint res = dst - src;
 
@@ -4116,7 +4231,7 @@ M68KMAKE_OP(cmpi, 16, ., d)
 
 M68KMAKE_OP(cmpi, 16, ., .)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint dst = M68KMAKE_GET_OPER_AY_16;
        uint res = dst - src;
 
@@ -4131,8 +4246,8 @@ M68KMAKE_OP(cmpi, 16, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_I_16();
-               uint dst = OPER_PCDI_16();
+               uint src = OPER_I_16(state);
+               uint dst = OPER_PCDI_16(state);
                uint res = dst - src;
 
                FLAG_N = NFLAG_16(res);
@@ -4149,8 +4264,8 @@ M68KMAKE_OP(cmpi, 16, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_I_16();
-               uint dst = OPER_PCIX_16();
+               uint src = OPER_I_16(state);
+               uint dst = OPER_PCIX_16(state);
                uint res = dst - src;
 
                FLAG_N = NFLAG_16(res);
@@ -4165,7 +4280,7 @@ M68KMAKE_OP(cmpi, 16, ., pcix)
 
 M68KMAKE_OP(cmpi, 32, ., d)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint dst = DY;
        uint res = dst - src;
 
@@ -4179,7 +4294,7 @@ M68KMAKE_OP(cmpi, 32, ., d)
 
 M68KMAKE_OP(cmpi, 32, ., .)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint dst = M68KMAKE_GET_OPER_AY_32;
        uint res = dst - src;
 
@@ -4194,8 +4309,8 @@ M68KMAKE_OP(cmpi, 32, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_I_32();
-               uint dst = OPER_PCDI_32();
+               uint src = OPER_I_32(state);
+               uint dst = OPER_PCDI_32(state);
                uint res = dst - src;
 
                FLAG_N = NFLAG_32(res);
@@ -4212,8 +4327,8 @@ M68KMAKE_OP(cmpi, 32, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_I_32();
-               uint dst = OPER_PCIX_32();
+               uint src = OPER_I_32(state);
+               uint dst = OPER_PCIX_32(state);
                uint res = dst - src;
 
                FLAG_N = NFLAG_32(res);
@@ -4228,8 +4343,8 @@ M68KMAKE_OP(cmpi, 32, ., pcix)
 
 M68KMAKE_OP(cmpm, 8, ., ax7)
 {
-       uint src = OPER_AY_PI_8();
-       uint dst = OPER_A7_PI_8();
+       uint src = OPER_AY_PI_8(state);
+       uint dst = OPER_A7_PI_8(state);
        uint res = dst - src;
 
        FLAG_N = NFLAG_8(res);
@@ -4241,8 +4356,8 @@ M68KMAKE_OP(cmpm, 8, ., ax7)
 
 M68KMAKE_OP(cmpm, 8, ., ay7)
 {
-       uint src = OPER_A7_PI_8();
-       uint dst = OPER_AX_PI_8();
+       uint src = OPER_A7_PI_8(state);
+       uint dst = OPER_AX_PI_8(state);
        uint res = dst - src;
 
        FLAG_N = NFLAG_8(res);
@@ -4254,8 +4369,8 @@ M68KMAKE_OP(cmpm, 8, ., ay7)
 
 M68KMAKE_OP(cmpm, 8, ., axy7)
 {
-       uint src = OPER_A7_PI_8();
-       uint dst = OPER_A7_PI_8();
+       uint src = OPER_A7_PI_8(state);
+       uint dst = OPER_A7_PI_8(state);
        uint res = dst - src;
 
        FLAG_N = NFLAG_8(res);
@@ -4267,8 +4382,8 @@ M68KMAKE_OP(cmpm, 8, ., axy7)
 
 M68KMAKE_OP(cmpm, 8, ., .)
 {
-       uint src = OPER_AY_PI_8();
-       uint dst = OPER_AX_PI_8();
+       uint src = OPER_AY_PI_8(state);
+       uint dst = OPER_AX_PI_8(state);
        uint res = dst - src;
 
        FLAG_N = NFLAG_8(res);
@@ -4280,8 +4395,8 @@ M68KMAKE_OP(cmpm, 8, ., .)
 
 M68KMAKE_OP(cmpm, 16, ., .)
 {
-       uint src = OPER_AY_PI_16();
-       uint dst = OPER_AX_PI_16();
+       uint src = OPER_AY_PI_16(state);
+       uint dst = OPER_AX_PI_16(state);
        uint res = dst - src;
 
        FLAG_N = NFLAG_16(res);
@@ -4293,8 +4408,8 @@ M68KMAKE_OP(cmpm, 16, ., .)
 
 M68KMAKE_OP(cmpm, 32, ., .)
 {
-       uint src = OPER_AY_PI_32();
-       uint dst = OPER_AX_PI_32();
+       uint src = OPER_AY_PI_32(state);
+       uint dst = OPER_AX_PI_32(state);
        uint res = dst - src;
 
        FLAG_N = NFLAG_32(res);
@@ -4310,7 +4425,7 @@ M68KMAKE_OP(cpbcc, 32, ., .)
        {
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
                return;
        }
        m68ki_exception_1111();
@@ -4323,7 +4438,7 @@ M68KMAKE_OP(cpdbcc, 32, ., .)
        {
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
                return;
        }
        m68ki_exception_1111();
@@ -4332,11 +4447,13 @@ M68KMAKE_OP(cpdbcc, 32, ., .)
 
 M68KMAKE_OP(cpgen, 32, ., .)
 {
+// TODO: what's the condition?
+//     if(HAS_FPU || HAS_PMMU)
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
                return;
        }
        m68ki_exception_1111();
@@ -4349,7 +4466,7 @@ M68KMAKE_OP(cpscc, 32, ., .)
        {
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
                return;
        }
        m68ki_exception_1111();
@@ -4362,14 +4479,23 @@ M68KMAKE_OP(cptrapcc, 32, ., .)
        {
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
         // JFF: unsupported, but at least if the trap doesn't occur, app should still work, so at least PC increase is correct
-        REG_PC += 4;  
+        REG_PC += 4;
                return;
        }
        m68ki_exception_1111();
 }
 
+M68KMAKE_OP(ftrapcc,32, ., .)
+{
+       if(HAS_FPU)
+       {
+               m68881_ftrap(state);
+       } else {
+               m68ki_exception_1111();
+       }
+}
 
 M68KMAKE_OP(dbt, 16, ., .)
 {
@@ -4385,7 +4511,7 @@ M68KMAKE_OP(dbf, 16, ., .)
        *r_dst = MASK_OUT_BELOW_16(*r_dst) | res;
        if(res != 0xffff)
        {
-               uint offset = OPER_I_16();
+               uint offset = OPER_I_16(state);
                REG_PC -= 2;
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                m68ki_branch_16(offset);
@@ -4407,7 +4533,7 @@ M68KMAKE_OP(dbcc, 16, ., .)
                *r_dst = MASK_OUT_BELOW_16(*r_dst) | res;
                if(res != 0xffff)
                {
-                       uint offset = OPER_I_16();
+                       uint offset = OPER_I_16(state);
                        REG_PC -= 2;
                        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                        m68ki_branch_16(offset);
@@ -4431,12 +4557,12 @@ M68KMAKE_OP(divs, 16, ., d)
 
        if(src != 0)
        {
+               FLAG_C = CFLAG_CLEAR;
                if((uint32)*r_dst == 0x80000000 && src == -1)
                {
                        FLAG_Z = 0;
                        FLAG_N = NFLAG_CLEAR;
                        FLAG_V = VFLAG_CLEAR;
-                       FLAG_C = CFLAG_CLEAR;
                        *r_dst = 0;
                        return;
                }
@@ -4449,7 +4575,6 @@ M68KMAKE_OP(divs, 16, ., d)
                        FLAG_Z = quotient;
                        FLAG_N = NFLAG_16(quotient);
                        FLAG_V = VFLAG_CLEAR;
-                       FLAG_C = CFLAG_CLEAR;
                        *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
                        return;
                }
@@ -4469,12 +4594,12 @@ M68KMAKE_OP(divs, 16, ., .)
 
        if(src != 0)
        {
+               FLAG_C = CFLAG_CLEAR;
                if((uint32)*r_dst == 0x80000000 && src == -1)
                {
                        FLAG_Z = 0;
                        FLAG_N = NFLAG_CLEAR;
                        FLAG_V = VFLAG_CLEAR;
-                       FLAG_C = CFLAG_CLEAR;
                        *r_dst = 0;
                        return;
                }
@@ -4487,7 +4612,6 @@ M68KMAKE_OP(divs, 16, ., .)
                        FLAG_Z = quotient;
                        FLAG_N = NFLAG_16(quotient);
                        FLAG_V = VFLAG_CLEAR;
-                       FLAG_C = CFLAG_CLEAR;
                        *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
                        return;
                }
@@ -4505,6 +4629,7 @@ M68KMAKE_OP(divu, 16, ., d)
 
        if(src != 0)
        {
+               FLAG_C = CFLAG_CLEAR;
                uint quotient = *r_dst / src;
                uint remainder = *r_dst % src;
 
@@ -4513,7 +4638,6 @@ M68KMAKE_OP(divu, 16, ., d)
                        FLAG_Z = quotient;
                        FLAG_N = NFLAG_16(quotient);
                        FLAG_V = VFLAG_CLEAR;
-                       FLAG_C = CFLAG_CLEAR;
                        *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
                        return;
                }
@@ -4531,6 +4655,7 @@ M68KMAKE_OP(divu, 16, ., .)
 
        if(src != 0)
        {
+               FLAG_C = CFLAG_CLEAR;
                uint quotient = *r_dst / src;
                uint remainder = *r_dst % src;
 
@@ -4539,7 +4664,6 @@ M68KMAKE_OP(divu, 16, ., .)
                        FLAG_Z = quotient;
                        FLAG_N = NFLAG_16(quotient);
                        FLAG_V = VFLAG_CLEAR;
-                       FLAG_C = CFLAG_CLEAR;
                        *r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));
                        return;
                }
@@ -4556,7 +4680,7 @@ M68KMAKE_OP(divl, 32, ., d)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint64 divisor   = DY;
                uint64 dividend  = 0;
                uint64 quotient  = 0;
@@ -4624,7 +4748,7 @@ M68KMAKE_OP(divl, 32, ., d)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint divisor = DY;
                uint dividend_hi = REG_D[word2 & 7];
                uint dividend_lo = REG_D[(word2 >> 12) & 7];
@@ -4767,7 +4891,7 @@ M68KMAKE_OP(divl, 32, ., .)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint64 divisor = M68KMAKE_GET_OPER_AY_32;
                uint64 dividend  = 0;
                uint64 quotient  = 0;
@@ -4835,7 +4959,7 @@ M68KMAKE_OP(divl, 32, ., .)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint divisor = M68KMAKE_GET_OPER_AY_32;
                uint dividend_hi = REG_D[word2 & 7];
                uint dividend_lo = REG_D[(word2 >> 12) & 7];
@@ -5049,7 +5173,7 @@ M68KMAKE_OP(eor, 32, ., .)
 
 M68KMAKE_OP(eori, 8, ., d)
 {
-       uint res = MASK_OUT_ABOVE_8(DY ^= OPER_I_8());
+       uint res = MASK_OUT_ABOVE_8(DY ^= OPER_I_8(state));
 
        FLAG_N = NFLAG_8(res);
        FLAG_Z = res;
@@ -5060,7 +5184,7 @@ M68KMAKE_OP(eori, 8, ., d)
 
 M68KMAKE_OP(eori, 8, ., .)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint res = src ^ m68ki_read_8(ea);
 
@@ -5075,7 +5199,7 @@ M68KMAKE_OP(eori, 8, ., .)
 
 M68KMAKE_OP(eori, 16, ., d)
 {
-       uint res = MASK_OUT_ABOVE_16(DY ^= OPER_I_16());
+       uint res = MASK_OUT_ABOVE_16(DY ^= OPER_I_16(state));
 
        FLAG_N = NFLAG_16(res);
        FLAG_Z = res;
@@ -5086,7 +5210,7 @@ M68KMAKE_OP(eori, 16, ., d)
 
 M68KMAKE_OP(eori, 16, ., .)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint res = src ^ m68ki_read_16(ea);
 
@@ -5101,7 +5225,7 @@ M68KMAKE_OP(eori, 16, ., .)
 
 M68KMAKE_OP(eori, 32, ., d)
 {
-       uint res = DY ^= OPER_I_32();
+       uint res = DY ^= OPER_I_32(state);
 
        FLAG_N = NFLAG_32(res);
        FLAG_Z = res;
@@ -5112,7 +5236,7 @@ M68KMAKE_OP(eori, 32, ., d)
 
 M68KMAKE_OP(eori, 32, ., .)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint res = src ^ m68ki_read_32(ea);
 
@@ -5127,7 +5251,7 @@ M68KMAKE_OP(eori, 32, ., .)
 
 M68KMAKE_OP(eori, 16, toc, .)
 {
-       m68ki_set_ccr(m68ki_get_ccr() ^ OPER_I_8());
+       m68ki_set_ccr(m68ki_get_ccr() ^ OPER_I_8(state));
 }
 
 
@@ -5135,9 +5259,9 @@ M68KMAKE_OP(eori, 16, tos, .)
 {
        if(FLAG_S)
        {
-               uint src = OPER_I_16();
+               uint src = OPER_I_16(state);
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
-               m68ki_set_sr(m68ki_get_sr() ^ src);
+               m68ki_set_sr(state, m68ki_get_sr() ^ src);
                return;
        }
        m68ki_exception_privilege_violation();
@@ -5227,8 +5351,6 @@ M68KMAKE_OP(jmp, 32, ., .)
 {
        m68ki_jump(M68KMAKE_GET_EA_AY_32);
        m68ki_trace_t0();                                  /* auto-disable (see m68kcpu.h) */
-       if(REG_PC == REG_PPC)
-               USE_ALL_CYCLES();
 }
 
 
@@ -5251,7 +5373,7 @@ M68KMAKE_OP(link, 16, ., a7)
 {
        REG_A[7] -= 4;
        m68ki_write_32(REG_A[7], REG_A[7]);
-       REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16()));
+       REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16(state)));
 }
 
 
@@ -5261,7 +5383,7 @@ M68KMAKE_OP(link, 16, ., .)
 
        m68ki_push_32(*r_dst);
        *r_dst = REG_A[7];
-       REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16()));
+       REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16(state)));
 }
 
 
@@ -5271,7 +5393,7 @@ M68KMAKE_OP(link, 32, ., a7)
        {
                REG_A[7] -= 4;
                m68ki_write_32(REG_A[7], REG_A[7]);
-               REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32());
+               REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32(state));
                return;
        }
        m68ki_exception_illegal();
@@ -5286,7 +5408,7 @@ M68KMAKE_OP(link, 32, ., .)
 
                m68ki_push_32(*r_dst);
                *r_dst = REG_A[7];
-               REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32());
+               REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + OPER_I_32(state));
                return;
        }
        m68ki_exception_illegal();
@@ -6709,7 +6831,7 @@ M68KMAKE_OP(move, 16, tos, d)
 {
        if(FLAG_S)
        {
-               m68ki_set_sr(DY);
+               m68ki_set_sr(state, DY);
                return;
        }
        m68ki_exception_privilege_violation();
@@ -6722,7 +6844,7 @@ M68KMAKE_OP(move, 16, tos, .)
        {
                uint new_sr = M68KMAKE_GET_OPER_AY_16;
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
-               m68ki_set_sr(new_sr);
+               m68ki_set_sr(state, new_sr);
                return;
        }
        m68ki_exception_privilege_violation();
@@ -6758,7 +6880,7 @@ M68KMAKE_OP(movec, 32, cr, .)
        {
                if(FLAG_S)
                {
-                       uint word2 = OPER_I_16();
+                       uint word2 = OPER_I_16(state);
 
                        m68ki_trace_t0();                  /* auto-disable (see m68kcpu.h) */
                        switch (word2 & 0xfff)
@@ -6809,7 +6931,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x003:                             /* TC */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_tc;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6817,7 +6939,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x004:                             /* ITT0 */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_itt0;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6825,7 +6947,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x005:                             /* ITT1 */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_itt1;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6833,7 +6955,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x006:                             /* DTT0 */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_dtt0;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6841,7 +6963,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x007:                             /* DTT1 */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_dtt1;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6849,7 +6971,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x805:                             /* MMUSR */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_sr_040;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6857,7 +6979,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x806:                             /* URP */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_urp_aptr;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6865,7 +6987,7 @@ M68KMAKE_OP(movec, 32, cr, .)
                        case 0x807:                             /* SRP */
                                if(CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       REG_DA[(word2 >> 12) & 15] = m68ki_cpu.mmu_srp_aptr;
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6888,7 +7010,7 @@ M68KMAKE_OP(movec, 32, rc, .)
        {
                if(FLAG_S)
                {
-                       uint word2 = OPER_I_16();
+                       uint word2 = OPER_I_16(state);
 
                        m68ki_trace_t0();                  /* auto-disable (see m68kcpu.h) */
                        switch (word2 & 0xfff)
@@ -6906,7 +7028,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                                        /* 68030 can write all bits except 5-7, 040 can write all */
                                        if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                        {
-                                               REG_CACR = REG_DA[(word2 >> 12) & 15];
+                                               REG_CACR = REG_DA[(word2 >> 12) & 15] & 0xfffffffe;  // Old I cache bit not working on 040
                                        }
                                        else if (CPU_TYPE_IS_030_PLUS(CPU_TYPE))
                                        {
@@ -6916,6 +7038,10 @@ M68KMAKE_OP(movec, 32, rc, .)
                                        {
                                                REG_CACR = REG_DA[(word2 >> 12) & 15] & 0x0f;
                                        }
+
+                                       if (REG_CACR & (M68K_CACR_CI | M68K_CACR_CEI)) {
+                                               m68ki_ic_clear(state);
+                                       }
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6964,7 +7090,16 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x003:                     /* TC */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_tc = REG_DA[(word2 >> 12) & 15];
+
+                                       if (m68ki_cpu.mmu_tc & 0x8000)
+                                       {
+                                               m68ki_cpu.pmmu_enabled = 1;
+                                       }
+                                       else
+                                       {
+                                               m68ki_cpu.pmmu_enabled = 0;
+                                       }
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6972,7 +7107,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x004:                     /* ITT0 */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_itt0 = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6980,7 +7115,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x005:                     /* ITT1 */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_itt1 = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6988,7 +7123,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x006:                     /* DTT0 */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_dtt0 = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -6996,7 +7131,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x007:                     /* DTT1 */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_dtt1 = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -7004,7 +7139,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x805:                     /* MMUSR */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_sr_040 = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -7012,7 +7147,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x806:                     /* URP */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_urp_aptr = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -7020,7 +7155,7 @@ M68KMAKE_OP(movec, 32, rc, .)
                        case 0x807:                     /* SRP */
                                if (CPU_TYPE_IS_040_PLUS(CPU_TYPE))
                                {
-                                       /* TODO */
+                                       m68ki_cpu.mmu_srp_aptr = REG_DA[(word2 >> 12) & 15];
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -7040,7 +7175,7 @@ M68KMAKE_OP(movec, 32, rc, .)
 M68KMAKE_OP(movem, 16, re, pd)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = AY;
        uint count = 0;
 
@@ -7060,7 +7195,7 @@ M68KMAKE_OP(movem, 16, re, pd)
 M68KMAKE_OP(movem, 16, re, .)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint count = 0;
 
@@ -7079,7 +7214,7 @@ M68KMAKE_OP(movem, 16, re, .)
 M68KMAKE_OP(movem, 32, re, pd)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = AY;
        uint count = 0;
 
@@ -7100,7 +7235,7 @@ M68KMAKE_OP(movem, 32, re, pd)
 M68KMAKE_OP(movem, 32, re, .)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint count = 0;
 
@@ -7119,7 +7254,7 @@ M68KMAKE_OP(movem, 32, re, .)
 M68KMAKE_OP(movem, 16, er, pi)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = AY;
        uint count = 0;
 
@@ -7139,7 +7274,7 @@ M68KMAKE_OP(movem, 16, er, pi)
 M68KMAKE_OP(movem, 16, er, pcdi)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = EA_PCDI_16();
        uint count = 0;
 
@@ -7158,7 +7293,7 @@ M68KMAKE_OP(movem, 16, er, pcdi)
 M68KMAKE_OP(movem, 16, er, pcix)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = EA_PCIX_16();
        uint count = 0;
 
@@ -7177,7 +7312,7 @@ M68KMAKE_OP(movem, 16, er, pcix)
 M68KMAKE_OP(movem, 16, er, .)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint count = 0;
 
@@ -7196,7 +7331,7 @@ M68KMAKE_OP(movem, 16, er, .)
 M68KMAKE_OP(movem, 32, er, pi)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = AY;
        uint count = 0;
 
@@ -7216,7 +7351,7 @@ M68KMAKE_OP(movem, 32, er, pi)
 M68KMAKE_OP(movem, 32, er, pcdi)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = EA_PCDI_32();
        uint count = 0;
 
@@ -7235,7 +7370,7 @@ M68KMAKE_OP(movem, 32, er, pcdi)
 M68KMAKE_OP(movem, 32, er, pcix)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = EA_PCIX_32();
        uint count = 0;
 
@@ -7254,7 +7389,7 @@ M68KMAKE_OP(movem, 32, er, pcix)
 M68KMAKE_OP(movem, 32, er, .)
 {
        uint i = 0;
-       uint register_list = OPER_I_16();
+       uint register_list = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint count = 0;
 
@@ -7316,7 +7451,7 @@ M68KMAKE_OP(moves, 8, ., .)
        {
                if(FLAG_S)
                {
-                       uint word2 = OPER_I_16();
+                       uint word2 = OPER_I_16(state);
                        uint ea = M68KMAKE_GET_EA_AY_8;
 
                        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
@@ -7351,7 +7486,7 @@ M68KMAKE_OP(moves, 16, ., .)
        {
                if(FLAG_S)
                {
-                       uint word2 = OPER_I_16();
+                       uint word2 = OPER_I_16(state);
                        uint ea = M68KMAKE_GET_EA_AY_16;
 
                        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
@@ -7386,7 +7521,7 @@ M68KMAKE_OP(moves, 32, ., .)
        {
                if(FLAG_S)
                {
-                       uint word2 = OPER_I_16();
+                       uint word2 = OPER_I_16(state);
                        uint ea = M68KMAKE_GET_EA_AY_32;
 
                        m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
@@ -7423,7 +7558,7 @@ M68KMAKE_OP(moveq, 32, ., .)
 
 M68KMAKE_OP(move16, 32, ., .)
 {
-       uint16 w2 = OPER_I_16();
+       uint16 w2 = OPER_I_16(state);
        int ax = REG_IR & 7;
        int ay = (w2 >> 12) & 7;
 
@@ -7499,7 +7634,7 @@ M68KMAKE_OP(mull, 32, ., d)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint64 src = DY;
                uint64 dst = REG_D[(word2 >> 12) & 7];
                uint64 res;
@@ -7547,7 +7682,7 @@ M68KMAKE_OP(mull, 32, ., d)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint src = DY;
                uint dst = REG_D[(word2 >> 12) & 7];
                uint neg = GET_MSB_32(src ^ dst);
@@ -7623,7 +7758,7 @@ M68KMAKE_OP(mull, 32, ., .)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint64 src = M68KMAKE_GET_OPER_AY_32;
                uint64 dst = REG_D[(word2 >> 12) & 7];
                uint64 res;
@@ -7671,7 +7806,7 @@ M68KMAKE_OP(mull, 32, ., .)
 
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint word2 = OPER_I_16();
+               uint word2 = OPER_I_16(state);
                uint src = M68KMAKE_GET_OPER_AY_32;
                uint dst = REG_D[(word2 >> 12) & 7];
                uint neg = GET_MSB_32(src ^ dst);
@@ -7744,19 +7879,19 @@ M68KMAKE_OP(mull, 32, ., .)
 M68KMAKE_OP(nbcd, 8, ., d)
 {
        uint* r_dst = &DY;
-       uint dst = *r_dst;
-       uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1());
+       uint dst = MASK_OUT_ABOVE_8(*r_dst);
+       uint res = - dst - XFLAG_AS_1();
 
-       if(res != 0x9a)
+       if(res != 0)
        {
-               FLAG_V = ~res; /* Undefined V behavior */
+               FLAG_V = res; /* Undefined V behavior */
 
-               if((res & 0x0f) == 0xa)
-                       res = (res & 0xf0) + 0x10;
+               if(((res|dst) & 0x0f) == 0)
+                       res = (res & 0xf0) + 6;
 
-               res = MASK_OUT_ABOVE_8(res);
+               res = MASK_OUT_ABOVE_8(res + 0x9a);
 
-               FLAG_V &= res; /* Undefined V behavior part II */
+               FLAG_V &= ~res; /* Undefined V behavior part II */
 
                *r_dst = MASK_OUT_BELOW_8(*r_dst) | res;
 
@@ -7778,18 +7913,18 @@ M68KMAKE_OP(nbcd, 8, ., .)
 {
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint dst = m68ki_read_8(ea);
-       uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1());
+       uint res = - dst - XFLAG_AS_1();
 
-       if(res != 0x9a)
+       if(res != 0)
        {
-               FLAG_V = ~res; /* Undefined V behavior */
+               FLAG_V = res; /* Undefined V behavior */
 
-               if((res & 0x0f) == 0xa)
-                       res = (res & 0xf0) + 0x10;
+               if(((res|dst) & 0x0f) == 0)
+                       res = (res & 0xf0) + 6;
 
-               res = MASK_OUT_ABOVE_8(res);
+               res = MASK_OUT_ABOVE_8(res + 0x9a);
 
-               FLAG_V &= res; /* Undefined V behavior part II */
+               FLAG_V &= ~res; /* Undefined V behavior part II */
 
                m68ki_write_8(ea, MASK_OUT_ABOVE_8(res));
 
@@ -8191,7 +8326,7 @@ M68KMAKE_OP(or, 32, re, .)
 
 M68KMAKE_OP(ori, 8, ., d)
 {
-       uint res = MASK_OUT_ABOVE_8((DY |= OPER_I_8()));
+       uint res = MASK_OUT_ABOVE_8((DY |= OPER_I_8(state)));
 
        FLAG_N = NFLAG_8(res);
        FLAG_Z = res;
@@ -8202,7 +8337,7 @@ M68KMAKE_OP(ori, 8, ., d)
 
 M68KMAKE_OP(ori, 8, ., .)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint res = MASK_OUT_ABOVE_8(src | m68ki_read_8(ea));
 
@@ -8217,7 +8352,7 @@ M68KMAKE_OP(ori, 8, ., .)
 
 M68KMAKE_OP(ori, 16, ., d)
 {
-       uint res = MASK_OUT_ABOVE_16(DY |= OPER_I_16());
+       uint res = MASK_OUT_ABOVE_16(DY |= OPER_I_16(state));
 
        FLAG_N = NFLAG_16(res);
        FLAG_Z = res;
@@ -8228,7 +8363,7 @@ M68KMAKE_OP(ori, 16, ., d)
 
 M68KMAKE_OP(ori, 16, ., .)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint res = MASK_OUT_ABOVE_16(src | m68ki_read_16(ea));
 
@@ -8243,7 +8378,7 @@ M68KMAKE_OP(ori, 16, ., .)
 
 M68KMAKE_OP(ori, 32, ., d)
 {
-       uint res = DY |= OPER_I_32();
+       uint res = DY |= OPER_I_32(state);
 
        FLAG_N = NFLAG_32(res);
        FLAG_Z = res;
@@ -8254,7 +8389,7 @@ M68KMAKE_OP(ori, 32, ., d)
 
 M68KMAKE_OP(ori, 32, ., .)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint res = src | m68ki_read_32(ea);
 
@@ -8269,7 +8404,7 @@ M68KMAKE_OP(ori, 32, ., .)
 
 M68KMAKE_OP(ori, 16, toc, .)
 {
-       m68ki_set_ccr(m68ki_get_ccr() | OPER_I_8());
+       m68ki_set_ccr(m68ki_get_ccr() | OPER_I_8(state));
 }
 
 
@@ -8277,9 +8412,9 @@ M68KMAKE_OP(ori, 16, tos, .)
 {
        if(FLAG_S)
        {
-               uint src = OPER_I_16();
+               uint src = OPER_I_16(state);
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
-               m68ki_set_sr(m68ki_get_sr() | src);
+               m68ki_set_sr(state, m68ki_get_sr() | src);
                return;
        }
        m68ki_exception_privilege_violation();
@@ -8291,7 +8426,7 @@ M68KMAKE_OP(pack, 16, rr, .)
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
                /* Note: DX and DY are reversed in Motorola's docs */
-               uint src = DY + OPER_I_16();
+               uint src = DY + OPER_I_16(state);
                uint* r_dst = &DX;
 
                *r_dst = MASK_OUT_BELOW_8(*r_dst) | ((src >> 4) & 0x00f0) | (src & 0x000f);
@@ -8309,9 +8444,9 @@ M68KMAKE_OP(pack, 16, mm, ax7)
                uint ea_src = EA_AY_PD_8();
                uint src = m68ki_read_8(ea_src);
                ea_src = EA_AY_PD_8();
-               src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16();
+               src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16(state);
 
-               m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
+               m68ki_write_8(EA_A7_PD_8(), ((src >> 8) & 0x000f) | ((src<<4) & 0x00f0));
                return;
        }
        m68ki_exception_illegal();
@@ -8326,7 +8461,7 @@ M68KMAKE_OP(pack, 16, mm, ay7)
                uint ea_src = EA_A7_PD_8();
                uint src = m68ki_read_8(ea_src);
                ea_src = EA_A7_PD_8();
-               src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16();
+               src = (src | (m68ki_read_8(ea_src) << 8)) + OPER_I_16(state);
 
                m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
                return;
@@ -8342,7 +8477,7 @@ M68KMAKE_OP(pack, 16, mm, axy7)
                uint ea_src = EA_A7_PD_8();
                uint src = m68ki_read_8(ea_src);
                ea_src = EA_A7_PD_8();
-               src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16();
+               src = (src | (m68ki_read_8(ea_src) << 8)) + OPER_I_16(state);
 
                m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
                return;
@@ -8359,7 +8494,7 @@ M68KMAKE_OP(pack, 16, mm, .)
                uint ea_src = EA_AY_PD_8();
                uint src = m68ki_read_8(ea_src);
                ea_src = EA_AY_PD_8();
-               src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16();
+               src = (src | (m68ki_read_8(ea_src) << 8)) + OPER_I_16(state);
 
                m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
                return;
@@ -8375,11 +8510,21 @@ M68KMAKE_OP(pea, 32, ., .)
        m68ki_push_32(ea);
 }
 
-M68KMAKE_OP(pflush, 32, ., .)
+M68KMAKE_OP(pflusha, 32, ., .)
 {
-       if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU))
+       if (HAS_PMMU)
+       {
+               fprintf(stderr,"68040: unhandled PFLUSHA (ir=%04x)\n", REG_IR);
+               return;
+       }
+       m68ki_exception_1111();
+}
+
+M68KMAKE_OP(pflushan, 32, ., .)
+{
+       if (HAS_PMMU)
        {
-               fprintf(stderr,"68040: unhandled PFLUSH\n");
+               fprintf(stderr,"68040: unhandled PFLUSHAN (ir=%04x)\n", REG_IR);
                return;
        }
        m68ki_exception_1111();
@@ -8389,7 +8534,7 @@ M68KMAKE_OP(pmmu, 32, ., .)
 {
        if ((CPU_TYPE_IS_EC020_PLUS(CPU_TYPE)) && (HAS_PMMU))
        {
-               m68881_mmu_ops();
+               void m68851_mmu_ops(m68ki_cpu_core *state);
        }
        else
        {
@@ -9190,7 +9335,7 @@ M68KMAKE_OP(rtd, 32, ., .)
                uint new_pc = m68ki_pull_32();
 
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
-               REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16()));
+               REG_A[7] = MASK_OUT_ABOVE_32(REG_A[7] + MAKE_INT_16(OPER_I_16(state)));
                m68ki_jump(new_pc);
                return;
        }
@@ -9214,7 +9359,7 @@ M68KMAKE_OP(rte, 32, ., .)
                        new_sr = m68ki_pull_16();
                        new_pc = m68ki_pull_32();
                        m68ki_jump(new_pc);
-                       m68ki_set_sr(new_sr);
+                       m68ki_set_sr(state, new_sr);
 
                        CPU_INSTR_MODE = INSTRUCTION_YES;
                        CPU_RUN_MODE = RUN_MODE_NORMAL;
@@ -9231,7 +9376,7 @@ M68KMAKE_OP(rte, 32, ., .)
                                new_pc = m68ki_pull_32();
                                m68ki_fake_pull_16();   /* format word */
                                m68ki_jump(new_pc);
-                               m68ki_set_sr(new_sr);
+                               m68ki_set_sr(state, new_sr);
                                CPU_INSTR_MODE = INSTRUCTION_YES;
                                CPU_RUN_MODE = RUN_MODE_NORMAL;
                                return;
@@ -9240,26 +9385,23 @@ M68KMAKE_OP(rte, 32, ., .)
                                new_sr = m68ki_pull_16();
                                new_pc = m68ki_pull_32();
                                m68ki_fake_pull_16();   /* format word */
-                               m68ki_fake_pull_16();   /* special status word */
+                               m68ki_jump(new_pc);
+                               m68ki_set_sr(state, new_sr);
+                               CPU_INSTR_MODE = INSTRUCTION_YES;
+                               CPU_RUN_MODE = RUN_MODE_NORMAL;
+                               m68ki_fake_pull_16();  /* special status */
                                m68ki_fake_pull_32();   /* fault address */
-                               m68ki_fake_pull_16();   /* unused/reserved */
-                               m68ki_fake_pull_16();   /* data output buffer */
-                               m68ki_fake_pull_16();   /* unused/reserved */
-                               m68ki_fake_pull_16();   /* data input buffer */
-                               m68ki_fake_pull_16();   /* unused/reserved */
-                               m68ki_fake_pull_16();   /* instruction input buffer */
-                               m68ki_fake_pull_32();   /* internal information, 16 words */
-                               m68ki_fake_pull_32();   /* (actually, we use 8 DWORDs) */
+                               m68ki_fake_pull_32();  /* reserved and data output buffer */
+                               m68ki_fake_pull_32();  /* reserved and data input buffer */
+                               m68ki_fake_pull_32();  /* reserved and instruction input buffer */
+                               m68ki_fake_pull_32();  /* 8 dwords of CPU specific undocumented data */
+                               m68ki_fake_pull_32();
                                m68ki_fake_pull_32();
                                m68ki_fake_pull_32();
                                m68ki_fake_pull_32();
                                m68ki_fake_pull_32();
                                m68ki_fake_pull_32();
                                m68ki_fake_pull_32();
-                               m68ki_jump(new_pc);
-                               m68ki_set_sr(new_sr);
-                               CPU_INSTR_MODE = INSTRUCTION_YES;
-                               CPU_RUN_MODE = RUN_MODE_NORMAL;
                                return;
                        }
                        CPU_INSTR_MODE = INSTRUCTION_YES;
@@ -9279,7 +9421,7 @@ rte_loop:
                                new_pc = m68ki_pull_32();
                                m68ki_fake_pull_16();   /* format word */
                                m68ki_jump(new_pc);
-                               m68ki_set_sr(new_sr);
+                               m68ki_set_sr(state, new_sr);
                                CPU_INSTR_MODE = INSTRUCTION_YES;
                                CPU_RUN_MODE = RUN_MODE_NORMAL;
                                return;
@@ -9287,7 +9429,7 @@ rte_loop:
                                new_sr = m68ki_pull_16();
                                m68ki_fake_pull_32();   /* program counter */
                                m68ki_fake_pull_16();   /* format word */
-                               m68ki_set_sr_noint(new_sr);
+                               m68ki_set_sr_noint(state, new_sr);
                                goto rte_loop;
                        case 2: /* Trap */
                                new_sr = m68ki_pull_16();
@@ -9295,7 +9437,85 @@ rte_loop:
                                m68ki_fake_pull_16();   /* format word */
                                m68ki_fake_pull_32();   /* address */
                                m68ki_jump(new_pc);
-                               m68ki_set_sr(new_sr);
+                               m68ki_set_sr(state, new_sr);
+                               CPU_INSTR_MODE = INSTRUCTION_YES;
+                               CPU_RUN_MODE = RUN_MODE_NORMAL;
+                               return;
+                       case 7: /* 68040 access error */
+                               new_sr = m68ki_pull_16();
+                               new_pc = m68ki_pull_32();
+                               m68ki_fake_pull_16();   /* $06: format word */
+                               m68ki_fake_pull_32();   /* $08: effective address */
+                               m68ki_fake_pull_16();   /* $0c: special status word */
+                               m68ki_fake_pull_16();   /* $0e: wb3s */
+                               m68ki_fake_pull_16();   /* $10: wb2s */
+                               m68ki_fake_pull_16();   /* $12: wb1s */
+                               m68ki_fake_pull_32();   /* $14: data fault address */
+                               m68ki_fake_pull_32();   /* $18: wb3a */
+                               m68ki_fake_pull_32();   /* $1c: wb3d */
+                               m68ki_fake_pull_32();   /* $20: wb2a */
+                               m68ki_fake_pull_32();   /* $24: wb2d */
+                               m68ki_fake_pull_32();   /* $28: wb1a */
+                               m68ki_fake_pull_32();   /* $2c: wb1d/pd0 */
+                               m68ki_fake_pull_32();   /* $30: pd1 */
+                               m68ki_fake_pull_32();   /* $34: pd2 */
+                               m68ki_fake_pull_32();   /* $38: pd3 */
+                               m68ki_jump(new_pc);
+                               m68ki_set_sr(state, new_sr);
+                               CPU_INSTR_MODE = INSTRUCTION_YES;
+                               CPU_RUN_MODE = RUN_MODE_NORMAL;
+                               return;
+
+                       case 0x0a: /* Bus Error at instruction boundary */
+                               new_sr = m68ki_pull_16();
+                               new_pc = m68ki_pull_32();
+                               m68ki_fake_pull_16();   /* $06: format word */
+                               m68ki_fake_pull_16();   /* $08: internal register */
+                               m68ki_fake_pull_16();   /* $0a: special status word */
+                               m68ki_fake_pull_16();   /* $0c: instruction pipe stage c */
+                               m68ki_fake_pull_16();   /* $0e: instruction pipe stage b */
+                               m68ki_fake_pull_32();   /* $10: data fault address */
+                               m68ki_fake_pull_32();   /* $14: internal registers */
+                               m68ki_fake_pull_32();   /* $18: data output buffer */
+                               m68ki_fake_pull_32();   /* $1c: internal registers */
+
+                               m68ki_jump(new_pc);
+                               m68ki_set_sr(state, new_sr);
+                               CPU_INSTR_MODE = INSTRUCTION_YES;
+                               CPU_RUN_MODE = RUN_MODE_NORMAL;
+                               return;
+
+                       case 0x0b: /* Bus Error - Instruction Execution in Progress */
+                               new_sr = m68ki_pull_16();
+                               new_pc = m68ki_pull_32();
+                               m68ki_fake_pull_16();   /* $06: format word */
+                               m68ki_fake_pull_16();   /* $08: internal register */
+                               m68ki_fake_pull_16();   /* $0a: special status word */
+                               m68ki_fake_pull_16();   /* $0c: instruction pipe stage c */
+                               m68ki_fake_pull_16();   /* $0e: instruction pipe stage b */
+                               m68ki_fake_pull_32();   /* $10: data fault address */
+                               m68ki_fake_pull_32();   /* $14: internal registers */
+                               m68ki_fake_pull_32();   /* $18: data output buffer */
+                               m68ki_fake_pull_32();   /* $1c: internal registers */
+                               m68ki_fake_pull_32();   /* $20:  */
+                               m68ki_fake_pull_32();   /* $24: stage B address */
+                               m68ki_fake_pull_32();   /* $28:  */
+                               m68ki_fake_pull_32();   /* $2c: data input buffer */
+                               m68ki_fake_pull_32();   /* $30:  */
+                               m68ki_fake_pull_16();   /* $34:  */
+                               m68ki_fake_pull_16();   /* $36: version #, internal information */
+                               m68ki_fake_pull_32();   /* $38:  */
+                               m68ki_fake_pull_32();   /* $3c:  */
+                               m68ki_fake_pull_32();   /* $40:  */
+                               m68ki_fake_pull_32();   /* $44:  */
+                               m68ki_fake_pull_32();   /* $48:  */
+                               m68ki_fake_pull_32();   /* $4c:  */
+                               m68ki_fake_pull_32();   /* $50:  */
+                               m68ki_fake_pull_32();   /* $54:  */
+                               m68ki_fake_pull_32();   /* $58:  */
+
+                               m68ki_jump(new_pc);
+                               m68ki_set_sr(state, new_sr);
                                CPU_INSTR_MODE = INSTRUCTION_YES;
                                CPU_RUN_MODE = RUN_MODE_NORMAL;
                                return;
@@ -9317,7 +9537,7 @@ M68KMAKE_OP(rtm, 32, ., .)
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: called unimplemented instruction %04x (%s)\n",
                                         m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC - 2), REG_IR,
-                                        m68k_disassemble_quick(ADDRESS_68K(REG_PC - 2))));
+                                        m68ki_disassemble_quick(ADDRESS_68K(REG_PC - 2),CPU_TYPE)));
                return;
        }
        m68ki_exception_illegal();
@@ -9345,19 +9565,23 @@ M68KMAKE_OP(sbcd, 8, rr, .)
        uint src = DY;
        uint dst = *r_dst;
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
+       uint corf = 0;
 
-       FLAG_V = ~res; /* Undefined V behavior */
-
-       if(res > 9)
-               res -= 6;
+       if(res > 0xf)
+               corf = 6;
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
-       if(FLAG_C)
+       FLAG_V = res; /* Undefined V behavior */
+       if(res > 0xff) {
                res += 0xa0;
+               FLAG_X = FLAG_C = CFLAG_SET;
+       } else if(res < corf)
+               FLAG_X = FLAG_C = CFLAG_SET;
+       else
+               FLAG_N = FLAG_X = FLAG_C = 0;
 
-       res = MASK_OUT_ABOVE_8(res);
+       res = MASK_OUT_ABOVE_8(res - corf);
 
-       FLAG_V &= res; /* Undefined V behavior part II */
+       FLAG_V &= ~res; /* Undefined V behavior part II */
        FLAG_N = NFLAG_8(res); /* Undefined N behavior */
        FLAG_Z |= res;
 
@@ -9367,23 +9591,27 @@ M68KMAKE_OP(sbcd, 8, rr, .)
 
 M68KMAKE_OP(sbcd, 8, mm, ax7)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
+       uint corf = 0;
 
-       FLAG_V = ~res; /* Undefined V behavior */
-
-       if(res > 9)
-               res -= 6;
+       if(res > 0xf)
+               corf = 6;
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
-       if(FLAG_C)
+       FLAG_V = res; /* Undefined V behavior */
+       if(res > 0xff) {
                res += 0xa0;
+               FLAG_X = FLAG_C = CFLAG_SET;
+       } else if(res < corf)
+               FLAG_X = FLAG_C = CFLAG_SET;
+       else
+               FLAG_N = FLAG_X = FLAG_C = 0;
 
-       res = MASK_OUT_ABOVE_8(res);
+       res = MASK_OUT_ABOVE_8(res - corf);
 
-       FLAG_V &= res; /* Undefined V behavior part II */
+       FLAG_V &= ~res; /* Undefined V behavior part II */
        FLAG_N = NFLAG_8(res); /* Undefined N behavior */
        FLAG_Z |= res;
 
@@ -9393,23 +9621,27 @@ M68KMAKE_OP(sbcd, 8, mm, ax7)
 
 M68KMAKE_OP(sbcd, 8, mm, ay7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
+       uint corf = 0;
 
-       FLAG_V = ~res; /* Undefined V behavior */
-
-       if(res > 9)
-               res -= 6;
+       if(res > 0xf)
+               corf = 6;
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
-       if(FLAG_C)
+       FLAG_V = res; /* Undefined V behavior */
+       if(res > 0xff) {
                res += 0xa0;
+               FLAG_X = FLAG_C = CFLAG_SET;
+       } else if(res < corf)
+               FLAG_X = FLAG_C = CFLAG_SET;
+       else
+               FLAG_N = FLAG_X = FLAG_C = 0;
 
-       res = MASK_OUT_ABOVE_8(res);
+       res = MASK_OUT_ABOVE_8(res - corf);
 
-       FLAG_V &= res; /* Undefined V behavior part II */
+       FLAG_V &= ~res; /* Undefined V behavior part II */
        FLAG_N = NFLAG_8(res); /* Undefined N behavior */
        FLAG_Z |= res;
 
@@ -9419,23 +9651,27 @@ M68KMAKE_OP(sbcd, 8, mm, ay7)
 
 M68KMAKE_OP(sbcd, 8, mm, axy7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
+       uint corf = 0;
 
-       FLAG_V = ~res; /* Undefined V behavior */
-
-       if(res > 9)
-               res -= 6;
+       if(res > 0xf)
+               corf = 6;
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
-       if(FLAG_C)
+       FLAG_V = res; /* Undefined V behavior */
+       if(res > 0xff) {
                res += 0xa0;
+               FLAG_X = FLAG_C = CFLAG_SET;
+       } else if(res < corf)
+               FLAG_X = FLAG_C = CFLAG_SET;
+       else
+               FLAG_N = FLAG_X = FLAG_C = 0;
 
-       res = MASK_OUT_ABOVE_8(res);
+       res = MASK_OUT_ABOVE_8(res - corf);
 
-       FLAG_V &= res; /* Undefined V behavior part II */
+       FLAG_V &= ~res; /* Undefined V behavior part II */
        FLAG_N = NFLAG_8(res); /* Undefined N behavior */
        FLAG_Z |= res;
 
@@ -9445,23 +9681,27 @@ M68KMAKE_OP(sbcd, 8, mm, axy7)
 
 M68KMAKE_OP(sbcd, 8, mm, .)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
+       uint corf = 0;
 
-       FLAG_V = ~res; /* Undefined V behavior */
-
-       if(res > 9)
-               res -= 6;
+       if(res > 0xf)
+               corf = 6;
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
-       FLAG_X = FLAG_C = (res > 0x99) << 8;
-       if(FLAG_C)
+       FLAG_V = res; /* Undefined V behavior */
+       if(res > 0xff) {
                res += 0xa0;
+               FLAG_X = FLAG_C = CFLAG_SET;
+       } else if(res < corf)
+               FLAG_X = FLAG_C = CFLAG_SET;
+       else
+               FLAG_N = FLAG_X = FLAG_C = 0;
 
-       res = MASK_OUT_ABOVE_8(res);
+       res = MASK_OUT_ABOVE_8(res - corf);
 
-       FLAG_V &= res; /* Undefined V behavior part II */
+       FLAG_V &= ~res; /* Undefined V behavior part II */
        FLAG_N = NFLAG_8(res); /* Undefined N behavior */
        FLAG_Z |= res;
 
@@ -9515,10 +9755,10 @@ M68KMAKE_OP(stop, 0, ., .)
 {
        if(FLAG_S)
        {
-               uint new_sr = OPER_I_16();
+               uint new_sr = OPER_I_16(state);
                m68ki_trace_t0();                          /* auto-disable (see m68kcpu.h) */
                CPU_STOPPED |= STOP_LEVEL_STOP;
-               m68ki_set_sr(new_sr);
+               m68ki_set_sr(state, new_sr);
                if(m68ki_remaining_cycles >= CYC_INSTRUCTION[REG_IR])
                        m68ki_remaining_cycles = CYC_INSTRUCTION[REG_IR];
                else
@@ -9758,7 +9998,7 @@ M68KMAKE_OP(suba, 32, ., .)
 M68KMAKE_OP(subi, 8, ., d)
 {
        uint* r_dst = &DY;
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint dst = MASK_OUT_ABOVE_8(*r_dst);
        uint res = dst - src;
 
@@ -9773,7 +10013,7 @@ M68KMAKE_OP(subi, 8, ., d)
 
 M68KMAKE_OP(subi, 8, ., .)
 {
-       uint src = OPER_I_8();
+       uint src = OPER_I_8(state);
        uint ea = M68KMAKE_GET_EA_AY_8;
        uint dst = m68ki_read_8(ea);
        uint res = dst - src;
@@ -9790,7 +10030,7 @@ M68KMAKE_OP(subi, 8, ., .)
 M68KMAKE_OP(subi, 16, ., d)
 {
        uint* r_dst = &DY;
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint dst = MASK_OUT_ABOVE_16(*r_dst);
        uint res = dst - src;
 
@@ -9805,7 +10045,7 @@ M68KMAKE_OP(subi, 16, ., d)
 
 M68KMAKE_OP(subi, 16, ., .)
 {
-       uint src = OPER_I_16();
+       uint src = OPER_I_16(state);
        uint ea = M68KMAKE_GET_EA_AY_16;
        uint dst = m68ki_read_16(ea);
        uint res = dst - src;
@@ -9822,7 +10062,7 @@ M68KMAKE_OP(subi, 16, ., .)
 M68KMAKE_OP(subi, 32, ., d)
 {
        uint* r_dst = &DY;
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint dst = *r_dst;
        uint res = dst - src;
 
@@ -9837,7 +10077,7 @@ M68KMAKE_OP(subi, 32, ., d)
 
 M68KMAKE_OP(subi, 32, ., .)
 {
-       uint src = OPER_I_32();
+       uint src = OPER_I_32(state);
        uint ea = M68KMAKE_GET_EA_AY_32;
        uint dst = m68ki_read_32(ea);
        uint res = dst - src;
@@ -10019,7 +10259,7 @@ M68KMAKE_OP(subx, 32, rr, .)
 
 M68KMAKE_OP(subx, 8, mm, ax7)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = dst - src - XFLAG_AS_1();
@@ -10037,7 +10277,7 @@ M68KMAKE_OP(subx, 8, mm, ax7)
 
 M68KMAKE_OP(subx, 8, mm, ay7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = dst - src - XFLAG_AS_1();
@@ -10055,7 +10295,7 @@ M68KMAKE_OP(subx, 8, mm, ay7)
 
 M68KMAKE_OP(subx, 8, mm, axy7)
 {
-       uint src = OPER_A7_PD_8();
+       uint src = OPER_A7_PD_8(state);
        uint ea  = EA_A7_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = dst - src - XFLAG_AS_1();
@@ -10073,7 +10313,7 @@ M68KMAKE_OP(subx, 8, mm, axy7)
 
 M68KMAKE_OP(subx, 8, mm, .)
 {
-       uint src = OPER_AY_PD_8();
+       uint src = OPER_AY_PD_8(state);
        uint ea  = EA_AX_PD_8();
        uint dst = m68ki_read_8(ea);
        uint res = dst - src - XFLAG_AS_1();
@@ -10091,7 +10331,7 @@ M68KMAKE_OP(subx, 8, mm, .)
 
 M68KMAKE_OP(subx, 16, mm, .)
 {
-       uint src = OPER_AY_PD_16();
+       uint src = OPER_AY_PD_16(state);
        uint ea  = EA_AX_PD_16();
        uint dst = m68ki_read_16(ea);
        uint res = dst - src - XFLAG_AS_1();
@@ -10109,7 +10349,7 @@ M68KMAKE_OP(subx, 16, mm, .)
 
 M68KMAKE_OP(subx, 32, mm, .)
 {
-       uint src = OPER_AY_PD_32();
+       uint src = OPER_AY_PD_32(state);
        uint ea  = EA_AX_PD_32();
        uint dst = m68ki_read_32(ea);
        uint res = dst - src - XFLAG_AS_1();
@@ -10194,6 +10434,7 @@ M68KMAKE_OP(trapt, 16, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
+       // TODO: review this... as mame is not using it...
         REG_PC += 2; // JFF else stackframe & return addresses are incorrect
                m68ki_exception_trap(EXCEPTION_TRAPV);  /* HJB 990403 */
                return;
@@ -10206,6 +10447,7 @@ M68KMAKE_OP(trapt, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
+       // TODO: review this... as mame is not using it...
         REG_PC += 4; // JFF else stackframe & return addresses are incorrect
                m68ki_exception_trap(EXCEPTION_TRAPV);  /* HJB 990403 */
                return;
@@ -10262,6 +10504,7 @@ M68KMAKE_OP(trapcc, 16, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
+       // TODO: review this... as mame is not using it...
        REG_PC += 2;  /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */
                if(M68KMAKE_CC)
                {
@@ -10279,6 +10522,7 @@ M68KMAKE_OP(trapcc, 32, ., .)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
+       // TODO: review this... as mame is not using it...
                REG_PC += 4;  /* JFF increase before or 1) stackframe is incorrect 2) RTE address is wrong if trap is taken */
                if(M68KMAKE_CC)
                {
@@ -10327,7 +10571,7 @@ M68KMAKE_OP(tst, 8, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_PCDI_8();
+               uint res = OPER_PCDI_8(state);
 
                FLAG_N = NFLAG_8(res);
                FLAG_Z = res;
@@ -10343,7 +10587,7 @@ M68KMAKE_OP(tst, 8, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_PCIX_8();
+               uint res = OPER_PCIX_8(state);
 
                FLAG_N = NFLAG_8(res);
                FLAG_Z = res;
@@ -10359,7 +10603,7 @@ M68KMAKE_OP(tst, 8, ., i)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_I_8();
+               uint res = OPER_I_8(state);
 
                FLAG_N = NFLAG_8(res);
                FLAG_Z = res;
@@ -10413,7 +10657,7 @@ M68KMAKE_OP(tst, 16, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_PCDI_16();
+               uint res = OPER_PCDI_16(state);
 
                FLAG_N = NFLAG_16(res);
                FLAG_Z = res;
@@ -10429,7 +10673,7 @@ M68KMAKE_OP(tst, 16, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_PCIX_16();
+               uint res = OPER_PCIX_16(state);
 
                FLAG_N = NFLAG_16(res);
                FLAG_Z = res;
@@ -10445,7 +10689,7 @@ M68KMAKE_OP(tst, 16, ., i)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_I_16();
+               uint res = OPER_I_16(state);
 
                FLAG_N = NFLAG_16(res);
                FLAG_Z = res;
@@ -10499,7 +10743,7 @@ M68KMAKE_OP(tst, 32, ., pcdi)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_PCDI_32();
+               uint res = OPER_PCDI_32(state);
 
                FLAG_N = NFLAG_32(res);
                FLAG_Z = res;
@@ -10515,7 +10759,7 @@ M68KMAKE_OP(tst, 32, ., pcix)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_PCIX_32();
+               uint res = OPER_PCIX_32(state);
 
                FLAG_N = NFLAG_32(res);
                FLAG_Z = res;
@@ -10531,7 +10775,7 @@ M68KMAKE_OP(tst, 32, ., i)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint res = OPER_I_32();
+               uint res = OPER_I_32(state);
 
                FLAG_N = NFLAG_32(res);
                FLAG_Z = res;
@@ -10566,7 +10810,7 @@ M68KMAKE_OP(unpk, 16, rr, .)
                uint src = DY;
                uint* r_dst = &DX;
 
-               *r_dst = MASK_OUT_BELOW_16(*r_dst) | (((((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16()) & 0xffff);
+               *r_dst = MASK_OUT_BELOW_16(*r_dst) | (((((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(state)) & 0xffff);
                return;
        }
        m68ki_exception_illegal();
@@ -10578,14 +10822,14 @@ M68KMAKE_OP(unpk, 16, mm, ax7)
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
                /* Note: AX and AY are reversed in Motorola's docs */
-               uint src = OPER_AY_PD_8();
+               uint src = OPER_AY_PD_8(state);
                uint ea_dst;
 
-               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
-               ea_dst = EA_A7_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
+               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(state);
                ea_dst = EA_A7_PD_8();
                m68ki_write_8(ea_dst, src & 0xff);
+               ea_dst = EA_A7_PD_8();
+               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
                return;
        }
        m68ki_exception_illegal();
@@ -10597,14 +10841,14 @@ M68KMAKE_OP(unpk, 16, mm, ay7)
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
                /* Note: AX and AY are reversed in Motorola's docs */
-               uint src = OPER_A7_PD_8();
+               uint src = OPER_A7_PD_8(state);
                uint ea_dst;
 
-               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
-               ea_dst = EA_AX_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
+               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(state);
                ea_dst = EA_AX_PD_8();
                m68ki_write_8(ea_dst, src & 0xff);
+               ea_dst = EA_AX_PD_8();
+               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
                return;
        }
        m68ki_exception_illegal();
@@ -10615,14 +10859,14 @@ M68KMAKE_OP(unpk, 16, mm, axy7)
 {
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
-               uint src = OPER_A7_PD_8();
+               uint src = OPER_A7_PD_8(state);
                uint ea_dst;
 
-               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
-               ea_dst = EA_A7_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
+               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(state);
                ea_dst = EA_A7_PD_8();
                m68ki_write_8(ea_dst, src & 0xff);
+               ea_dst = EA_A7_PD_8();
+               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
                return;
        }
        m68ki_exception_illegal();
@@ -10634,14 +10878,14 @@ M68KMAKE_OP(unpk, 16, mm, .)
        if(CPU_TYPE_IS_EC020_PLUS(CPU_TYPE))
        {
                /* Note: AX and AY are reversed in Motorola's docs */
-               uint src = OPER_AY_PD_8();
+               uint src = OPER_AY_PD_8(state);
                uint ea_dst;
 
-               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
-               ea_dst = EA_AX_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
+               src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16(state);
                ea_dst = EA_AX_PD_8();
                m68ki_write_8(ea_dst, src & 0xff);
+               ea_dst = EA_AX_PD_8();
+               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
                return;
        }
        m68ki_exception_illegal();