@@ -48,18 +48,19 @@ pub enum AddressingMode {
48
48
None ,
49
49
Indirect ,
50
50
Relative ,
51
+ Accumulator ,
51
52
}
52
53
53
54
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
54
55
pub enum Flag {
55
- Negative ,
56
- Overflow ,
57
- // Break2,
58
- // Break,
59
- Decimal ,
60
- Interrupt ,
56
+ Carry , // 0th bit
61
57
Zero ,
62
- Carry ,
58
+ Interrupt ,
59
+ Decimal ,
60
+ Break ,
61
+ Break2 ,
62
+ Overflow ,
63
+ Negative , // 7th bit
63
64
}
64
65
65
66
// TODO: restore this later. It's hard-coded to support Snake right now
@@ -186,8 +187,7 @@ impl Cpu {
186
187
let target = self . mem_read_zero_page_wrapping ( base) ; // indirect
187
188
target. wrapping_add ( self . y as u16 ) // indexed
188
189
}
189
- AddressingMode :: None => panic ! ( "mode {:?} is not supported" , mode) ,
190
- AddressingMode :: Relative => panic ! ( "mode {:?} is not supported" , mode) ,
190
+ _ => panic ! ( "mode {:?} is not supported" , mode) ,
191
191
}
192
192
}
193
193
@@ -343,15 +343,20 @@ 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 ( mid, overflow) = self . a . overflowing_add ( param) ;
346
+
347
+ self . adc_helper ( param) ;
348
+ }
349
+
350
+ fn adc_helper ( & mut self , mem_value : u8 ) {
351
+ let ( mid, overflow) = self . a . overflowing_add ( mem_value) ;
347
352
348
353
let c = if self . get_flag ( Flag :: Carry ) { 1 } else { 0 } ;
349
354
let ( result, overflow2) = mid. overflowing_add ( c) ;
350
355
351
356
self . set_zero_and_negative_flags ( result) ;
352
357
self . set_flag ( Flag :: Carry , overflow || overflow2) ;
353
358
354
- let v = ( result ^ self . a ) & ( result ^ param ) & 0x80 ;
359
+ let v = ( result ^ self . a ) & ( result ^ mem_value ) & 0x80 ;
355
360
self . set_flag ( Flag :: Overflow , v > 0 ) ;
356
361
357
362
self . a = result;
@@ -369,8 +374,7 @@ impl Cpu {
369
374
370
375
/// ASL (Arithmetic Shift Left)
371
376
fn asl ( & mut self , mode : & AddressingMode ) {
372
- // I've overloaded the addressing mode idea to handle accumlator variant
373
- if mode == & AddressingMode :: None {
377
+ if mode == & AddressingMode :: Accumulator {
374
378
let old_val = self . a ;
375
379
let new_val = self . a << 1 ;
376
380
@@ -452,14 +456,9 @@ impl Cpu {
452
456
453
457
let ( result, borrow) = val. overflowing_sub ( param) ;
454
458
455
- // let gte = val >= param;
456
459
self . set_flag ( Flag :: Carry , !borrow) ;
457
460
458
- // let eq = val == param;
459
- self . set_flag ( Flag :: Zero , result == 0 ) ;
460
-
461
- // let sign = (param & (1 << 7)) > 0;
462
- self . set_flag ( Flag :: Negative , borrow) ;
461
+ self . set_zero_and_negative_flags ( result) ;
463
462
}
464
463
465
464
/// CMP (CoMPare accumulator)
@@ -567,7 +566,7 @@ impl Cpu {
567
566
let param = self . mem_read ( addr) ;
568
567
569
568
self . x = param;
570
- self . set_zero_and_negative_flags ( self . a ) ;
569
+ self . set_zero_and_negative_flags ( self . x ) ;
571
570
}
572
571
573
572
/// LDY (LoaD Y register)
@@ -576,13 +575,12 @@ impl Cpu {
576
575
let param = self . mem_read ( addr) ;
577
576
578
577
self . y = param;
579
- self . set_zero_and_negative_flags ( self . a ) ;
578
+ self . set_zero_and_negative_flags ( self . y ) ;
580
579
}
581
580
582
581
/// LSR (Logical Shift Right)
583
582
fn lsr ( & mut self , mode : & AddressingMode ) {
584
- // I've overloaded the addressing mode idea to handle accumlator variant
585
- if mode == & AddressingMode :: None {
583
+ if mode == & AddressingMode :: Accumulator {
586
584
let old_val = self . a ;
587
585
let new_val = self . a >> 1 ;
588
586
@@ -617,8 +615,7 @@ impl Cpu {
617
615
618
616
/// ROL (ROtate Left)
619
617
fn rol ( & mut self , mode : & AddressingMode ) {
620
- // I've overloaded the addressing mode idea to handle accumlator variant
621
- if mode == & AddressingMode :: None {
618
+ if mode == & AddressingMode :: Accumulator {
622
619
let old_val = self . a ;
623
620
let new_val = ( self . a << 1 ) + self . get_flag ( Flag :: Carry ) as u8 ;
624
621
@@ -640,8 +637,7 @@ impl Cpu {
640
637
641
638
/// ROR (ROtate Right)
642
639
fn ror ( & mut self , mode : & AddressingMode ) {
643
- // I've overloaded the addressing mode idea to handle accumlator variant
644
- if mode == & AddressingMode :: None {
640
+ if mode == & AddressingMode :: Accumulator {
645
641
let old_val = self . a ;
646
642
let mut new_val = self . a >> 1 ;
647
643
if self . get_flag ( Flag :: Carry ) {
@@ -671,22 +667,16 @@ impl Cpu {
671
667
fn rti ( & mut self ) {
672
668
self . status = self . stack_pop ( ) ;
673
669
self . pc = self . stack_pop_u16 ( ) ;
674
- // self.set_flag(Flag::Break, false);
675
- // self.set_flag(Flag::Break2, true);
670
+ self . set_flag ( Flag :: Break , false ) ;
671
+ self . set_flag ( Flag :: Break2 , true ) ;
676
672
}
677
673
678
674
/// SBC (SuBtract with Carry)
679
675
fn sbc ( & mut self , mode : & AddressingMode ) {
680
676
let addr = self . get_operand_address ( mode) ;
681
677
let param = self . mem_read ( addr) ;
682
- let ( new_val, overflow) = self . a . overflowing_sub ( param) ;
683
- self . a = new_val;
684
678
685
- self . set_zero_and_negative_flags ( new_val) ;
686
- if overflow {
687
- self . set_flag ( Flag :: Carry , false ) ;
688
- }
689
- self . set_flag ( Flag :: Overflow , false ) ; // TODO: not implemented -- fix it for snake to work?
679
+ self . adc_helper ( 255 - param) ;
690
680
}
691
681
692
682
/// STA (STore Accumulator)
@@ -715,7 +705,6 @@ impl Cpu {
715
705
/// TXS (Transfer X to Stack ptr)
716
706
fn txs ( & mut self ) {
717
707
self . sp = self . x ;
718
- self . set_zero_and_negative_flags ( self . sp ) ;
719
708
}
720
709
721
710
/// TSX (Transfer Stack ptr to X)
@@ -777,8 +766,8 @@ impl Cpu {
777
766
Flag :: Zero => 1 ,
778
767
Flag :: Interrupt => 2 ,
779
768
Flag :: Decimal => 3 ,
780
- // Flag::Break => 4,
781
- // Flag::Break2 => 5,
769
+ Flag :: Break => 4 ,
770
+ Flag :: Break2 => 5 ,
782
771
Flag :: Overflow => 6 ,
783
772
Flag :: Negative => 7 ,
784
773
} ;
@@ -799,8 +788,8 @@ impl Cpu {
799
788
Flag :: Zero => 1 ,
800
789
Flag :: Interrupt => 2 ,
801
790
Flag :: Decimal => 3 ,
802
- // Flag::Break => 4,
803
- // Flag::Break2 => 5,
791
+ Flag :: Break => 4 ,
792
+ Flag :: Break2 => 5 ,
804
793
Flag :: Overflow => 6 ,
805
794
Flag :: Negative => 7 ,
806
795
} ;
@@ -830,7 +819,19 @@ impl Cpu {
830
819
}
831
820
AddressingMode :: ZeroPageX => format ! ( "${:02X},X" , param1) ,
832
821
AddressingMode :: ZeroPageY => format ! ( "${:02X},Y" , param1) ,
833
- AddressingMode :: Absolute => format ! ( "${:02X}{:02X}" , param2, param1) ,
822
+ AddressingMode :: Absolute => {
823
+ let hi = ( param2 as u16 ) << 8 ;
824
+ let addr: u16 = hi + ( param1 as u16 ) ;
825
+ match name {
826
+ OpName :: STX | OpName :: LDX | OpName :: LDA => format ! (
827
+ "${:02X}{:02X} = {:02X}" ,
828
+ param2,
829
+ param1,
830
+ self . mem_read( addr)
831
+ ) ,
832
+ _ => format ! ( "${:02X}{:02X}" , param2, param1, ) ,
833
+ }
834
+ }
834
835
AddressingMode :: AbsoluteX => format ! ( "${:02X}{:02X},X" , param2, param1) ,
835
836
AddressingMode :: AbsoluteY => format ! ( "${:02X}{:02X},Y" , param2, param1) ,
836
837
AddressingMode :: IndirectX => {
@@ -857,6 +858,7 @@ impl Cpu {
857
858
( self . pc as isize + 2 + ( param1 as i8 ) as isize ) as u16
858
859
)
859
860
}
861
+ AddressingMode :: Accumulator => format ! ( "A" ) ,
860
862
// AddressingMode::Indirect => todo!(),
861
863
_ => "" . to_string ( ) ,
862
864
} ;
@@ -1533,7 +1535,7 @@ mod tests {
1533
1535
1534
1536
#[ test]
1535
1537
fn test_nestest ( ) {
1536
- let max_known_good_line = 313 ;
1538
+ let max_known_good_line = 1061 ;
1537
1539
1538
1540
let program = fs:: read ( "roms/nestest.nes" ) . unwrap ( ) ;
1539
1541
@@ -1568,8 +1570,10 @@ mod tests {
1568
1570
assert_eq ! (
1569
1571
actual[ idx] ,
1570
1572
e. unwrap( ) . as_str( ) ,
1571
- "first diff found on line = {:?}" ,
1572
- line_num
1573
+ "First diff found on line = {:?}. In context the output was: \n \n {}\n {}\n " ,
1574
+ line_num,
1575
+ if idx == 0 { "n/a" } else { & actual[ idx - 1 ] } ,
1576
+ & actual[ idx]
1573
1577
) ;
1574
1578
}
1575
1579
}
0 commit comments