Simplify control flow parsing logic
parent
fc76248853
commit
01cf67ca35
|
@ -1,93 +1,76 @@
|
|||
use crate::{
|
||||
cpu::{
|
||||
instructions::{control::ControlFlowInstruction, Instruction},
|
||||
parse, register,
|
||||
parse,
|
||||
},
|
||||
memory::{GetViewTuple, View},
|
||||
register::Flag,
|
||||
};
|
||||
|
||||
use super::{OpcodeParser, ParseOutput, ParseResult};
|
||||
use super::{OpcodeParser, OrParse, ParseOutput, ParseResult};
|
||||
|
||||
pub struct Parser;
|
||||
|
||||
enum ConditionalControlFlowType {
|
||||
Call,
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl OpcodeParser for Parser {
|
||||
fn parse_opcode(data: &View) -> ParseResult {
|
||||
let opcode = parse::get_opcode_from_data(data);
|
||||
match opcode {
|
||||
0xC3 => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediate { addr },
|
||||
)),
|
||||
0xCD => Ok(build_immediate_parameterized_control_flow_data(
|
||||
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 {
|
||||
flag: register::Flag::Zero,
|
||||
value: 0,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xD4 => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::CallIfFlagMatches {
|
||||
flag: register::Flag::Carry,
|
||||
value: 0,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xCC => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::CallIfFlagMatches {
|
||||
flag: register::Flag::Zero,
|
||||
value: 1,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
0xDC => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::CallIfFlagMatches {
|
||||
flag: register::Flag::Carry,
|
||||
value: 1,
|
||||
addr,
|
||||
},
|
||||
)),
|
||||
_ => Err(parse::Error::UnknownOpcode(opcode)),
|
||||
}
|
||||
parse_unconditional_control_operation(data)
|
||||
.or_parse(|_opcode| parse_conditional_control_operation(data))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_unconditional_control_operation(data: &View) -> ParseResult {
|
||||
let opcode = parse::get_opcode_from_data(data);
|
||||
|
||||
match opcode {
|
||||
0xC3 => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediate { addr },
|
||||
)),
|
||||
0xCD => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::Call { addr },
|
||||
)),
|
||||
_ => Err(parse::Error::UnknownOpcode(opcode)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_conditional_control_operation(data: &View) -> ParseResult {
|
||||
let opcode = parse::get_opcode_from_data(data);
|
||||
|
||||
let (flag, value) = conditional_control_flow_flag_for_opcode(opcode)?;
|
||||
let control_flow_type = conditional_control_flow_type_for_opcode(opcode)?;
|
||||
match control_flow_type {
|
||||
ConditionalControlFlowType::Jump => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::JumpToImmediateIfFlagMatches { flag, value, addr },
|
||||
)),
|
||||
ConditionalControlFlowType::Call => Ok(build_immediate_parameterized_control_flow_data(
|
||||
data,
|
||||
|addr| ControlFlowInstruction::CallIfFlagMatches { flag, value, addr },
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn conditional_control_flow_type_for_opcode(opcode: u8) -> Result<ConditionalControlFlowType, parse::Error> {
|
||||
match opcode {
|
||||
0xC2 | 0xD2 | 0xCA | 0xDA => Ok(ConditionalControlFlowType::Jump),
|
||||
0xC4 | 0xD4 | 0xCC | 0xDC => Ok(ConditionalControlFlowType::Call),
|
||||
_ => Err(parse::Error::UnknownOpcode(opcode)),
|
||||
}
|
||||
}
|
||||
|
||||
fn conditional_control_flow_flag_for_opcode(opcode: u8) -> Result<(Flag, u8), parse::Error> {
|
||||
match opcode {
|
||||
0xC2 | 0xC4 => Ok((Flag::Zero, 0)),
|
||||
0xD2 | 0xD4 => Ok((Flag::Carry, 0)),
|
||||
0xCA | 0xCC => Ok((Flag::Zero, 1)),
|
||||
0xDA | 0xDC => Ok((Flag::Carry, 1)),
|
||||
_ => Err(parse::Error::UnknownOpcode(opcode)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue