@@ -204,6 +204,8 @@ impl CPUFlag {
204204
205205#[ cfg( test) ]
206206mod tests {
207+ use std:: fs:: OpenOptions ;
208+
207209 use crate :: cpu:: operations:: Operation ;
208210
209211 use crate :: bus;
@@ -660,6 +662,278 @@ mod tests {
660662 assert_eq ! ( cpu. registers. is_flag_set( CPUFlag :: InterruptDisable ) , true ) ;
661663 }
662664
665+ #[ test]
666+ fn test_cpu_add_mem_to_acc_immediate ( ) {
667+ let opcode: u8 = Operation :: AddMemToAccImm . get_opcode ( ) ;
668+ let value: u8 = 3 ;
669+ let acc_value: u8 = 10 ;
670+ let expected_value: u8 = value + acc_value;
671+
672+ let mut bus = TestBus :: new ( ) ;
673+ bus. write ( 0 , opcode) ;
674+ bus. write ( 1 , value) ;
675+ let mut cpu = CPU :: new ( bus) ;
676+ cpu. registers . a = acc_value;
677+
678+ _test_read_and_decode_operation ( & mut cpu) ;
679+
680+ _test_immediate_read ( & mut cpu) ;
681+
682+ cpu. step ( ) ;
683+
684+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
685+ assert_eq ! (
686+ cpu. current_micro_instruction,
687+ Some ( MicroInstruction :: AddMemoryToAccumulator )
688+ ) ;
689+
690+ assert_eq ! ( cpu. registers. a, expected_value) ;
691+ }
692+
693+ #[ test]
694+ fn test_cpu_add_mem_to_acc_zero_page ( ) {
695+ let opcode: u8 = Operation :: AddMemToAccZeroPage . get_opcode ( ) ;
696+ let value: u8 = 7 ;
697+ let acc_value: u8 = 160 ;
698+ let expected_value: u8 = value + acc_value;
699+ let address: u8 = 0x2A ;
700+
701+ let mut bus = TestBus :: new ( ) ;
702+ bus. write ( 0 , opcode) ;
703+ bus. write ( 1 , address) ;
704+ bus. write ( address as u16 , value) ;
705+ let mut cpu = CPU :: new ( bus) ;
706+ cpu. registers . a = acc_value;
707+
708+ _test_read_and_decode_operation ( & mut cpu) ;
709+
710+ _test_zero_page_read ( & mut cpu) ;
711+
712+ cpu. step ( ) ;
713+
714+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
715+ assert_eq ! (
716+ cpu. current_micro_instruction,
717+ Some ( MicroInstruction :: AddMemoryToAccumulator )
718+ ) ;
719+
720+ assert_eq ! ( cpu. registers. a, expected_value) ;
721+ }
722+
723+ #[ test]
724+ fn test_cpu_add_mem_to_acc_zero_page_x ( ) {
725+ let opcode: u8 = Operation :: AddMemToAccZeroPageX . get_opcode ( ) ;
726+ let value: u8 = 7 ;
727+ let acc_value: u8 = 160 ;
728+ let x_value: u8 = 10 ;
729+ let expected_value: u8 = value + acc_value;
730+ let address: u8 = 0x2A ;
731+ let expected_address: u8 = address + x_value;
732+
733+ let mut bus = TestBus :: new ( ) ;
734+ bus. write ( 0 , opcode) ;
735+ bus. write ( 1 , address) ;
736+ bus. write ( expected_address as u16 , value) ;
737+ let mut cpu = CPU :: new ( bus) ;
738+ cpu. registers . a = acc_value;
739+ cpu. registers . x = x_value;
740+
741+ _test_read_and_decode_operation ( & mut cpu) ;
742+
743+ _test_zero_page_x_read ( & mut cpu) ;
744+
745+ cpu. step ( ) ;
746+
747+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
748+ assert_eq ! (
749+ cpu. current_micro_instruction,
750+ Some ( MicroInstruction :: AddMemoryToAccumulator )
751+ ) ;
752+
753+ assert_eq ! ( cpu. registers. a, expected_value) ;
754+ }
755+
756+ #[ test]
757+ fn test_cpu_add_mem_to_acc_absolute ( ) {
758+ let opcode: u8 = Operation :: AddMemToAccAbsolute . get_opcode ( ) ;
759+ let value: u8 = 7 ;
760+ let acc_value: u8 = 160 ;
761+ let expected_value: u8 = value + acc_value;
762+ let adl: u8 = 0x2A ;
763+ let adh: u8 = 0xBB ;
764+ let expected_address: u16 = 0xBB2A ;
765+
766+ let mut bus = TestBus :: new ( ) ;
767+ bus. write ( 0 , opcode) ;
768+ bus. write ( 1 , adl) ;
769+ bus. write ( 2 , adh) ;
770+ bus. write ( expected_address, value) ;
771+ let mut cpu = CPU :: new ( bus) ;
772+ cpu. registers . a = acc_value;
773+
774+ _test_read_and_decode_operation ( & mut cpu) ;
775+
776+ _test_absolute_read ( & mut cpu) ;
777+
778+ cpu. step ( ) ;
779+
780+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
781+ assert_eq ! (
782+ cpu. current_micro_instruction,
783+ Some ( MicroInstruction :: AddMemoryToAccumulator )
784+ ) ;
785+
786+ assert_eq ! ( cpu. registers. a, expected_value) ;
787+ }
788+
789+ #[ test]
790+ fn test_cpu_add_mem_to_acc_absolute_x ( ) {
791+ let opcode: u8 = Operation :: AddMemToAccAbsoluteX . get_opcode ( ) ;
792+ let value: u8 = 7 ;
793+ let acc_value: u8 = 160 ;
794+ let x_value: u8 = 11 ;
795+ let expected_value: u8 = value + acc_value;
796+ let adl: u8 = 0x2A ;
797+ let adh: u8 = 0xBB ;
798+ let address: u16 = 0xBB2A ;
799+ let expected_address: u16 = address + x_value as u16 ;
800+
801+ let mut bus = TestBus :: new ( ) ;
802+ bus. write ( 0 , opcode) ;
803+ bus. write ( 1 , adl) ;
804+ bus. write ( 2 , adh) ;
805+ bus. write ( expected_address, value) ;
806+ let mut cpu = CPU :: new ( bus) ;
807+ cpu. registers . a = acc_value;
808+ cpu. registers . x = x_value;
809+
810+ _test_read_and_decode_operation ( & mut cpu) ;
811+
812+ _test_absolute_x_read ( & mut cpu) ;
813+
814+ cpu. step ( ) ;
815+
816+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
817+ assert_eq ! (
818+ cpu. current_micro_instruction,
819+ Some ( MicroInstruction :: AddMemoryToAccumulator )
820+ ) ;
821+
822+ assert_eq ! ( cpu. registers. a, expected_value) ;
823+ }
824+
825+ #[ test]
826+ fn test_cpu_add_mem_to_acc_absolute_y ( ) {
827+ let opcode: u8 = Operation :: AddMemToAccAbsoluteY . get_opcode ( ) ;
828+ let value: u8 = 7 ;
829+ let acc_value: u8 = 160 ;
830+ let y_value: u8 = 110 ;
831+ let expected_value: u8 = value + acc_value;
832+ let adl: u8 = 0x2A ;
833+ let adh: u8 = 0xBB ;
834+ let address: u16 = 0xBB2A ;
835+ let expected_address: u16 = address + y_value as u16 ;
836+
837+ let mut bus = TestBus :: new ( ) ;
838+ bus. write ( 0 , opcode) ;
839+ bus. write ( 1 , adl) ;
840+ bus. write ( 2 , adh) ;
841+ bus. write ( expected_address, value) ;
842+ let mut cpu = CPU :: new ( bus) ;
843+ cpu. registers . a = acc_value;
844+ cpu. registers . y = y_value;
845+
846+ _test_read_and_decode_operation ( & mut cpu) ;
847+
848+ _test_absolute_y_read ( & mut cpu) ;
849+
850+ cpu. step ( ) ;
851+
852+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
853+ assert_eq ! (
854+ cpu. current_micro_instruction,
855+ Some ( MicroInstruction :: AddMemoryToAccumulator )
856+ ) ;
857+
858+ assert_eq ! ( cpu. registers. a, expected_value) ;
859+ }
860+
861+ #[ test]
862+ fn test_cpu_add_mem_to_acc_indirect_x ( ) {
863+ let opcode = Operation :: AddMemToAccIndirectX . get_opcode ( ) ;
864+ let value: u8 = 30 ;
865+ let acc_value: u8 = 15 ;
866+ let expected_value: u8 = value + acc_value;
867+ let x_value: u8 = 10 ;
868+ let adl: u8 = 0x80 ;
869+ let expected_address: u16 = ( adl + x_value) as u16 ;
870+ let indirect_adl: u8 = 0xBB ;
871+ let indirect_adh: u8 = 0xAA ;
872+ let indirect_address: u16 = 0xAABB ;
873+
874+ let mut bus = TestBus :: new ( ) ;
875+ bus. write ( 0 , opcode) ;
876+ bus. write ( 1 , adl) ;
877+ bus. write ( expected_address, indirect_adl) ;
878+ bus. write ( expected_address + 1 , indirect_adh) ;
879+ bus. write ( indirect_address, value) ;
880+ let mut cpu = CPU :: new ( bus) ;
881+ cpu. registers . a = acc_value;
882+ cpu. registers . x = x_value;
883+
884+ _test_read_and_decode_operation ( & mut cpu) ;
885+
886+ _test_indirect_x_read ( & mut cpu) ;
887+
888+ cpu. step ( ) ;
889+
890+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
891+ assert_eq ! (
892+ cpu. current_micro_instruction,
893+ Some ( MicroInstruction :: AddMemoryToAccumulator )
894+ ) ;
895+
896+ assert_eq ! ( cpu. registers. a, expected_value) ;
897+ }
898+
899+ #[ test]
900+ fn test_cpu_add_mem_to_acc_indirect_y ( ) {
901+ let opcode: u8 = Operation :: AddMemToAccIndirectY . get_opcode ( ) ;
902+ let value: u8 = 60 ;
903+ let acc_value: u8 = 99 ;
904+ let expected_value: u8 = value + acc_value;
905+ let y_value: u8 = 20 ;
906+ let adl: u8 = 0x80 ;
907+ let indirect_adl: u8 = 0xBB ;
908+ let indirect_adh: u8 = 0xAA ;
909+ let indirect_address: u16 = 0xAABB ;
910+ let expected_address: u16 = indirect_address + y_value as u16 ;
911+
912+ let mut bus = TestBus :: new ( ) ;
913+ bus. write ( 0 , opcode) ;
914+ bus. write ( 1 , adl) ;
915+ bus. write ( adl as u16 , indirect_adl) ;
916+ bus. write ( ( adl + 1 ) as u16 , indirect_adh) ;
917+ bus. write ( expected_address, value) ;
918+ let mut cpu = CPU :: new ( bus) ;
919+ cpu. registers . a = acc_value;
920+ cpu. registers . y = y_value;
921+
922+ _test_read_and_decode_operation ( & mut cpu) ;
923+
924+ _test_indirect_y_read ( & mut cpu) ;
925+
926+ cpu. step ( ) ;
927+
928+ assert_eq ! ( cpu. state, CPUState :: Fetching ) ;
929+ assert_eq ! (
930+ cpu. current_micro_instruction,
931+ Some ( MicroInstruction :: AddMemoryToAccumulator )
932+ ) ;
933+
934+ assert_eq ! ( cpu. registers. a, expected_value) ;
935+ }
936+
663937 #[ test]
664938 fn test_cpu_asl_a ( ) {
665939 const OPCODE : u8 = 0x0A ;
0 commit comments