Add complement A register instruction
This commit is contained in:
parent
1bbd14e5d2
commit
e0745e149f
|
@ -4,4 +4,5 @@
|
||||||
pub enum MiscInstruction {
|
pub enum MiscInstruction {
|
||||||
SetCarryFlag,
|
SetCarryFlag,
|
||||||
ComplementCarryFlag,
|
ComplementCarryFlag,
|
||||||
|
ComplementARegister,
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ impl OpcodeParser for Parser {
|
||||||
match opcode {
|
match opcode {
|
||||||
0x37 => Ok(build_set_carry_flag_data()),
|
0x37 => Ok(build_set_carry_flag_data()),
|
||||||
0x3F => Ok(build_complement_carry_flag_data()),
|
0x3F => Ok(build_complement_carry_flag_data()),
|
||||||
|
0x2F => Ok(build_complement_a_register_data()),
|
||||||
_ => Err(super::Error::UnknownOpcode(opcode)),
|
_ => Err(super::Error::UnknownOpcode(opcode)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,3 +37,13 @@ fn build_complement_carry_flag_data() -> ParseOutput {
|
||||||
1,
|
1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_complement_a_register_data() -> ParseOutput {
|
||||||
|
(
|
||||||
|
RunnableInstruction {
|
||||||
|
instruction: Instruction::Misc(MiscInstruction::ComplementARegister),
|
||||||
|
cycles: 4,
|
||||||
|
},
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,23 @@ impl Run for MiscInstruction {
|
||||||
|
|
||||||
set_flags_in_carry_bit_instruction(processor, flipped);
|
set_flags_in_carry_bit_instruction(processor, flipped);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
MiscInstruction::ComplementARegister => {
|
||||||
|
let current_value = processor
|
||||||
|
.registers
|
||||||
|
.get_single_8bit_register(register::SingleEightBit::A);
|
||||||
|
processor
|
||||||
|
.registers
|
||||||
|
.set_single_8bit_register(register::SingleEightBit::A, !current_value);
|
||||||
|
|
||||||
|
processor
|
||||||
|
.registers
|
||||||
|
.set_flag_bit(register::Flag::HalfCarry, 1);
|
||||||
|
processor
|
||||||
|
.registers
|
||||||
|
.set_flag_bit(register::Flag::Subtract, 1);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +44,10 @@ fn set_flags_in_carry_bit_instruction(processor: &mut Processor, carry_flag: u8)
|
||||||
.registers
|
.registers
|
||||||
.set_flag_bit(register::Flag::Carry, carry_flag);
|
.set_flag_bit(register::Flag::Carry, carry_flag);
|
||||||
|
|
||||||
processor.registers.set_flag_bit(register::Flag::HalfCarry, 0);
|
processor
|
||||||
processor.registers.set_flag_bit(register::Flag::Subtract, 0);
|
.registers
|
||||||
|
.set_flag_bit(register::Flag::HalfCarry, 0);
|
||||||
|
processor
|
||||||
|
.registers
|
||||||
|
.set_flag_bit(register::Flag::Subtract, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
use crate::testutil;
|
||||||
use ferris_boi::{
|
use ferris_boi::{
|
||||||
cpu::{instructions::RunnableInstruction, Processor},
|
cpu::{instructions::RunnableInstruction, Processor},
|
||||||
register,
|
register,
|
||||||
};
|
};
|
||||||
use test_case::test_case;
|
use test_case::test_case;
|
||||||
use crate::testutil;
|
|
||||||
|
|
||||||
#[test_case(1)]
|
#[test_case(1)]
|
||||||
#[test_case(0)]
|
#[test_case(0)]
|
||||||
|
@ -66,3 +66,42 @@ fn test_all_carry_bit_instructions_adjust_flags(opcode: u8) {
|
||||||
(register::Flag::Zero, 1),
|
(register::Flag::Zero, 1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_complement_a_register_value() {
|
||||||
|
let mut processor = Processor::default();
|
||||||
|
processor.registers.a = 0xF0;
|
||||||
|
|
||||||
|
let data = [0x2F, 0x03];
|
||||||
|
let (ins, extra_data) =
|
||||||
|
RunnableInstruction::from_data(&data).expect("could not parse instruction");
|
||||||
|
|
||||||
|
assert_eq!(extra_data, &[0x03]);
|
||||||
|
processor.run_instruction(&ins);
|
||||||
|
|
||||||
|
assert_eq!(0x0F, processor.registers.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_complement_a_register_flags() {
|
||||||
|
let mut processor = Processor::default();
|
||||||
|
processor.registers.a = 0xF0;
|
||||||
|
testutil::set_opposite_of_expected_flags(&mut processor, (0, 1, 1, 0));
|
||||||
|
|
||||||
|
let data = [0x2F, 0x03];
|
||||||
|
let (ins, extra_data) =
|
||||||
|
RunnableInstruction::from_data(&data).expect("could not parse instruction");
|
||||||
|
|
||||||
|
assert_eq!(extra_data, &[0x03]);
|
||||||
|
processor.run_instruction(&ins);
|
||||||
|
|
||||||
|
testutil::assert_flags_eq!(
|
||||||
|
processor,
|
||||||
|
// Always 1
|
||||||
|
(register::Flag::HalfCarry, 1),
|
||||||
|
(register::Flag::Subtract, 1),
|
||||||
|
// Value is preserved
|
||||||
|
(register::Flag::Carry, 1),
|
||||||
|
(register::Flag::Zero, 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue