diff --git a/src/cpu/instructions/control.rs b/src/cpu/instructions/control.rs index 8f7d8dd..1ce425e 100644 --- a/src/cpu/instructions/control.rs +++ b/src/cpu/instructions/control.rs @@ -14,4 +14,9 @@ pub enum ControlFlowInstruction { value: u8, addr: u16, }, + JumpToImmediateIfFlagMatches { + flag: register::Flag, + value: u8, + addr: u16, + }, } diff --git a/src/cpu/parse/control.rs b/src/cpu/parse/control.rs index e236f7d..e731ef5 100644 --- a/src/cpu/parse/control.rs +++ b/src/cpu/parse/control.rs @@ -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 { diff --git a/src/cpu/run/control.rs b/src/cpu/run/control.rs index fc91c49..368d3bd 100644 --- a/src/cpu/run/control.rs +++ b/src/cpu/run/control.rs @@ -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)) diff --git a/tests/cpu/control.rs b/tests/cpu/control.rs index 1ca8f17..a102d63 100644 --- a/tests/cpu/control.rs +++ b/tests/cpu/control.rs @@ -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 diff --git a/tests/cpu/jsmoo/testdata/disabled/c2.json b/tests/cpu/jsmoo/testdata/c2.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/c2.json rename to tests/cpu/jsmoo/testdata/c2.json diff --git a/tests/cpu/jsmoo/testdata/disabled/ca.json b/tests/cpu/jsmoo/testdata/ca.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/ca.json rename to tests/cpu/jsmoo/testdata/ca.json diff --git a/tests/cpu/jsmoo/testdata/disabled/d2.json b/tests/cpu/jsmoo/testdata/d2.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/d2.json rename to tests/cpu/jsmoo/testdata/d2.json diff --git a/tests/cpu/jsmoo/testdata/disabled/da.json b/tests/cpu/jsmoo/testdata/da.json similarity index 100% rename from tests/cpu/jsmoo/testdata/disabled/da.json rename to tests/cpu/jsmoo/testdata/da.json