void do_sbc(byte abyte)
{
UInt16 tmp = (UInt16)(a - abyte - (c_flag ? 0 : 1));
if (!d_flag)
{
// Binary mode
c_flag = tmp < 0x100;
v_flag = ((a ^ tmp) & 0x80) > 0 && ((a ^ abyte) & 0x80) > 0;
z_flag = n_flag = (byte)tmp;
a = (byte)tmp;
}
else
{
UInt16 al, ah;
// Decimal mode
al = (UInt16)((a & 0x0f) - (abyte & 0x0f) - (c_flag ? 0 : 1)); // Calculate lower nybble
ah = (UInt16)((a >> 4) - (abyte >> 4)); // Calculate upper nybble
if ((al & 0x10) != 0)
{
al -= 6; // BCD fixup for lower nybble
ah--;
}
if ((ah & 0x10) != 0) ah -= 6; // BCD fixup for upper nybble
c_flag = tmp < 0x100; // Set flags
v_flag = ((a ^ tmp) & 0x80) != 0 && ((a ^ abyte) & 0x80) != 0;
z_flag = n_flag = (byte)tmp;
a = (byte)((ah << 4) | (al & 0x0f)); // Compose result
}
}