@@ -343,12 +343,18 @@ impl Cpu {
343
343
fn adc ( & mut self , mode : & AddressingMode ) {
344
344
let addr = self . get_operand_address ( mode) ;
345
345
let param = self . mem_read ( addr) ;
346
- let ( new_val, overflow) = self . a . overflowing_add ( param) ;
347
- self . a = new_val;
346
+ let ( mid, overflow) = self . a . overflowing_add ( param) ;
348
347
349
- self . set_zero_and_negative_flags ( new_val) ;
350
- self . set_flag ( Flag :: Carry , overflow) ;
351
- self . set_flag ( Flag :: Overflow , false ) ; // TODO: not implemented -- fix it for snake to work?
348
+ let c = if self . get_flag ( Flag :: Carry ) { 1 } else { 0 } ;
349
+ let ( result, overflow2) = mid. overflowing_add ( c) ;
350
+
351
+ self . set_zero_and_negative_flags ( result) ;
352
+ self . set_flag ( Flag :: Carry , overflow || overflow2) ;
353
+
354
+ let v = ( result ^ self . a ) & ( result ^ param) & 0x80 ;
355
+ self . set_flag ( Flag :: Overflow , v > 0 ) ;
356
+
357
+ self . a = result;
352
358
}
353
359
354
360
/// AND (bitwise AND with accumulator)
@@ -1527,6 +1533,8 @@ mod tests {
1527
1533
1528
1534
#[ test]
1529
1535
fn test_nestest ( ) {
1536
+ let max_known_good_line = 313 ;
1537
+
1530
1538
let program = fs:: read ( "roms/nestest.nes" ) . unwrap ( ) ;
1531
1539
1532
1540
let mut cpu = Cpu :: new ( ) ;
@@ -1552,7 +1560,6 @@ mod tests {
1552
1560
Err ( e) => e. into_inner ( ) ,
1553
1561
} ;
1554
1562
1555
- let max_known_good_line = 230 ;
1556
1563
for ( idx, e) in expected. lines ( ) . enumerate ( ) {
1557
1564
let line_num = idx + 1 ;
1558
1565
if line_num > max_known_good_line {
0 commit comments