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