1
0
mirror of https://github.com/pevans/erc-c.git synced 2025-02-25 14:29:13 +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(); 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 // Carry is handled slightly differently in SBC; it's set if the
// value is non-negative, and unset if negative. (It's essentially a // 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. // carry is also a factor.
int diff = int diff =
((a_msd * 10) + a_lsd) - ((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 // Force C to high to begin with
cpu->P |= MOS_CARRY; cpu->P |= MOS_CARRY;

View File

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