@@ -721,11 +721,23 @@ void nes_cpu::ADC(nes_addr_mode addr_mode)
721721void nes_cpu::_ADC (uint8_t val)
722722{
723723 uint8_t old_val = A ();
724- A () = val + A () + get_carry ();
724+ uint8_t new_val = old_val;
725+ bool bit7_overflow = false ;
726+
727+ // FF+FF+1=FF -> need to detect such case by checking for overflow in each step
728+ // However, for FF+80+1=80 -> the sign bit got "rescued" so we should just check final result
729+ new_val += val;
730+ if (new_val < old_val) bit7_overflow = true ;
731+
732+ uint8_t old_val2 = new_val;
733+ new_val += get_carry ();
734+ if (new_val < old_val2) bit7_overflow = true ;
735+
736+ A () = new_val;
725737
726738 // flags
727- set_overflow_flag (is_sign_overflow (old_val, val, A () ));
728- set_carry_flag (old_val > A () || val > A () );
739+ set_overflow_flag (is_sign_overflow (old_val, val, new_val ));
740+ set_carry_flag (bit7_overflow );
729741 calc_alu_flag (A ());
730742}
731743
@@ -803,15 +815,7 @@ void nes_cpu::SBC(nes_addr_mode addr_mode)
803815
804816void nes_cpu::_SBC (uint8_t val)
805817{
806- val = ~val + 1 ; // turn it into a add operand
807- val = val -(1 - get_carry ()); // account for the carry
808- uint8_t old_val = A ();
809- A () = A () + val;
810-
811- // flags
812- set_overflow_flag (is_sign_overflow (old_val, val, A ()));
813- set_carry_flag (A () <= old_val);
814- calc_alu_flag (A ());
818+ _ADC (~val);
815819}
816820
817821// Load Accumulator
@@ -1130,7 +1134,7 @@ void nes_cpu::LSR(nes_addr_mode addr_mode)
11301134 set_carry_flag (val & 0x1 );
11311135
11321136 // @DOCBUG:
1133- // http://obelisk.me.uk/6502/reference.html#ASL incorrectly states ASL detects A == 0
1137+ // http://obelisk.me.uk/6502/reference.html#LSR incorrectly states ASL detects A == 0
11341138 set_zero_flag (new_val == 0 );
11351139 set_negative_flag (new_val & 0x80 );
11361140
@@ -1208,7 +1212,9 @@ void nes_cpu::ROL(nes_addr_mode addr_mode)
12081212
12091213 // flags
12101214 set_carry_flag (val & 0x80 );
1211- set_zero_flag (A () == 0 );
1215+ // @DOCBUG
1216+ // http://obelisk.me.uk/6502/reference.html#ROL incorrectly states zero is set if A == 0
1217+ set_zero_flag (new_val == 0 );
12121218 set_negative_flag (new_val & 0x80 );
12131219
12141220 // cycle count
@@ -1225,7 +1231,10 @@ void nes_cpu::ROR(nes_addr_mode addr_mode)
12251231
12261232 // flags
12271233 set_carry_flag (val & 0x1 );
1228- set_zero_flag (A () == 0 );
1234+
1235+ // @DOCBUG
1236+ // http://obelisk.me.uk/6502/reference.html#ROR incorrectly states zero is set if A == 0
1237+ set_zero_flag (new_val == 0 );
12291238 set_negative_flag (new_val & 0x80 );
12301239
12311240 // cycle count
0 commit comments