1
0
mirror of https://github.com/pevans/erc-c.git synced 2024-06-11 05:29:33 +00:00

When carry is set, subtract one fewer, not one more

A subtle misunderstanding... which led to bizarre and unexpected
behavior elsewhere.
This commit is contained in:
Peter Evans 2018-02-26 18:58:35 -06:00
parent 4b4e58089b
commit 30c07df9cb
2 changed files with 6 additions and 6 deletions

View File

@ -209,7 +209,7 @@ DEFINE_INST(sbc)
}
MOS_CARRY_BIT();
SET_RESULT(cpu->A - oper - carry);
SET_RESULT(cpu->A - oper - (carry ? 0 : 1));
// Carry is handled slightly differently in SBC; it's set if the
// value is non-negative, and unset if negative. (It's essentially a
@ -252,7 +252,7 @@ DEFINE_INST(sbc_dec)
// carry is also a factor.
int diff =
((a_msd * 10) + a_lsd) -
((o_msd * 10) + o_lsd) - carry;
((o_msd * 10) + o_lsd) - (carry ? 0 : 1);
// Force C to high to begin with
cpu->P |= MOS_CARRY;

View File

@ -129,12 +129,12 @@ Test(mos6502_arith, sbc)
{
cpu->A = 5;
mos6502_handle_sbc(cpu, 3);
cr_assert_eq(cpu->A, 1);
cr_assert_eq(cpu->A, 2);
cpu->P &= ~MOS_CARRY;
cpu->A = 16;
mos6502_handle_sbc(cpu, 8);
cr_assert_eq(cpu->A, 8);
cr_assert_eq(cpu->A, 7);
}
Test(mos6502_arith, sbc_dec)
@ -142,10 +142,10 @@ Test(mos6502_arith, sbc_dec)
cpu->P = 0;
cpu->A = 0x15;
mos6502_handle_sbc_dec(cpu, 0x6);
cr_assert_eq(cpu->A, 0x9);
cr_assert_eq(cpu->A, 0x8);
cpu->P |= MOS_CARRY;
cpu->A = 0x12;
mos6502_handle_sbc_dec(cpu, 0x2);
cr_assert_eq(cpu->A, 0x9);
cr_assert_eq(cpu->A, 0x10);
}