68k cores: fix bcd instructions
authornotaz <notasas@gmail.com>
Wed, 20 Sep 2017 20:37:58 +0000 (23:37 +0300)
committernotaz <notasas@gmail.com>
Wed, 20 Sep 2017 20:47:09 +0000 (23:47 +0300)
passing flamewing's test now

Makefile
cpu/cyclone
cpu/fame/famec_opcodes.h
cpu/musashi/m68k_in.c

index ca7dc49..8a95d99 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -217,7 +217,9 @@ pico/cd/gfx_cd.o: CFLAGS += -fno-strict-aliasing
 # on x86, this is reduced by ~300MB when debug info is off (but not on ARM)
 # not using O3 and -fno-expensive-optimizations seems to also help, but you may
 # want to remove this stuff for better performance if your compiler can handle it
+ifndef DEBUG
 cpu/fame/famec.o: CFLAGS += -g0 -O2 -fno-expensive-optimizations
+endif
 
 # random deps
 pico/carthw/svp/compiler.o : cpu/drc/emit_$(ARCH).c
index 66dda84..b889883 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 66dda842eae01f47f5389b931ec9567fb0bbb6a1
+Subproject commit b889883d36b2d247488c82d79d1eaab4dd41d236
index bd2efb0..99ba379 100644 (file)
@@ -16936,18 +16936,20 @@ OPCODE(0x4800)
        u32 adr, res;
        u32 src, dst;
 
-       res = DREGu8((Opcode >> 0) & 7);
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       dst = DREGu8((Opcode >> 0) & 7);
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       DREGu8((Opcode >> 0) & 7) = res;
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               DREGu8((Opcode >> 0) & 7) = res;
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
 RET(6)
 }
@@ -16960,18 +16962,20 @@ OPCODE(0x4810)
 
        adr = AREG((Opcode >> 0) & 7);
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(12)
@@ -16986,18 +16990,20 @@ OPCODE(0x4818)
        adr = AREG((Opcode >> 0) & 7);
        AREG((Opcode >> 0) & 7) += 1;
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(12)
@@ -17012,18 +17018,20 @@ OPCODE(0x4820)
        adr = AREG((Opcode >> 0) & 7) - 1;
        AREG((Opcode >> 0) & 7) = adr;
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(14)
@@ -17038,18 +17046,20 @@ OPCODE(0x4828)
        FETCH_SWORD(adr);
        adr += AREG((Opcode >> 0) & 7);
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(16)
@@ -17064,18 +17074,20 @@ OPCODE(0x4830)
        adr = AREG((Opcode >> 0) & 7);
        DECODE_EXT_WORD
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(18)
@@ -17089,18 +17101,20 @@ OPCODE(0x4838)
 
        FETCH_SWORD(adr);
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(16)
@@ -17114,18 +17128,20 @@ OPCODE(0x4839)
 
        FETCH_LONG(adr);
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(20)
@@ -17140,18 +17156,20 @@ OPCODE(0x481F)
        adr = AREG(7);
        AREG(7) += 2;
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(12)
@@ -17166,18 +17184,20 @@ OPCODE(0x4827)
        adr = AREG(7) - 2;
        AREG(7) = adr;
        PRE_IO
-       READ_BYTE_F(adr, res)
-       res = 0x9a - res - ((flag_X >> M68K_SR_X_SFT) & 1);
+       READ_BYTE_F(adr, dst)
+       res = -dst - ((flag_X >> M68K_SR_X_SFT) & 1);
 
-       if (res != 0x9a)
+       if (res != 0)
        {
-               if ((res & 0x0f) == 0xa) res = (res & 0xf0) + 0x10;
-               res &= 0xFF;
-       WRITE_BYTE_F(adr, res)
+               flag_V = res;
+               if (((res|dst) & 0x0f) == 0) res = (res & 0xf0) + 6;
+               res = (res + 0x9a) & 0xFF;
+               WRITE_BYTE_F(adr, res)
+               flag_V &= ~res;
                flag_NotZ |= res;
                flag_X = flag_C = M68K_SR_C;
        }
-       else flag_X = flag_C = 0;
+       else flag_V = flag_X = flag_C = 0;
        flag_N = res;
        POST_IO
 RET(14)
@@ -26933,19 +26953,19 @@ OPCODE(0x8100)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        src = DREGu8((Opcode >> 0) & 7);
        dst = DREGu8((Opcode >> 9) & 7);
        res = (dst & 0xF) - (src & 0xF) - ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res -= 6;
+       if (res > 0xF) corf = 6;
        res += (dst & 0xF0) - (src & 0xF0);
-       if (res > 0x99)
-       {
-               res += 0xA0;
-               flag_X = flag_C = M68K_SR_C;
-       }
-       else flag_X = flag_C = 0;
-       flag_NotZ |= res & 0xFF;
+       flag_V = res;
+       flag_X = flag_C = (s32)res < (s32)corf ? M68K_SR_C : 0;
+       if (res > 0xff) res += 0xA0;
+       res = (res - corf) & 0xFF;
+       flag_V &= ~res;
+       flag_NotZ |= res;
        flag_N = res;
        DREGu8((Opcode >> 9) & 7) = res;
 RET(6)
@@ -26956,6 +26976,7 @@ OPCODE(0x8108)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG((Opcode >> 0) & 7) - 1;
        AREG((Opcode >> 0) & 7) = adr;
@@ -26965,15 +26986,14 @@ OPCODE(0x8108)
        AREG((Opcode >> 9) & 7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) - (src & 0xF) - ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res -= 6;
+       if (res > 0xF) corf = 6;
        res += (dst & 0xF0) - (src & 0xF0);
-       if (res > 0x99)
-       {
-               res += 0xA0;
-               flag_X = flag_C = M68K_SR_C;
-       }
-       else flag_X = flag_C = 0;
-       flag_NotZ |= res & 0xFF;
+       flag_V = res;
+       flag_X = flag_C = (s32)res < (s32)corf ? M68K_SR_C : 0;
+       if (res > 0xff) res += 0xA0;
+       res = (res - corf) & 0xFF;
+       flag_V &= ~res;
+       flag_NotZ |= res;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
        POST_IO
@@ -26985,6 +27005,7 @@ OPCODE(0x810F)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG(7) - 2;
        AREG(7) = adr;
@@ -26994,15 +27015,14 @@ OPCODE(0x810F)
        AREG((Opcode >> 9) & 7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) - (src & 0xF) - ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res -= 6;
+       if (res > 0xF) corf = 6;
        res += (dst & 0xF0) - (src & 0xF0);
-       if (res > 0x99)
-       {
-               res += 0xA0;
-               flag_X = flag_C = M68K_SR_C;
-       }
-       else flag_X = flag_C = 0;
-       flag_NotZ |= res & 0xFF;
+       flag_V = res;
+       flag_X = flag_C = (s32)res < (s32)corf ? M68K_SR_C : 0;
+       if (res > 0xff) res += 0xA0;
+       res = (res - corf) & 0xFF;
+       flag_V &= ~res;
+       flag_NotZ |= res;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
        POST_IO
@@ -27014,6 +27034,7 @@ OPCODE(0x8F08)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG((Opcode >> 0) & 7) - 1;
        AREG((Opcode >> 0) & 7) = adr;
@@ -27023,15 +27044,14 @@ OPCODE(0x8F08)
        AREG(7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) - (src & 0xF) - ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res -= 6;
+       if (res > 0xF) corf = 6;
        res += (dst & 0xF0) - (src & 0xF0);
-       if (res > 0x99)
-       {
-               res += 0xA0;
-               flag_X = flag_C = M68K_SR_C;
-       }
-       else flag_X = flag_C = 0;
-       flag_NotZ |= res & 0xFF;
+       flag_V = res;
+       flag_X = flag_C = (s32)res < (s32)corf ? M68K_SR_C : 0;
+       if (res > 0xff) res += 0xA0;
+       res = (res - corf) & 0xFF;
+       flag_V &= ~res;
+       flag_NotZ |= res;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
        POST_IO
@@ -27043,6 +27063,7 @@ OPCODE(0x8F0F)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG(7) - 2;
        AREG(7) = adr;
@@ -27052,15 +27073,14 @@ OPCODE(0x8F0F)
        AREG(7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) - (src & 0xF) - ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res -= 6;
+       if (res > 0xF) corf = 6;
        res += (dst & 0xF0) - (src & 0xF0);
-       if (res > 0x99)
-       {
-               res += 0xA0;
-               flag_X = flag_C = M68K_SR_C;
-       }
-       else flag_X = flag_C = 0;
-       flag_NotZ |= res & 0xFF;
+       flag_V = res;
+       flag_X = flag_C = (s32)res < (s32)corf ? M68K_SR_C : 0;
+       if (res > 0xff) res += 0xA0;
+       res = (res - corf) & 0xFF;
+       flag_V &= ~res;
+       flag_NotZ |= res;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
        POST_IO
@@ -34120,18 +34140,22 @@ OPCODE(0xC100)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        src = DREGu8((Opcode >> 0) & 7);
        dst = DREGu8((Opcode >> 9) & 7);
        res = (dst & 0xF) + (src & 0xF) + ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res += 6;
+       if (res > 9) corf = 6;
        res += (dst & 0xF0) + (src & 0xF0);
-       if (res > 0x99)
+       flag_V = ~res;
+       res += corf;
+       if (res > 0x9F)
        {
                res -= 0xA0;
                flag_X = flag_C = M68K_SR_C;
        }
        else flag_X = flag_C = 0;
+       flag_V &= res;
        flag_NotZ |= res & 0xFF;
        flag_N = res;
        DREGu8((Opcode >> 9) & 7) = res;
@@ -34143,6 +34167,7 @@ OPCODE(0xC108)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG((Opcode >> 0) & 7) - 1;
        AREG((Opcode >> 0) & 7) = adr;
@@ -34152,14 +34177,17 @@ OPCODE(0xC108)
        AREG((Opcode >> 9) & 7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) + (src & 0xF) + ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res += 6;
+       if (res > 9) corf = 6;
        res += (dst & 0xF0) + (src & 0xF0);
-       if (res > 0x99)
+       flag_V = ~res;
+       res += corf;
+       if (res > 0x9F)
        {
                res -= 0xA0;
                flag_X = flag_C = M68K_SR_C;
        }
        else flag_X = flag_C = 0;
+       flag_V &= res;
        flag_NotZ |= res & 0xFF;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
@@ -34172,6 +34200,7 @@ OPCODE(0xC10F)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG(7) - 2;
        AREG(7) = adr;
@@ -34181,14 +34210,17 @@ OPCODE(0xC10F)
        AREG((Opcode >> 9) & 7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) + (src & 0xF) + ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res += 6;
+       if (res > 9) corf = 6;
        res += (dst & 0xF0) + (src & 0xF0);
-       if (res > 0x99)
+       flag_V = ~res;
+       res += corf;
+       if (res > 0x9F)
        {
                res -= 0xA0;
                flag_X = flag_C = M68K_SR_C;
        }
        else flag_X = flag_C = 0;
+       flag_V &= res;
        flag_NotZ |= res & 0xFF;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
@@ -34201,6 +34233,7 @@ OPCODE(0xCF08)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG((Opcode >> 0) & 7) - 1;
        AREG((Opcode >> 0) & 7) = adr;
@@ -34210,14 +34243,17 @@ OPCODE(0xCF08)
        AREG(7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) + (src & 0xF) + ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res += 6;
+       if (res > 9) corf = 6;
        res += (dst & 0xF0) + (src & 0xF0);
-       if (res > 0x99)
+       flag_V = ~res;
+       res += corf;
+       if (res > 0x9F)
        {
                res -= 0xA0;
                flag_X = flag_C = M68K_SR_C;
        }
        else flag_X = flag_C = 0;
+       flag_V &= res;
        flag_NotZ |= res & 0xFF;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
@@ -34230,6 +34266,7 @@ OPCODE(0xCF0F)
 {
        u32 adr, res;
        u32 src, dst;
+       u32 corf = 0;
 
        adr = AREG(7) - 2;
        AREG(7) = adr;
@@ -34239,14 +34276,17 @@ OPCODE(0xCF0F)
        AREG(7) = adr;
        READ_BYTE_F(adr, dst)
        res = (dst & 0xF) + (src & 0xF) + ((flag_X >> M68K_SR_X_SFT) & 1);
-       if (res > 9) res += 6;
+       if (res > 9) corf = 6;
        res += (dst & 0xF0) + (src & 0xF0);
-       if (res > 0x99)
+       flag_V = ~res;
+       res += corf;
+       if (res > 0x9F)
        {
                res -= 0xA0;
                flag_X = flag_C = M68K_SR_C;
        }
        else flag_X = flag_C = 0;
+       flag_V &= res;
        flag_NotZ |= res & 0xFF;
        flag_N = res;
        WRITE_BYTE_F(adr, res)
index 5c9cc06..d1756a5 100644 (file)
@@ -918,13 +918,15 @@ M68KMAKE_OP(abcd, 8, rr, .)
        uint src = DY;\r
        uint dst = *r_dst;\r
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();\r
-\r
-       FLAG_V = ~res; /* Undefined V behavior */\r
+       uint corf = 0;\r
 \r
        if(res > 9)\r
-               res += 6;\r
+               corf = 6;\r
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);\r
-       FLAG_X = FLAG_C = (res > 0x99) << 8;\r
+       FLAG_V = ~res; /* Undefined V behavior */\r
+\r
+       res += corf;\r
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;\r
        if(FLAG_C)\r
                res -= 0xa0;\r
 \r
@@ -944,13 +946,15 @@ M68KMAKE_OP(abcd, 8, mm, ax7)
        uint ea  = EA_A7_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();\r
-\r
-       FLAG_V = ~res; /* Undefined V behavior */\r
+       uint corf = 0;\r
 \r
        if(res > 9)\r
-               res += 6;\r
+               corf = 6;\r
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);\r
-       FLAG_X = FLAG_C = (res > 0x99) << 8;\r
+       FLAG_V = ~res; /* Undefined V behavior */\r
+\r
+       res += corf;\r
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;\r
        if(FLAG_C)\r
                res -= 0xa0;\r
 \r
@@ -970,13 +974,15 @@ M68KMAKE_OP(abcd, 8, mm, ay7)
        uint ea  = EA_AX_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();\r
-\r
-       FLAG_V = ~res; /* Undefined V behavior */\r
+       uint corf = 0;\r
 \r
        if(res > 9)\r
-               res += 6;\r
+               corf = 6;\r
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);\r
-       FLAG_X = FLAG_C = (res > 0x99) << 8;\r
+       FLAG_V = ~res; /* Undefined V behavior */\r
+\r
+       res += corf;\r
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;\r
        if(FLAG_C)\r
                res -= 0xa0;\r
 \r
@@ -996,13 +1002,15 @@ M68KMAKE_OP(abcd, 8, mm, axy7)
        uint ea  = EA_A7_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();\r
-\r
-       FLAG_V = ~res; /* Undefined V behavior */\r
+       uint corf = 0;\r
 \r
        if(res > 9)\r
-               res += 6;\r
+               corf = 6;\r
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);\r
-       FLAG_X = FLAG_C = (res > 0x99) << 8;\r
+       FLAG_V = ~res; /* Undefined V behavior */\r
+\r
+       res += corf;\r
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;\r
        if(FLAG_C)\r
                res -= 0xa0;\r
 \r
@@ -1022,13 +1030,15 @@ M68KMAKE_OP(abcd, 8, mm, .)
        uint ea  = EA_AX_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();\r
-\r
-       FLAG_V = ~res; /* Undefined V behavior */\r
+       uint corf = 0;\r
 \r
        if(res > 9)\r
-               res += 6;\r
+               corf = 6;\r
        res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);\r
-       FLAG_X = FLAG_C = (res > 0x99) << 8;\r
+       FLAG_V = ~res; /* Undefined V behavior */\r
+\r
+       res += corf;\r
+       FLAG_X = FLAG_C = (res > 0x9f) << 8;\r
        if(FLAG_C)\r
                res -= 0xa0;\r
 \r
@@ -7794,19 +7804,19 @@ M68KMAKE_OP(mull, 32, ., .)
 M68KMAKE_OP(nbcd, 8, ., d)\r
 {\r
        uint* r_dst = &DY;\r
-       uint dst = *r_dst;\r
-       uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1());\r
+       uint dst = MASK_OUT_ABOVE_8(*r_dst);\r
+       uint res = -dst - XFLAG_AS_1();\r
 \r
-       if(res != 0x9a)\r
+       if(res != 0)\r
        {\r
-               FLAG_V = ~res; /* Undefined V behavior */\r
+               FLAG_V = res; /* Undefined V behavior */\r
 \r
-               if((res & 0x0f) == 0xa)\r
-                       res = (res & 0xf0) + 0x10;\r
+               if(((res|dst) & 0x0f) == 0)\r
+                       res = (res & 0xf0) + 6;\r
 \r
-               res = MASK_OUT_ABOVE_8(res);\r
+               res = MASK_OUT_ABOVE_8(res + 0x9a);\r
 \r
-               FLAG_V &= res; /* Undefined V behavior part II */\r
+               FLAG_V &= ~res; /* Undefined V behavior part II */\r
 \r
                *r_dst = MASK_OUT_BELOW_8(*r_dst) | res;\r
 \r
@@ -7828,18 +7838,18 @@ M68KMAKE_OP(nbcd, 8, ., .)
 {\r
        uint ea = M68KMAKE_GET_EA_AY_8;\r
        uint dst = m68ki_read_8(ea);\r
-       uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1());\r
+       uint res = -dst - XFLAG_AS_1();\r
 \r
-       if(res != 0x9a)\r
+       if(res != 0)\r
        {\r
-               FLAG_V = ~res; /* Undefined V behavior */\r
+               FLAG_V = res; /* Undefined V behavior */\r
 \r
-               if((res & 0x0f) == 0xa)\r
-                       res = (res & 0xf0) + 0x10;\r
+               if(((res|dst) & 0x0f) == 0)\r
+                       res = (res & 0xf0) + 6;\r
 \r
-               res = MASK_OUT_ABOVE_8(res);\r
+               res = MASK_OUT_ABOVE_8(res + 0x9a);\r
 \r
-               FLAG_V &= res; /* Undefined V behavior part II */\r
+               FLAG_V &= ~res; /* Undefined V behavior part II */\r
 \r
                m68ki_write_8(ea, MASK_OUT_ABOVE_8(res));\r
 \r
@@ -9359,26 +9369,26 @@ M68KMAKE_OP(sbcd, 8, rr, .)
        uint src = DY;\r
        uint dst = *r_dst;\r
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();\r
+       uint corf = 0;\r
 \r
-//  FLAG_V = ~res; /* Undefined V behavior */\r
-       FLAG_V = VFLAG_CLEAR;   /* Undefined in Motorola's M68000PM/AD rev.1 and safer to assume cleared. */\r
-\r
-       if(res > 9)\r
-               res -= 6;\r
+       if(res > 0xf)\r
+               corf = 6;\r
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);\r
-       if(res > 0x99)\r
+       FLAG_V = res; /* Undefined V behavior */\r
+       if(res > 0xff)\r
        {\r
                res += 0xa0;\r
                FLAG_X = FLAG_C = CFLAG_SET;\r
-               FLAG_N = NFLAG_SET;     /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */\r
        }\r
+       else if(res < corf)\r
+               FLAG_X = FLAG_C = CFLAG_SET;\r
        else\r
-               FLAG_N = FLAG_X = FLAG_C = 0;\r
+               FLAG_X = FLAG_C = 0;\r
 \r
-       res = MASK_OUT_ABOVE_8(res);\r
+       res = MASK_OUT_ABOVE_8(res - corf);\r
 \r
-//  FLAG_V &= res; /* Undefined V behavior part II */\r
-//  FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
+       FLAG_V &= ~res; /* Undefined V behavior part II */\r
+       FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
        FLAG_Z |= res;\r
 \r
        *r_dst = MASK_OUT_BELOW_8(*r_dst) | res;\r
@@ -9391,26 +9401,26 @@ M68KMAKE_OP(sbcd, 8, mm, ax7)
        uint ea  = EA_A7_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();\r
+       uint corf = 0;\r
 \r
-//  FLAG_V = ~res; /* Undefined V behavior */\r
-       FLAG_V = VFLAG_CLEAR;   /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */\r
-\r
-       if(res > 9)\r
-               res -= 6;\r
+       if(res > 0xf)\r
+               corf = 6;\r
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);\r
-       if(res > 0x99)\r
+       FLAG_V = res; /* Undefined V behavior */\r
+       if(res > 0xff)\r
        {\r
                res += 0xa0;\r
                FLAG_X = FLAG_C = CFLAG_SET;\r
-               FLAG_N = NFLAG_SET;     /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */\r
        }\r
+       else if(res < corf)\r
+               FLAG_X = FLAG_C = CFLAG_SET;\r
        else\r
-               FLAG_N = FLAG_X = FLAG_C = 0;\r
+               FLAG_X = FLAG_C = 0;\r
 \r
-       res = MASK_OUT_ABOVE_8(res);\r
+       res = MASK_OUT_ABOVE_8(res - corf);\r
 \r
-//  FLAG_V &= res; /* Undefined V behavior part II */\r
-//  FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
+       FLAG_V &= ~res; /* Undefined V behavior part II */\r
+       FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
        FLAG_Z |= res;\r
 \r
        m68ki_write_8(ea, res);\r
@@ -9423,26 +9433,26 @@ M68KMAKE_OP(sbcd, 8, mm, ay7)
        uint ea  = EA_AX_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();\r
+       uint corf = 0;\r
 \r
-//  FLAG_V = ~res; /* Undefined V behavior */\r
-       FLAG_V = VFLAG_CLEAR;   /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */\r
-\r
-       if(res > 9)\r
-               res -= 6;\r
+       if(res > 0xf)\r
+               corf = 6;\r
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);\r
-       if(res > 0x99)\r
+       FLAG_V = res; /* Undefined V behavior */\r
+       if(res > 0xff)\r
        {\r
                res += 0xa0;\r
                FLAG_X = FLAG_C = CFLAG_SET;\r
-               FLAG_N = NFLAG_SET;     /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */\r
        }\r
+       else if(res < corf)\r
+               FLAG_X = FLAG_C = CFLAG_SET;\r
        else\r
-               FLAG_N = FLAG_X = FLAG_C = 0;\r
+               FLAG_X = FLAG_C = 0;\r
 \r
-       res = MASK_OUT_ABOVE_8(res);\r
+       res = MASK_OUT_ABOVE_8(res - corf);\r
 \r
-//  FLAG_V &= res; /* Undefined V behavior part II */\r
-//  FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
+       FLAG_V &= ~res; /* Undefined V behavior part II */\r
+       FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
        FLAG_Z |= res;\r
 \r
        m68ki_write_8(ea, res);\r
@@ -9455,26 +9465,26 @@ M68KMAKE_OP(sbcd, 8, mm, axy7)
        uint ea  = EA_A7_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();\r
+       uint corf = 0;\r
 \r
-//  FLAG_V = ~res; /* Undefined V behavior */\r
-       FLAG_V = VFLAG_CLEAR;   /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */\r
-\r
-       if(res > 9)\r
-               res -= 6;\r
+       if(res > 0xf)\r
+               corf = 6;\r
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);\r
-       if(res > 0x99)\r
+       FLAG_V = res; /* Undefined V behavior */\r
+       if(res > 0xff)\r
        {\r
                res += 0xa0;\r
                FLAG_X = FLAG_C = CFLAG_SET;\r
-               FLAG_N = NFLAG_SET;     /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */\r
        }\r
+       else if(res < corf)\r
+               FLAG_X = FLAG_C = CFLAG_SET;\r
        else\r
-               FLAG_N = FLAG_X = FLAG_C = 0;\r
+               FLAG_X = FLAG_C = 0;\r
 \r
-       res = MASK_OUT_ABOVE_8(res);\r
+       res = MASK_OUT_ABOVE_8(res - corf);\r
 \r
-//  FLAG_V &= res; /* Undefined V behavior part II */\r
-//  FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
+       FLAG_V &= ~res; /* Undefined V behavior part II */\r
+       FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
        FLAG_Z |= res;\r
 \r
        m68ki_write_8(ea, res);\r
@@ -9487,26 +9497,26 @@ M68KMAKE_OP(sbcd, 8, mm, .)
        uint ea  = EA_AX_PD_8();\r
        uint dst = m68ki_read_8(ea);\r
        uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();\r
+       uint corf = 0;\r
 \r
-//  FLAG_V = ~res; /* Undefined V behavior */\r
-       FLAG_V = VFLAG_CLEAR;   /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */\r
-\r
-       if(res > 9)\r
-               res -= 6;\r
+       if(res > 0xf)\r
+               corf = 6;\r
        res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);\r
-       if(res > 0x99)\r
+       FLAG_V = res; /* Undefined V behavior */\r
+       if(res > 0xff)\r
        {\r
                res += 0xa0;\r
                FLAG_X = FLAG_C = CFLAG_SET;\r
-               FLAG_N = NFLAG_SET;     /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */\r
        }\r
+       else if(res < corf)\r
+               FLAG_X = FLAG_C = CFLAG_SET;\r
        else\r
-               FLAG_N = FLAG_X = FLAG_C = 0;\r
+               FLAG_X = FLAG_C = 0;\r
 \r
-       res = MASK_OUT_ABOVE_8(res);\r
+       res = MASK_OUT_ABOVE_8(res - corf);\r
 \r
-//  FLAG_V &= res; /* Undefined V behavior part II */\r
-//  FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
+       FLAG_V &= ~res; /* Undefined V behavior part II */\r
+       FLAG_N = NFLAG_8(res); /* Undefined N behavior */\r
        FLAG_Z |= res;\r
 \r
        m68ki_write_8(ea, res);\r