Pass decimal mode tests.

This commit is contained in:
Brandon Wright 2018-10-02 17:16:06 -05:00
parent 8f8ace4054
commit bf12c09a12
1 changed files with 86 additions and 132 deletions

View File

@ -315,57 +315,40 @@ static inline void ADC (uint16 Work16)
{ {
if (CheckDecimal()) if (CheckDecimal())
{ {
uint16 A1 = Registers.A.W & 0x000F; uint32 result;
uint16 A2 = Registers.A.W & 0x00F0; uint32 carry = CheckCarry();
uint16 A3 = Registers.A.W & 0x0F00;
uint32 A4 = Registers.A.W & 0xF000;
uint16 W1 = Work16 & 0x000F;
uint16 W2 = Work16 & 0x00F0;
uint16 W3 = Work16 & 0x0F00;
uint16 W4 = Work16 & 0xF000;
A1 += W1 + CheckCarry(); result = (Registers.A.W & 0x000F) + (Work16 & 0x000F) + carry;
if (A1 > 0x0009) if (result > 0x0009)
{ result += 0x0006;
A1 -= 0x000A; carry = (result > 0x000F);
A1 &= 0x000F;
A2 += 0x0010;
}
A2 += W2; result = (Registers.A.W & 0x00F0) + (Work16 & 0x00F0) + (result & 0x000F) + carry * 0x10;
if (A2 > 0x0090) if (result > 0x009F)
{ result += 0x0060;
A2 -= 0x00A0; carry = (result > 0x00FF);
A2 &= 0x00F0;
A3 += 0x0100;
}
A3 += W3; result = (Registers.A.W & 0x0F00) + (Work16 & 0x0F00) + (result & 0x00FF) + carry * 0x100;
if (A3 > 0x0900) if (result > 0x09FF)
{ result += 0x0600;
A3 -= 0x0A00; carry = (result > 0x0FFF);
A3 &= 0x0F00;
A4 += 0x1000;
}
A4 += W4; result = (Registers.A.W & 0xF000) + (Work16 & 0xF000) + (result & 0x0FFF) + carry * 0x1000;
if (A4 > 0x9000)
{
A4 -= 0xA000;
A4 &= 0xF000;
SetCarry();
}
else
ClearCarry();
uint16 Ans16 = A4 | A3 | A2 | A1; if ((Registers.A.W & 0x8000) == (Work16 & 0x8000) && (Registers.A.W & 0x8000) != (result & 0x8000))
if (~(Registers.A.W ^ Work16) & (Work16 ^ Ans16) & 0x8000)
SetOverflow(); SetOverflow();
else else
ClearOverflow(); ClearOverflow();
Registers.A.W = Ans16; if (result > 0x9FFF)
result += 0x6000;
if (result > 0xFFFF)
SetCarry();
else
ClearCarry();
Registers.A.W = result & 0xFFFF;
SetZN(Registers.A.W); SetZN(Registers.A.W);
} }
else else
@ -388,37 +371,30 @@ static inline void ADC (uint8 Work8)
{ {
if (CheckDecimal()) if (CheckDecimal())
{ {
uint8 A1 = Registers.A.W & 0x0F; uint32 result;
uint16 A2 = Registers.A.W & 0xF0; uint32 carry = CheckCarry();
uint8 W1 = Work8 & 0x0F;
uint8 W2 = Work8 & 0xF0;
A1 += W1 + CheckCarry(); result = (Registers.AL & 0x0F) + (Work8 & 0x0F) + carry;
if (A1 > 0x09) if ( result > 0x09 )
{ result += 0x06;
A1 -= 0x0A; carry = (result > 0x0F);
A1 &= 0x0F;
A2 += 0x10;
}
A2 += W2; result = (Registers.AL & 0xF0) + (Work8 & 0xF0) + (result & 0x0F) + (carry * 0x10);
if (A2 > 0x90)
{
A2 -= 0xA0;
A2 &= 0xF0;
SetCarry();
}
else
ClearCarry();
uint8 Ans8 = A2 | A1; if ((Registers.AL & 0x80) == (Work8 & 0x80) && (Registers.AL & 0x80) != (result & 0x80))
if (~(Registers.AL ^ Work8) & (Work8 ^ Ans8) & 0x80)
SetOverflow(); SetOverflow();
else else
ClearOverflow(); ClearOverflow();
Registers.AL = Ans8; if (result > 0x9F)
result += 0x60;
if (result > 0xFF)
SetCarry();
else
ClearCarry();
Registers.AL = result & 0xFF;
SetZN(Registers.AL); SetZN(Registers.AL);
} }
else else
@ -691,58 +667,42 @@ static inline void SBC (uint16 Work16)
{ {
if (CheckDecimal()) if (CheckDecimal())
{ {
uint16 A1 = Registers.A.W & 0x000F; int result;
uint16 A2 = Registers.A.W & 0x00F0; int carry = CheckCarry();
uint16 A3 = Registers.A.W & 0x0F00;
uint32 A4 = Registers.A.W & 0xF000;
uint16 W1 = Work16 & 0x000F;
uint16 W2 = Work16 & 0x00F0;
uint16 W3 = Work16 & 0x0F00;
uint16 W4 = Work16 & 0xF000;
A1 -= W1 + !CheckCarry(); Work16 ^= 0xFFFF;
A2 -= W2;
A3 -= W3;
A4 -= W4;
if (A1 > 0x000F) result = (Registers.A.W & 0x000F) + (Work16 & 0x000F) + carry;
{ if (result < 0x0010)
A1 += 0x000A; result -= 0x0006;
A1 &= 0x000F; carry = (result > 0x000F);
A2 -= 0x0010;
}
if (A2 > 0x00F0) result = (Registers.A.W & 0x00F0) + (Work16 & 0x00F0) + (result & 0x000F) + carry * 0x10;
{ if (result < 0x0100)
A2 += 0x00A0; result -= 0x0060;
A2 &= 0x00F0; carry = (result > 0x00FF);
A3 -= 0x0100;
}
if (A3 > 0x0F00) result = (Registers.A.W & 0x0F00) + (Work16 & 0x0F00) + (result & 0x00FF) + carry * 0x100;
{ if (result < 0x1000)
A3 += 0x0A00; result -= 0x0600;
A3 &= 0x0F00; carry = (result > 0x0FFF);
A4 -= 0x1000;
}
if (A4 > 0xF000) result = (Registers.A.W & 0xF000) + (Work16 & 0xF000) + (result & 0x0FFF) + carry * 0x1000;
{
A4 += 0xA000;
A4 &= 0xF000;
ClearCarry();
}
else
SetCarry();
uint16 Ans16 = A4 | A3 | A2 | A1; if (((Registers.A.W ^ Work16) & 0x8000) == 0 && ((Registers.A.W ^ result) & 0x8000))
if ((Registers.A.W ^ Work16) & (Registers.A.W ^ Ans16) & 0x8000)
SetOverflow(); SetOverflow();
else else
ClearOverflow(); ClearOverflow();
Registers.A.W = Ans16; if (result < 0x10000)
result -= 0x6000;
if (result > 0xFFFF)
SetCarry();
else
ClearCarry();
Registers.A.W = result & 0xFFFF;
SetZN(Registers.A.W); SetZN(Registers.A.W);
} }
else else
@ -765,38 +725,32 @@ static inline void SBC (uint8 Work8)
{ {
if (CheckDecimal()) if (CheckDecimal())
{ {
uint8 A1 = Registers.A.W & 0x0F; int result;
uint16 A2 = Registers.A.W & 0xF0; int carry = CheckCarry();
uint8 W1 = Work8 & 0x0F;
uint8 W2 = Work8 & 0xF0;
A1 -= W1 + !CheckCarry(); Work8 ^= 0xFF;
A2 -= W2;
if (A1 > 0x0F) result = (Registers.AL & 0x0F) + (Work8 & 0x0F) + carry;
{ if (result < 0x10)
A1 += 0x0A; result -= 0x06;
A1 &= 0x0F; carry = (result > 0x0F);
A2 -= 0x10;
}
if (A2 > 0xF0) result = (Registers.AL & 0xF0) + (Work8 & 0xF0) + (result & 0x0F) + carry * 0x10;
{
A2 += 0xA0;
A2 &= 0xF0;
ClearCarry();
}
else
SetCarry();
uint8 Ans8 = A2 | A1; if ((Registers.AL & 0x80) == (Work8 & 0x80) && (Registers.AL & 0x80) != (result & 0x80))
if ((Registers.AL ^ Work8) & (Registers.AL ^ Ans8) & 0x80)
SetOverflow(); SetOverflow();
else else
ClearOverflow(); ClearOverflow();
Registers.AL = Ans8; if (result < 0x100 )
result -= 0x60;
if (result > 0xFF)
SetCarry();
else
ClearCarry();
Registers.AL = result & 0xFF;
SetZN(Registers.AL); SetZN(Registers.AL);
} }
else else