diff --git a/src/cpu/instructions/manip.rs b/src/cpu/instructions/manip.rs index f5ddab8..272dcec 100644 --- a/src/cpu/instructions/manip.rs +++ b/src/cpu/instructions/manip.rs @@ -9,4 +9,8 @@ pub enum BitManipulationInstruction { SetHLValueBit { bit: u8, }, + ClearRegisterBit { + register: register::SingleEightBit, + bit: u8, + }, } diff --git a/src/cpu/parse/manip.rs b/src/cpu/parse/manip.rs index ccd948d..890734b 100644 --- a/src/cpu/parse/manip.rs +++ b/src/cpu/parse/manip.rs @@ -1,4 +1,6 @@ -use super::{unparsed::Opcode, OpcodeParser, ParseResult}; +use std::ops::RangeInclusive; + +use super::{unparsed::Opcode, OpcodeParser, OrParse, ParseResult}; use crate::{ cpu::{ instructions::{manip::BitManipulationInstruction, Instruction}, @@ -19,7 +21,7 @@ impl OpcodeParser for Parser { fn parse_opcode(data: &View) -> ParseResult { let opcode = parse::get_opcode_from_data(data); - parse_set_opcode(opcode) + parse_set_opcode(opcode).or_parse(parse_clear_opcode) } } @@ -32,7 +34,7 @@ fn parse_set_opcode(opcode: Opcode) -> ParseResult { return Err(parse::Error::UnknownOpcode(opcode)); } - let bit = bit_for_set_opcode(sixteen_bit_opcode)?; + let bit = bit_for_opcode(sixteen_bit_opcode, 0xCB_C0..=0xCB_FF)?; let operand = operand_for_opcode(sixteen_bit_opcode)?; let ins = match operand { OpcodeOperand::HLValue => BitManipulationInstruction::SetHLValueBit { bit }, @@ -44,6 +46,27 @@ fn parse_set_opcode(opcode: Opcode) -> ParseResult { Ok((Instruction::BitManipulation(ins), 2)) } +fn parse_clear_opcode(opcode: Opcode) -> ParseResult { + let Opcode::SixteenBit(sixteen_bit_opcode) = opcode else { + return Err(parse::Error::UnknownOpcode(opcode)); + }; + + if !(0xCB_80..=0xCB_BF).contains(&sixteen_bit_opcode) { + return Err(parse::Error::UnknownOpcode(opcode)); + } + + let bit = bit_for_opcode(sixteen_bit_opcode, 0xCB_80..=0xCB_BF)?; + let operand = operand_for_opcode(sixteen_bit_opcode)?; + let ins = match operand { + OpcodeOperand::HLValue => todo!(), + OpcodeOperand::Register(register) => { + BitManipulationInstruction::ClearRegisterBit { register, bit } + } + }; + + Ok((Instruction::BitManipulation(ins), 2)) +} + fn operand_for_opcode(opcode: u16) -> Result { let register_nibble = opcode & 0x000F; match register_nibble { @@ -59,12 +82,15 @@ fn operand_for_opcode(opcode: u16) -> Result { } } -fn bit_for_set_opcode(opcode: u16) -> Result { - if !(0xCB_C0..=0xCB_FF).contains(&opcode) { +fn bit_for_opcode( + opcode: u16, + opcode_variant_range: RangeInclusive, +) -> Result { + if !opcode_variant_range.contains(&opcode) { return Err(parse::Error::UnknownOpcode(opcode.into())); } - let bit = (opcode - 0xCB_C0) / 8; + let bit = (opcode - opcode_variant_range.start()) / 8; // Given the range we've constrained to, this has to be able to fit in 8 bits Ok(bit.try_into().unwrap()) diff --git a/src/cpu/run/manip.rs b/src/cpu/run/manip.rs index 16a2ed3..4cebb70 100644 --- a/src/cpu/run/manip.rs +++ b/src/cpu/run/manip.rs @@ -1,6 +1,7 @@ use crate::{ cpu::{instructions::manip::BitManipulationInstruction, run, Processor}, - memory, register, + memory, + register::{self, SingleEightBit}, }; use super::{Cycles, Run}; @@ -9,12 +10,7 @@ impl Run for BitManipulationInstruction { fn run_on(&self, processor: &mut Processor) -> Result { match *self { BitManipulationInstruction::SetRegisterBit { register, bit } => { - let register_value = processor.registers.get_single_8bit_register(register); - let upd_value = set_nth_bit(register_value, bit); - - processor - .registers - .set_single_8bit_register(register, upd_value); + transform_register_value(processor, register, |value| set_nth_bit(value, bit)); Ok(Cycles(8)) } @@ -24,6 +20,12 @@ impl Run for BitManipulationInstruction { Ok(Cycles(16)) } + + BitManipulationInstruction::ClearRegisterBit { register, bit } => { + transform_register_value(processor, register, |value| clear_nth_bit(value, bit)); + + Ok(Cycles(8)) + } } } } @@ -34,6 +36,26 @@ fn set_nth_bit(value: u8, bit: u8) -> u8 { value | (0x1 << bit) } +fn clear_nth_bit(value: u8, bit: u8) -> u8 { + assert!(bit < 8, "Cannot clear a bit greater than 7"); + + let clear_mask = !(0x1 << bit); + value & clear_mask +} + +fn transform_register_value u8>( + processor: &mut Processor, + register: SingleEightBit, + transform: F, +) { + let register_value = processor.registers.get_single_8bit_register(register); + let upd_value = transform(register_value); + + processor + .registers + .set_single_8bit_register(register, upd_value); +} + fn transform_hl_value u8>( processor: &mut Processor, transform: F, diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 80.json b/tests/cpu/jsmoo/testdata/cb 80.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 80.json rename to tests/cpu/jsmoo/testdata/cb 80.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 81.json b/tests/cpu/jsmoo/testdata/cb 81.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 81.json rename to tests/cpu/jsmoo/testdata/cb 81.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 82.json b/tests/cpu/jsmoo/testdata/cb 82.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 82.json rename to tests/cpu/jsmoo/testdata/cb 82.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 83.json b/tests/cpu/jsmoo/testdata/cb 83.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 83.json rename to tests/cpu/jsmoo/testdata/cb 83.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 84.json b/tests/cpu/jsmoo/testdata/cb 84.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 84.json rename to tests/cpu/jsmoo/testdata/cb 84.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 85.json b/tests/cpu/jsmoo/testdata/cb 85.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 85.json rename to tests/cpu/jsmoo/testdata/cb 85.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 87.json b/tests/cpu/jsmoo/testdata/cb 87.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 87.json rename to tests/cpu/jsmoo/testdata/cb 87.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 88.json b/tests/cpu/jsmoo/testdata/cb 88.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 88.json rename to tests/cpu/jsmoo/testdata/cb 88.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 89.json b/tests/cpu/jsmoo/testdata/cb 89.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 89.json rename to tests/cpu/jsmoo/testdata/cb 89.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 8a.json b/tests/cpu/jsmoo/testdata/cb 8a.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 8a.json rename to tests/cpu/jsmoo/testdata/cb 8a.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 8b.json b/tests/cpu/jsmoo/testdata/cb 8b.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 8b.json rename to tests/cpu/jsmoo/testdata/cb 8b.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 8c.json b/tests/cpu/jsmoo/testdata/cb 8c.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 8c.json rename to tests/cpu/jsmoo/testdata/cb 8c.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 8f.json b/tests/cpu/jsmoo/testdata/cb 8f.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 8f.json rename to tests/cpu/jsmoo/testdata/cb 8f.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 90.json b/tests/cpu/jsmoo/testdata/cb 90.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 90.json rename to tests/cpu/jsmoo/testdata/cb 90.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 91.json b/tests/cpu/jsmoo/testdata/cb 91.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 91.json rename to tests/cpu/jsmoo/testdata/cb 91.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 92.json b/tests/cpu/jsmoo/testdata/cb 92.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 92.json rename to tests/cpu/jsmoo/testdata/cb 92.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 93.json b/tests/cpu/jsmoo/testdata/cb 93.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 93.json rename to tests/cpu/jsmoo/testdata/cb 93.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 94.json b/tests/cpu/jsmoo/testdata/cb 94.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 94.json rename to tests/cpu/jsmoo/testdata/cb 94.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 95.json b/tests/cpu/jsmoo/testdata/cb 95.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 95.json rename to tests/cpu/jsmoo/testdata/cb 95.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 97.json b/tests/cpu/jsmoo/testdata/cb 97.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 97.json rename to tests/cpu/jsmoo/testdata/cb 97.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 98.json b/tests/cpu/jsmoo/testdata/cb 98.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 98.json rename to tests/cpu/jsmoo/testdata/cb 98.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 99.json b/tests/cpu/jsmoo/testdata/cb 99.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 99.json rename to tests/cpu/jsmoo/testdata/cb 99.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 9a.json b/tests/cpu/jsmoo/testdata/cb 9a.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 9a.json rename to tests/cpu/jsmoo/testdata/cb 9a.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 9b.json b/tests/cpu/jsmoo/testdata/cb 9b.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 9b.json rename to tests/cpu/jsmoo/testdata/cb 9b.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 9c.json b/tests/cpu/jsmoo/testdata/cb 9c.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 9c.json rename to tests/cpu/jsmoo/testdata/cb 9c.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb 9f.json b/tests/cpu/jsmoo/testdata/cb 9f.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb 9f.json rename to tests/cpu/jsmoo/testdata/cb 9f.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a0.json b/tests/cpu/jsmoo/testdata/cb a0.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a0.json rename to tests/cpu/jsmoo/testdata/cb a0.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a1.json b/tests/cpu/jsmoo/testdata/cb a1.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a1.json rename to tests/cpu/jsmoo/testdata/cb a1.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a2.json b/tests/cpu/jsmoo/testdata/cb a2.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a2.json rename to tests/cpu/jsmoo/testdata/cb a2.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a3.json b/tests/cpu/jsmoo/testdata/cb a3.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a3.json rename to tests/cpu/jsmoo/testdata/cb a3.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a4.json b/tests/cpu/jsmoo/testdata/cb a4.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a4.json rename to tests/cpu/jsmoo/testdata/cb a4.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a5.json b/tests/cpu/jsmoo/testdata/cb a5.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a5.json rename to tests/cpu/jsmoo/testdata/cb a5.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a7.json b/tests/cpu/jsmoo/testdata/cb a7.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a7.json rename to tests/cpu/jsmoo/testdata/cb a7.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a8.json b/tests/cpu/jsmoo/testdata/cb a8.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a8.json rename to tests/cpu/jsmoo/testdata/cb a8.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb a9.json b/tests/cpu/jsmoo/testdata/cb a9.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb a9.json rename to tests/cpu/jsmoo/testdata/cb a9.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb aa.json b/tests/cpu/jsmoo/testdata/cb aa.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb aa.json rename to tests/cpu/jsmoo/testdata/cb aa.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb ab.json b/tests/cpu/jsmoo/testdata/cb ab.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb ab.json rename to tests/cpu/jsmoo/testdata/cb ab.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb ac.json b/tests/cpu/jsmoo/testdata/cb ac.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb ac.json rename to tests/cpu/jsmoo/testdata/cb ac.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb af.json b/tests/cpu/jsmoo/testdata/cb af.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb af.json rename to tests/cpu/jsmoo/testdata/cb af.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b0.json b/tests/cpu/jsmoo/testdata/cb b0.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b0.json rename to tests/cpu/jsmoo/testdata/cb b0.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b1.json b/tests/cpu/jsmoo/testdata/cb b1.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b1.json rename to tests/cpu/jsmoo/testdata/cb b1.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b2.json b/tests/cpu/jsmoo/testdata/cb b2.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b2.json rename to tests/cpu/jsmoo/testdata/cb b2.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b3.json b/tests/cpu/jsmoo/testdata/cb b3.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b3.json rename to tests/cpu/jsmoo/testdata/cb b3.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b4.json b/tests/cpu/jsmoo/testdata/cb b4.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b4.json rename to tests/cpu/jsmoo/testdata/cb b4.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b5.json b/tests/cpu/jsmoo/testdata/cb b5.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b5.json rename to tests/cpu/jsmoo/testdata/cb b5.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b7.json b/tests/cpu/jsmoo/testdata/cb b7.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b7.json rename to tests/cpu/jsmoo/testdata/cb b7.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b8.json b/tests/cpu/jsmoo/testdata/cb b8.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b8.json rename to tests/cpu/jsmoo/testdata/cb b8.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb b9.json b/tests/cpu/jsmoo/testdata/cb b9.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb b9.json rename to tests/cpu/jsmoo/testdata/cb b9.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb ba.json b/tests/cpu/jsmoo/testdata/cb ba.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb ba.json rename to tests/cpu/jsmoo/testdata/cb ba.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb bb.json b/tests/cpu/jsmoo/testdata/cb bb.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb bb.json rename to tests/cpu/jsmoo/testdata/cb bb.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb bc.json b/tests/cpu/jsmoo/testdata/cb bc.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb bc.json rename to tests/cpu/jsmoo/testdata/cb bc.json diff --git a/tests/cpu/jsmoo/testdata/disabled/cb bf.json b/tests/cpu/jsmoo/testdata/cb bf.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/cb bf.json rename to tests/cpu/jsmoo/testdata/cb bf.json diff --git a/tests/cpu/manip.rs b/tests/cpu/manip.rs index b46de35..b54370b 100644 --- a/tests/cpu/manip.rs +++ b/tests/cpu/manip.rs @@ -1,6 +1,6 @@ use ferris_boi::{ cpu::{instructions::Instruction, Processor}, - register, + register::{self, SingleEightBit}, }; use test_case::test_case; @@ -83,7 +83,6 @@ fn test_set_register_bit(opcode_variant: u8, register: register::SingleEightBit, ); } -// Register A #[test_case(0xC6, 0b00000001)] #[test_case(0xCE, 0b00000010)] #[test_case(0xD6, 0b00000100)] @@ -119,3 +118,83 @@ fn test_set_hl_value_bit(opcode_variant: u8, expected: u8) { .expect("failed to get memory value") ); } + +// Register B +#[test_case(0x80, register::SingleEightBit::B, 0b11111110)] +#[test_case(0x88, register::SingleEightBit::B, 0b11111101)] +#[test_case(0x90, register::SingleEightBit::B, 0b11111011)] +#[test_case(0x98, register::SingleEightBit::B, 0b11110111)] +#[test_case(0xA0, register::SingleEightBit::B, 0b11101111)] +#[test_case(0xA8, register::SingleEightBit::B, 0b11011111)] +#[test_case(0xB0, register::SingleEightBit::B, 0b10111111)] +#[test_case(0xB8, register::SingleEightBit::B, 0b01111111)] +// Register C +#[test_case(0x81, register::SingleEightBit::C, 0b11111110)] +#[test_case(0x89, register::SingleEightBit::C, 0b11111101)] +#[test_case(0x91, register::SingleEightBit::C, 0b11111011)] +#[test_case(0x99, register::SingleEightBit::C, 0b11110111)] +#[test_case(0xA1, register::SingleEightBit::C, 0b11101111)] +#[test_case(0xA9, register::SingleEightBit::C, 0b11011111)] +#[test_case(0xB1, register::SingleEightBit::C, 0b10111111)] +#[test_case(0xB9, register::SingleEightBit::C, 0b01111111)] +// Register D +#[test_case(0x82, register::SingleEightBit::D, 0b11111110)] +#[test_case(0x8A, register::SingleEightBit::D, 0b11111101)] +#[test_case(0x92, register::SingleEightBit::D, 0b11111011)] +#[test_case(0x9A, register::SingleEightBit::D, 0b11110111)] +#[test_case(0xA2, register::SingleEightBit::D, 0b11101111)] +#[test_case(0xAA, register::SingleEightBit::D, 0b11011111)] +#[test_case(0xB2, register::SingleEightBit::D, 0b10111111)] +#[test_case(0xBA, register::SingleEightBit::D, 0b01111111)] +// Register E +#[test_case(0x83, register::SingleEightBit::E, 0b11111110)] +#[test_case(0x8B, register::SingleEightBit::E, 0b11111101)] +#[test_case(0x93, register::SingleEightBit::E, 0b11111011)] +#[test_case(0x9B, register::SingleEightBit::E, 0b11110111)] +#[test_case(0xA3, register::SingleEightBit::E, 0b11101111)] +#[test_case(0xAB, register::SingleEightBit::E, 0b11011111)] +#[test_case(0xB3, register::SingleEightBit::E, 0b10111111)] +#[test_case(0xBB, register::SingleEightBit::E, 0b01111111)] +// Register H +#[test_case(0x84, register::SingleEightBit::H, 0b11111110)] +#[test_case(0x8C, register::SingleEightBit::H, 0b11111101)] +#[test_case(0x94, register::SingleEightBit::H, 0b11111011)] +#[test_case(0x9C, register::SingleEightBit::H, 0b11110111)] +#[test_case(0xA4, register::SingleEightBit::H, 0b11101111)] +#[test_case(0xAC, register::SingleEightBit::H, 0b11011111)] +#[test_case(0xB4, register::SingleEightBit::H, 0b10111111)] +#[test_case(0xBC, register::SingleEightBit::H, 0b01111111)] +// Register L +#[test_case(0x85, register::SingleEightBit::L, 0b11111110)] +#[test_case(0x8D, register::SingleEightBit::L, 0b11111101)] +#[test_case(0x95, register::SingleEightBit::L, 0b11111011)] +#[test_case(0x9D, register::SingleEightBit::L, 0b11110111)] +#[test_case(0xA5, register::SingleEightBit::L, 0b11101111)] +#[test_case(0xAD, register::SingleEightBit::L, 0b11011111)] +#[test_case(0xB5, register::SingleEightBit::L, 0b10111111)] +#[test_case(0xBD, register::SingleEightBit::L, 0b01111111)] +// Register A +#[test_case(0x87, register::SingleEightBit::A, 0b11111110)] +#[test_case(0x8F, register::SingleEightBit::A, 0b11111101)] +#[test_case(0x97, register::SingleEightBit::A, 0b11111011)] +#[test_case(0x9F, register::SingleEightBit::A, 0b11110111)] +#[test_case(0xA7, register::SingleEightBit::A, 0b11101111)] +#[test_case(0xAF, register::SingleEightBit::A, 0b11011111)] +#[test_case(0xB7, register::SingleEightBit::A, 0b10111111)] +#[test_case(0xBF, register::SingleEightBit::A, 0b01111111)] +fn test_clear_register_bit(opcode_variant: u8, register: SingleEightBit, expected: u8) { + let mut processor = Processor::default(); + + processor.registers.set_single_8bit_register(register, 0xFF); + let data = [0xCB, opcode_variant, 0x02]; + + let (ins, extra_data) = Instruction::from_data(&data).expect("could not parse instruction"); + assert_eq!(extra_data, &[0x02]); + + processor.run_instruction(ins); + + assert_eq!( + expected, + processor.registers.get_single_8bit_register(register) + ); +}