mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-10 21:05:12 +01:00
[Core/CPU] fixed 68k undocumented behaviors for ABCD/SBCD/NBCD instructions (thanks to flamewing for his test ROM)
This commit is contained in:
parent
a62c6f9ffe
commit
5a74df31ee
@ -78,6 +78,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
|||||||
[Core/CPU]
|
[Core/CPU]
|
||||||
---------------
|
---------------
|
||||||
* improved 68k auto-vectored interrupts acknowledge cycle timing accuracy (Bubsy background color corruption during cutscenes)
|
* improved 68k auto-vectored interrupts acknowledge cycle timing accuracy (Bubsy background color corruption during cutscenes)
|
||||||
|
* fixed 68k undocumented behaviors for ABCD/SBCD/NBCD instructions (thanks to flamewing for his test ROM)
|
||||||
* fixed Z80 interrupt duration (Bomb on Basic City music running too fast)
|
* fixed Z80 interrupt duration (Bomb on Basic City music running too fast)
|
||||||
* fixed Z80 SP register initialization on power-on for Master System & Game Gear
|
* fixed Z80 SP register initialization on power-on for Master System & Game Gear
|
||||||
(Ace of Aces, Shadow Dancer, Ecco the Dolphin, Evander Holyfield Real Deal Boxing)
|
(Ace of Aces, Shadow Dancer, Ecco the Dolphin, Evander Holyfield Real Deal Boxing)
|
||||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
Binary file not shown.
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
@ -31,6 +31,8 @@
|
|||||||
- added proper cycle use on reset
|
- added proper cycle use on reset
|
||||||
- added cycle accurate timings for MUL/DIV instructions (thanks to Jorge Cwik !)
|
- added cycle accurate timings for MUL/DIV instructions (thanks to Jorge Cwik !)
|
||||||
- fixed undocumented flags for DIV instructions (Blood Shot)
|
- fixed undocumented flags for DIV instructions (Blood Shot)
|
||||||
|
- fixed undocumented behaviors for ABCD/SBCD/NBCD instructions (thanks to flamewing for his test ROM)
|
||||||
|
- improved auto-vectored interrupts acknowledge cycle timing accuracy
|
||||||
- added MAIN-CPU & SUB-CPU support for Mega CD emulation
|
- added MAIN-CPU & SUB-CPU support for Mega CD emulation
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -143,13 +143,15 @@ static void m68k_op_abcd_8_rr(void)
|
|||||||
uint src = DY;
|
uint src = DY;
|
||||||
uint dst = *r_dst;
|
uint dst = *r_dst;
|
||||||
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
|
||||||
|
|
||||||
if(res > 9)
|
if(res > 9)
|
||||||
res += 6;
|
corf = 6;
|
||||||
res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
|
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)
|
if(FLAG_C)
|
||||||
res -= 0xa0;
|
res -= 0xa0;
|
||||||
|
|
||||||
@ -169,13 +171,15 @@ static void m68k_op_abcd_8_mm_ax7(void)
|
|||||||
uint ea = EA_A7_PD_8();
|
uint ea = EA_A7_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
|
||||||
|
|
||||||
if(res > 9)
|
if(res > 9)
|
||||||
res += 6;
|
corf = 6;
|
||||||
res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
|
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)
|
if(FLAG_C)
|
||||||
res -= 0xa0;
|
res -= 0xa0;
|
||||||
|
|
||||||
@ -195,13 +199,15 @@ static void m68k_op_abcd_8_mm_ay7(void)
|
|||||||
uint ea = EA_AX_PD_8();
|
uint ea = EA_AX_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
|
||||||
|
|
||||||
if(res > 9)
|
if(res > 9)
|
||||||
res += 6;
|
corf = 6;
|
||||||
res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
|
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)
|
if(FLAG_C)
|
||||||
res -= 0xa0;
|
res -= 0xa0;
|
||||||
|
|
||||||
@ -221,13 +227,15 @@ static void m68k_op_abcd_8_mm_axy7(void)
|
|||||||
uint ea = EA_A7_PD_8();
|
uint ea = EA_A7_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
|
||||||
|
|
||||||
if(res > 9)
|
if(res > 9)
|
||||||
res += 6;
|
corf = 6;
|
||||||
res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
|
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)
|
if(FLAG_C)
|
||||||
res -= 0xa0;
|
res -= 0xa0;
|
||||||
|
|
||||||
@ -247,13 +255,15 @@ static void m68k_op_abcd_8_mm(void)
|
|||||||
uint ea = EA_AX_PD_8();
|
uint ea = EA_AX_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
uint res = LOW_NIBBLE(src) + LOW_NIBBLE(dst) + XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
|
||||||
|
|
||||||
if(res > 9)
|
if(res > 9)
|
||||||
res += 6;
|
corf = 6;
|
||||||
res += HIGH_NIBBLE(src) + HIGH_NIBBLE(dst);
|
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)
|
if(FLAG_C)
|
||||||
res -= 0xa0;
|
res -= 0xa0;
|
||||||
|
|
||||||
@ -15846,32 +15856,33 @@ static void m68k_op_nbcd_8_d(void)
|
|||||||
{
|
{
|
||||||
uint* r_dst = &DY;
|
uint* r_dst = &DY;
|
||||||
uint dst = *r_dst;
|
uint dst = *r_dst;
|
||||||
uint res = MASK_OUT_ABOVE_8(0x9a - dst - XFLAG_AS_1());
|
uint res = -dst - XFLAG_AS_1();
|
||||||
|
|
||||||
if(res != 0x9a)
|
if(res)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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;
|
*r_dst = MASK_OUT_BELOW_8(*r_dst) | res;
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -15879,32 +15890,33 @@ static void m68k_op_nbcd_8_ai(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AY_AI_8();
|
uint ea = EA_AY_AI_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -15912,32 +15924,33 @@ static void m68k_op_nbcd_8_pi(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AY_PI_8();
|
uint ea = EA_AY_PI_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -15945,32 +15958,33 @@ static void m68k_op_nbcd_8_pi7(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_A7_PI_8();
|
uint ea = EA_A7_PI_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -15978,32 +15992,33 @@ static void m68k_op_nbcd_8_pd(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AY_PD_8();
|
uint ea = EA_AY_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -16011,32 +16026,33 @@ static void m68k_op_nbcd_8_pd7(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_A7_PD_8();
|
uint ea = EA_A7_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -16044,32 +16060,33 @@ static void m68k_op_nbcd_8_di(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AY_DI_8();
|
uint ea = EA_AY_DI_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -16077,32 +16094,33 @@ static void m68k_op_nbcd_8_ix(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AY_IX_8();
|
uint ea = EA_AY_IX_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -16110,32 +16128,33 @@ static void m68k_op_nbcd_8_aw(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AW_8();
|
uint ea = EA_AW_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -16143,32 +16162,33 @@ static void m68k_op_nbcd_8_al(void)
|
|||||||
{
|
{
|
||||||
uint ea = EA_AL_8();
|
uint ea = EA_AL_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
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)
|
||||||
{
|
{
|
||||||
FLAG_V = ~res; /* Undefined V behavior */
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
if((res & 0x0f) == 0xa)
|
if(((res|dst) & 0x0f) == 0x0)
|
||||||
res = (res & 0xf0) + 0x10;
|
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));
|
m68ki_write_8(ea, res);
|
||||||
|
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
FLAG_C = CFLAG_SET;
|
FLAG_C = CFLAG_SET;
|
||||||
FLAG_X = XFLAG_SET;
|
FLAG_X = XFLAG_SET;
|
||||||
|
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FLAG_V = VFLAG_CLEAR;
|
FLAG_V = VFLAG_CLEAR;
|
||||||
FLAG_C = CFLAG_CLEAR;
|
FLAG_C = CFLAG_CLEAR;
|
||||||
FLAG_X = XFLAG_CLEAR;
|
FLAG_X = XFLAG_CLEAR;
|
||||||
|
FLAG_N = NFLAG_CLEAR;
|
||||||
}
|
}
|
||||||
FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -19736,26 +19756,28 @@ static void m68k_op_sbcd_8_rr(void)
|
|||||||
uint src = DY;
|
uint src = DY;
|
||||||
uint dst = *r_dst;
|
uint dst = *r_dst;
|
||||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
|
|
||||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
if(res > 0xf)
|
||||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to assume cleared. */
|
corf = 6;
|
||||||
|
|
||||||
if(res > 9)
|
|
||||||
res -= 6;
|
|
||||||
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
||||||
if(res > 0x99)
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
|
if(res > 0xff)
|
||||||
{
|
{
|
||||||
res += 0xa0;
|
res += 0xa0;
|
||||||
FLAG_X = FLAG_C = CFLAG_SET;
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */
|
|
||||||
}
|
}
|
||||||
|
else if(res < corf)
|
||||||
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
else
|
else
|
||||||
FLAG_N = FLAG_X = FLAG_C = 0;
|
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_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
|
|
||||||
*r_dst = MASK_OUT_BELOW_8(*r_dst) | res;
|
*r_dst = MASK_OUT_BELOW_8(*r_dst) | res;
|
||||||
@ -19768,26 +19790,27 @@ static void m68k_op_sbcd_8_mm_ax7(void)
|
|||||||
uint ea = EA_A7_PD_8();
|
uint ea = EA_A7_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
|
|
||||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
if(res > 0xf)
|
||||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
corf = 6;
|
||||||
|
|
||||||
if(res > 9)
|
|
||||||
res -= 6;
|
|
||||||
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
||||||
if(res > 0x99)
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
|
if(res > 0xff)
|
||||||
{
|
{
|
||||||
res += 0xa0;
|
res += 0xa0;
|
||||||
FLAG_X = FLAG_C = CFLAG_SET;
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */
|
|
||||||
}
|
}
|
||||||
|
else if(res < corf)
|
||||||
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
else
|
else
|
||||||
FLAG_N = FLAG_X = FLAG_C = 0;
|
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_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
|
|
||||||
m68ki_write_8(ea, res);
|
m68ki_write_8(ea, res);
|
||||||
@ -19800,26 +19823,27 @@ static void m68k_op_sbcd_8_mm_ay7(void)
|
|||||||
uint ea = EA_AX_PD_8();
|
uint ea = EA_AX_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
|
|
||||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
if(res > 0xf)
|
||||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
corf = 6;
|
||||||
|
|
||||||
if(res > 9)
|
|
||||||
res -= 6;
|
|
||||||
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
||||||
if(res > 0x99)
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
|
if(res > 0xff)
|
||||||
{
|
{
|
||||||
res += 0xa0;
|
res += 0xa0;
|
||||||
FLAG_X = FLAG_C = CFLAG_SET;
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */
|
|
||||||
}
|
}
|
||||||
|
else if(res < corf)
|
||||||
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
else
|
else
|
||||||
FLAG_N = FLAG_X = FLAG_C = 0;
|
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_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
|
|
||||||
m68ki_write_8(ea, res);
|
m68ki_write_8(ea, res);
|
||||||
@ -19832,26 +19856,27 @@ static void m68k_op_sbcd_8_mm_axy7(void)
|
|||||||
uint ea = EA_A7_PD_8();
|
uint ea = EA_A7_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
|
|
||||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
if(res > 0xf)
|
||||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
corf = 6;
|
||||||
|
|
||||||
if(res > 9)
|
|
||||||
res -= 6;
|
|
||||||
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
||||||
if(res > 0x99)
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
|
if(res > 0xff)
|
||||||
{
|
{
|
||||||
res += 0xa0;
|
res += 0xa0;
|
||||||
FLAG_X = FLAG_C = CFLAG_SET;
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */
|
|
||||||
}
|
}
|
||||||
|
else if(res < corf)
|
||||||
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
else
|
else
|
||||||
FLAG_N = FLAG_X = FLAG_C = 0;
|
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_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
|
|
||||||
m68ki_write_8(ea, res);
|
m68ki_write_8(ea, res);
|
||||||
@ -19864,26 +19889,27 @@ static void m68k_op_sbcd_8_mm(void)
|
|||||||
uint ea = EA_AX_PD_8();
|
uint ea = EA_AX_PD_8();
|
||||||
uint dst = m68ki_read_8(ea);
|
uint dst = m68ki_read_8(ea);
|
||||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||||
|
uint corf = 0;
|
||||||
|
|
||||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
if(res > 0xf)
|
||||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
corf = 6;
|
||||||
|
|
||||||
if(res > 9)
|
|
||||||
res -= 6;
|
|
||||||
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
res += HIGH_NIBBLE(dst) - HIGH_NIBBLE(src);
|
||||||
if(res > 0x99)
|
FLAG_V = res; /* Undefined V behavior */
|
||||||
|
|
||||||
|
if(res > 0xff)
|
||||||
{
|
{
|
||||||
res += 0xa0;
|
res += 0xa0;
|
||||||
FLAG_X = FLAG_C = CFLAG_SET;
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
FLAG_N = NFLAG_SET; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to follow carry. */
|
|
||||||
}
|
}
|
||||||
|
else if(res < corf)
|
||||||
|
FLAG_X = FLAG_C = CFLAG_SET;
|
||||||
else
|
else
|
||||||
FLAG_N = FLAG_X = FLAG_C = 0;
|
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_N = NFLAG_8(res); /* Undefined N behavior */
|
||||||
FLAG_Z |= res;
|
FLAG_Z |= res;
|
||||||
|
|
||||||
m68ki_write_8(ea, res);
|
m68ki_write_8(ea, res);
|
||||||
|
Loading…
Reference in New Issue
Block a user