Add conditional jumps
parent
a5e838dda4
commit
827aef74f8
|
@ -14,4 +14,9 @@ pub enum ControlFlowInstruction {
|
|||
value: u8,
|
||||
addr: u16,
|
||||
},
|
||||
JumpToImmediateIfFlagMatches {
|
||||
flag: register::Flag,
|
||||
value: u8,
|
||||
addr: u16,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -22,6 +22,38 @@ impl OpcodeParser for Parser {
|
|||
data,
|
||||
|addr| ControlFlowInstruction::Call { addr },
|
||||
)),
|
||||
0xC2 => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediateIfFlagMatches {
|
||||
flag: register::Flag::Zero,
|
||||
value: 0,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xD2 => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediateIfFlagMatches {
|
||||
flag: register::Flag::Carry,
|
||||
value: 0,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xCA => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediateIfFlagMatches {
|
||||
flag: register::Flag::Zero,
|
||||
value: 1,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xDA => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediateIfFlagMatches {
|
||||
flag: register::Flag::Carry,
|
||||
value: 1,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xC4 => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::CallIfFlagMatches {
|
||||
|
|
|
@ -12,6 +12,17 @@ impl Run for ControlFlowInstruction {
|
|||
|
||||
Ok(Cycles(16))
|
||||
}
|
||||
Self::JumpToImmediateIfFlagMatches { flag, value, addr } => {
|
||||
if processor.registers.get_flag_bit(flag) == value {
|
||||
processor.registers.set_single_16bit_register(
|
||||
register::SingleSixteenBit::ProgramCounter,
|
||||
addr,
|
||||
);
|
||||
Ok(Cycles(16))
|
||||
} else {
|
||||
Ok(Cycles(12))
|
||||
}
|
||||
}
|
||||
Self::Call { addr } => {
|
||||
do_call(processor, addr)?;
|
||||
Ok(Cycles(24))
|
||||
|
|
|
@ -56,7 +56,11 @@ fn test_call_pushes_pc_onto_stack() {
|
|||
#[test_case(0xDC, Flag::Carry, 1; "CALL C")]
|
||||
#[test_case(0xC4, Flag::Zero, 0; "CALL NZ")]
|
||||
#[test_case(0xD4, Flag::Carry, 0; "CALL NC")]
|
||||
fn test_call_jumps_if_condition_matches(opcode: u8, flag: Flag, expected_value: u8) {
|
||||
#[test_case(0xCA, Flag::Zero, 1; "JP Z")]
|
||||
#[test_case(0xDA, Flag::Carry, 1; "JP C")]
|
||||
#[test_case(0xC2, Flag::Zero, 0; "JP NZ")]
|
||||
#[test_case(0xD2, Flag::Carry, 0; "JP NC")]
|
||||
fn test_call_and_jump_jumps_if_condition_matches(opcode: u8, flag: Flag, expected_value: u8) {
|
||||
let mut processor = Processor::default();
|
||||
processor.registers.set_flag_bit(flag, expected_value);
|
||||
|
||||
|
@ -93,7 +97,11 @@ fn test_call_grows_stack_if_condition_matches(opcode: u8, flag: Flag, expected_v
|
|||
#[test_case(0xDC, Flag::Carry, 1; "CALL C")]
|
||||
#[test_case(0xC4, Flag::Zero, 0; "CALL NZ")]
|
||||
#[test_case(0xD4, Flag::Carry, 0; "CALL NC")]
|
||||
fn test_call_does_nothing_if_condition_fails(opcode: u8, flag: Flag, expected_value: u8) {
|
||||
#[test_case(0xCA, Flag::Zero, 1; "JP Z")]
|
||||
#[test_case(0xDA, Flag::Carry, 1; "JP C")]
|
||||
#[test_case(0xC2, Flag::Zero, 0; "JP NZ")]
|
||||
#[test_case(0xD2, Flag::Carry, 0; "JP NC")]
|
||||
fn test_call_and_jump_does_nothing_if_condition_fails(opcode: u8, flag: Flag, expected_value: u8) {
|
||||
let mut processor = Processor::default();
|
||||
processor
|
||||
.registers
|
||||
|
|
Loading…
Reference in New Issue