diff --git a/src/cpu/parse/arith8/add.rs b/src/cpu/parse/arith8/add.rs index aa7ffbb..3175fba 100644 --- a/src/cpu/parse/arith8/add.rs +++ b/src/cpu/parse/arith8/add.rs @@ -22,6 +22,11 @@ impl OpcodeParser for EightBitAddParser { 0x85 => Ok(build_add_register_to_a_data(register::SingleEightBit::L)), 0x86 => Ok(build_add_hl_address_to_a_data()), 0xC6 => Ok(build_add_immediate_to_a_data(data)), + + 0x8F => Ok(build_add_register_to_a_with_carry_data( + register::SingleEightBit::A, + )), + 0x88 => Ok(build_add_register_to_a_with_carry_data( register::SingleEightBit::B, )), @@ -40,6 +45,7 @@ impl OpcodeParser for EightBitAddParser { 0x8D => Ok(build_add_register_to_a_with_carry_data( register::SingleEightBit::L, )), + 0xCE => Ok(build_add_immediate_to_a_with_carry_data(data)), _ => Err(Error::UnknownOpcode(opcode)), } diff --git a/tests/cpu/arith8.rs b/tests/cpu/arith8.rs index 25fbd76..b4a115a 100644 --- a/tests/cpu/arith8.rs +++ b/tests/cpu/arith8.rs @@ -362,6 +362,49 @@ fn test_add_register_with_carry_to_a_flags( ); } +#[test_case(0xF0, 0, 0xE0; "no carry bit")] +#[test_case(0xF0, 1, 0xE1; "carry bit")] +fn test_add_a_to_itself_with_carry_value(initial_value: u8, carry_bit: u8, expected_value: u8) { + let mut processor = Processor::default(); + processor.registers.a = initial_value; + processor + .registers + .set_flag_bit(register::Flag::Carry, carry_bit); + let data = [0x8F, 0x01]; + + let (ins, extra_data) = + RunnableInstruction::from_data(&data).expect("could not parse instruction"); + assert_eq!(extra_data, &[0x01]); + processor.run_instruction(&ins); + + assert_eq!(processor.registers.a, expected_value); +} + +#[test_case(0xF0, 0, AdditionOperationFlags{zero: 0, carry: 1, half_carry: 0}; "carry bit")] +#[test_case(0x0F, 0, AdditionOperationFlags{zero: 0, carry: 0, half_carry: 1}; "half carry bit")] +#[test_case(0x0E, 1, AdditionOperationFlags{zero: 0, carry: 0, half_carry: 1}; "half carry bit with input carry bit")] +fn test_add_a_to_itself_with_carry_flags(initial_value: u8, carry_bit: u8, expected_flags: AdditionOperationFlags) { + let mut processor = Processor::default(); + processor.registers.a = initial_value; + processor + .registers + .set_flag_bit(register::Flag::Carry, carry_bit); + let data = [0x8F, 0x01]; + + let (ins, extra_data) = + RunnableInstruction::from_data(&data).expect("could not parse instruction"); + assert_eq!(extra_data, &[0x01]); + processor.run_instruction(&ins); + + testutil::assert_flags_eq!( + processor, + (register::Flag::Zero, expected_flags.zero), + (register::Flag::Subtract, 0), + (register::Flag::HalfCarry, expected_flags.half_carry), + (register::Flag::Carry, expected_flags.carry), + ); +} + #[test_case(0x01, 0x00, 0x02, 0x03; "no carry")] #[test_case(0x01, 0x01, 0x02, 0x04; "carry")] fn test_add_immediate_with_carry_to_a_value( diff --git a/tests/cpu/jsmoo/testdata/disabled/8f.json b/tests/cpu/jsmoo/testdata/8f.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/8f.json rename to tests/cpu/jsmoo/testdata/8f.json