]> git.sesse.net Git - pistorm/commitdiff
Bus Error and 68k OPs update (to latest MAME)
authorshanshe <shanshe@gmail.com>
Tue, 13 Apr 2021 08:53:17 +0000 (10:53 +0200)
committershanshe <shanshe@gmail.com>
Tue, 13 Apr 2021 16:31:06 +0000 (18:31 +0200)
m68k_in.c
m68kcpu.c
m68kcpu.h

index 9283892dc99f458f272055e899414b0b3eb0620a..ec2614fb48e84a5c133defa5d21257ed65dcd189 100644 (file)
--- a/m68k_in.c
+++ b/m68k_in.c
@@ -947,13 +947,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;
 
@@ -973,13 +974,14 @@ M68KMAKE_OP(abcd, 8, mm, ax7)
        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;
 
@@ -999,13 +1001,14 @@ M68KMAKE_OP(abcd, 8, mm, ay7)
        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;
 
@@ -1025,13 +1028,14 @@ M68KMAKE_OP(abcd, 8, mm, axy7)
        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;
 
@@ -1051,13 +1055,14 @@ M68KMAKE_OP(abcd, 8, mm, .)
        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;
 
@@ -2508,7 +2513,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);
@@ -2599,7 +2604,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);
@@ -2660,17 +2665,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);
 
@@ -2742,17 +2750,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)
@@ -2839,7 +2850,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)
@@ -2928,13 +2939,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;
 
@@ -2946,11 +2959,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)
                {
@@ -3146,6 +3166,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) */
@@ -3158,8 +3179,9 @@ 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();
 }
 
 
@@ -3169,8 +3191,9 @@ M68KMAKE_OP(bra, 16, ., .)
        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();
 }
 
 
@@ -3182,16 +3205,19 @@ M68KMAKE_OP(bra, 32, ., .)
                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();
        }
 }
 
@@ -3269,9 +3295,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));
        }
 }
 
@@ -3314,7 +3342,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();
@@ -3585,17 +3613,25 @@ 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;
+               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;
 
-    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);
@@ -3612,16 +3648,24 @@ 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;
+               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;
 
-    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);
@@ -3637,17 +3681,25 @@ 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;
+               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);
@@ -3662,16 +3714,25 @@ 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;
+               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);
@@ -3686,16 +3747,25 @@ 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;
+               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;
 
-    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);
@@ -3710,16 +3780,25 @@ 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;
+               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);
@@ -3733,16 +3812,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();
+               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;
@@ -3755,16 +3840,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();
+               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;
@@ -3777,17 +3868,22 @@ 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();
+               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;
@@ -3809,7 +3905,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;
@@ -3831,7 +3931,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;
@@ -3853,7 +3957,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;
@@ -4315,7 +4423,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();
@@ -4328,7 +4436,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();
@@ -4337,11 +4445,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();
@@ -4354,7 +4464,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();
@@ -4367,7 +4477,7 @@ 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;  
                return;
@@ -4445,12 +4555,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;
                }
@@ -4463,7 +4573,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;
                }
@@ -4483,12 +4592,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;
                }
@@ -4501,7 +4610,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;
                }
@@ -4519,6 +4627,7 @@ M68KMAKE_OP(divu, 16, ., d)
 
        if(src != 0)
        {
+               FLAG_C = CFLAG_CLEAR;
                uint quotient = *r_dst / src;
                uint remainder = *r_dst % src;
 
@@ -4527,7 +4636,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;
                }
@@ -4545,6 +4653,7 @@ M68KMAKE_OP(divu, 16, ., .)
 
        if(src != 0)
        {
+               FLAG_C = CFLAG_CLEAR;
                uint quotient = *r_dst / src;
                uint remainder = *r_dst % src;
 
@@ -4553,7 +4662,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;
                }
@@ -5241,8 +5349,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();
 }
 
 
@@ -6920,7 +7026,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))
                                        {
@@ -6930,6 +7036,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();
+                                       }
                                        return;
                                }
                                m68ki_exception_illegal();
@@ -7767,19 +7877,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;
 
@@ -7801,18 +7911,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));
 
@@ -8334,7 +8444,7 @@ M68KMAKE_OP(pack, 16, mm, ax7)
                ea_src = EA_AY_PD_8();
                src = ((src << 8) | m68ki_read_8(ea_src)) + OPER_I_16();
 
-               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();
@@ -8349,7 +8459,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();
 
                m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
                return;
@@ -8365,7 +8475,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();
 
                m68ki_write_8(EA_A7_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
                return;
@@ -8382,7 +8492,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();
 
                m68ki_write_8(EA_AX_PD_8(), ((src >> 4) & 0x00f0) | (src & 0x000f));
                return;
@@ -9273,26 +9383,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(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;
@@ -9327,6 +9434,84 @@ rte_loop:
                                new_pc = m68ki_pull_32();
                                m68ki_fake_pull_16();   /* format word */
                                m68ki_fake_pull_32();   /* address */
+                               m68ki_jump(new_pc);
+                               m68ki_set_sr(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(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(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(new_sr);
                                CPU_INSTR_MODE = INSTRUCTION_YES;
@@ -9350,7 +9535,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();
@@ -9378,19 +9563,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;
 
@@ -9404,19 +9593,23 @@ M68KMAKE_OP(sbcd, 8, mm, ax7)
        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;
 
@@ -9430,19 +9623,23 @@ M68KMAKE_OP(sbcd, 8, mm, ay7)
        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;
 
@@ -9456,19 +9653,23 @@ M68KMAKE_OP(sbcd, 8, mm, axy7)
        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;
 
@@ -9482,19 +9683,23 @@ M68KMAKE_OP(sbcd, 8, mm, .)
        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;
 
@@ -10227,6 +10432,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;
@@ -10239,6 +10445,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;
@@ -10295,6 +10502,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)
                {
@@ -10312,6 +10520,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)
                {
@@ -10616,9 +10825,9 @@ M68KMAKE_OP(unpk, 16, mm, ax7)
 
                src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
                ea_dst = EA_A7_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
-               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();
@@ -10635,9 +10844,9 @@ M68KMAKE_OP(unpk, 16, mm, ay7)
 
                src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
                ea_dst = EA_AX_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
-               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();
@@ -10653,9 +10862,9 @@ M68KMAKE_OP(unpk, 16, mm, axy7)
 
                src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
                ea_dst = EA_A7_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
-               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();
@@ -10672,9 +10881,9 @@ M68KMAKE_OP(unpk, 16, mm, .)
 
                src = (((src << 4) & 0x0f00) | (src & 0x000f)) + OPER_I_16();
                ea_dst = EA_AX_PD_8();
-               m68ki_write_8(ea_dst, (src >> 8) & 0xff);
-               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();
index 4cc48c5f75044fc636e4da876bd9b0a55f939fcf..74f83c84850c4a0bb590675b0264204601caa586 100644 (file)
--- a/m68kcpu.c
+++ b/m68kcpu.c
@@ -990,9 +990,6 @@ int m68k_execute(int num_cycles)
                /* Main loop.  Keep going until we run out of clock cycles */
                do
                {
-#ifdef M68K_BUSERR_THING
-                       int i;
-#endif
                        /* Set tracing accodring to T1. (T0 is done inside instruction) */
                        m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
 
@@ -1006,8 +1003,9 @@ int m68k_execute(int num_cycles)
                        REG_PPC = REG_PC;
 
                        /* Record previous D/A register state (in case of bus error) */
+//#define M68K_BUSERR_THING
 #ifdef M68K_BUSERR_THING
-                       for (i = 15; i >= 0; i--){
+                       for (int i = 15; i >= 0; i--){
                                REG_DA_SAVE[i] = REG_DA[i];
                        }
 #endif
index 923f143b49d2c64c02dcdee6aff4e1e8a0a81a76..680aa714b3678b3c5c02a6b5576488b9a2971fa9 100644 (file)
--- a/m68kcpu.h
+++ b/m68kcpu.h
@@ -43,6 +43,7 @@ extern "C" {
 #include <endian.h>
 
 #include <setjmp.h>
+#include <stdio.h>
 
 /* ======================================================================== */
 /* ==================== ARCHITECTURE-DEPENDANT DEFINES ==================== */
@@ -667,6 +668,7 @@ extern jmp_buf m68ki_aerr_trap;
                        longjmp(m68ki_aerr_trap, 1); \
                }
 #endif
+       #define m68ki_bus_error(ADDR,WRITE_MODE) m68ki_aerr_address=ADDR;m68ki_aerr_write_mode=WRITE_MODE;m68ki_exception_bus_error()
 
        #define m68ki_check_address_error_010_less(ADDR, WRITE_MODE, FC) \
                if (CPU_TYPE_IS_010_LESS(CPU_TYPE)) \
@@ -682,12 +684,12 @@ extern jmp_buf m68ki_aerr_trap;
 /* Logging */
 #if M68K_LOG_ENABLE
        #include <stdio.h>
-       extern FILE* M68K_LOG_FILEHANDLE
+//     extern FILE* M68K_LOG_FILEHANDLE;
        extern const char *const m68ki_cpu_names[];
 
-       #define M68K_DO_LOG(A) if(M68K_LOG_FILEHANDLE) fprintf A
+       #define M68K_DO_LOG(A) do{printf("*************");printf A;}while(0) //if(M68K_LOG_FILEHANDLE) fprintf A
        #if M68K_LOG_1010_1111
-               #define M68K_DO_LOG_EMU(A) if(M68K_LOG_FILEHANDLE) fprintf A
+               #define M68K_DO_LOG_EMU(A) printf A //if(M68K_LOG_FILEHANDLE) fprintf A
        #else
                #define M68K_DO_LOG_EMU(A)
        #endif
@@ -2279,13 +2281,32 @@ static inline void m68ki_exception_address_error(void)
                CPU_STOPPED = STOP_LEVEL_HALT;
                return;
        }
-       CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
 
-       /* Note: This is implemented for 68000 only! */
-       m68ki_stack_frame_buserr(sr);
+       CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET_WSF;
+
+       if (CPU_TYPE_IS_000(CPU_TYPE))
+       {
+               /* Note: This is implemented for 68000 only! */
+               m68ki_stack_frame_buserr(sr);
+       }
+       else if (CPU_TYPE_IS_010(CPU_TYPE))
+       {
+               /* only the 68010 throws this unique type-1000 frame */
+               m68ki_stack_frame_1000(REG_PPC, sr, EXCEPTION_BUS_ERROR);
+       }
+       else if (m68ki_cpu.mmu_tmp_buserror_address == REG_PPC)
+       {
+               m68ki_stack_frame_1010(sr, EXCEPTION_BUS_ERROR, REG_PPC, m68ki_cpu.mmu_tmp_buserror_address);
+       }
+       else
+       {
+               m68ki_stack_frame_1011(sr, EXCEPTION_BUS_ERROR, REG_PPC, m68ki_cpu.mmu_tmp_buserror_address);
+       }
 
        m68ki_jump_vector(EXCEPTION_ADDRESS_ERROR);
 
+       m68ki_cpu.run_mode = RUN_MODE_BERR_AERR_RESET;
+
        /* Use up some clock cycles. Note that we don't need to undo the
        instruction's cycles here as we've longjmp:ed directly from the
        instruction handler without passing the part of the excecute loop