Refactor InstructionRunner trait to be Run trait on each instruction type

old-bit-manip
Nick Krichevsky 2023-11-11 14:54:35 -05:00
parent 770073489b
commit f703d195f9
4 changed files with 28 additions and 50 deletions

View File

@ -26,23 +26,17 @@ pub enum Error {
Unknown(Box<dyn std::error::Error>), Unknown(Box<dyn std::error::Error>),
} }
/// `InstructionRunner` takes a single instruction and runs it on the given processor. /// `Run` takes a single instruction and runs it on the given processor.
trait InstructionRunner<I: Copy> { trait Run {
fn run_instruction(processor: &mut Processor, instruction: I) -> Result<(), Error>; fn run_on(&self, processor: &mut Processor) -> Result<(), Error>;
} }
/// `run_instruction` will run the given instruction on the processor. /// `run_instruction` will run the given instruction on the processor.
#[allow(clippy::module_name_repetitions)] #[allow(clippy::module_name_repetitions)]
pub fn run_instruction(processor: &mut Processor, instruction: Instruction) -> Result<(), Error> { pub fn run_instruction(processor: &mut Processor, instruction: Instruction) -> Result<(), Error> {
match instruction { match instruction {
Instruction::EightBitLoad(load_instruction) => { Instruction::EightBitLoad(load_instruction) => load_instruction.run_on(processor),
load8::EightBitLoadRunner::run_instruction(processor, load_instruction) Instruction::SixteenBitLoad(load_instruction) => load_instruction.run_on(processor),
} Instruction::EightBitArithmetic(arith_instruction) => arith_instruction.run_on(processor),
Instruction::SixteenBitLoad(load_instruction) => {
load16::SixteenBitLoadRunner::run_instruction(processor, load_instruction)
}
Instruction::EightBitArithmetic(arith_instruction) => {
arith8::EightBitArithmeticRunner::run_instruction(processor, arith_instruction)
}
} }
} }

View File

@ -4,14 +4,11 @@ use crate::{
register, register,
}; };
use super::InstructionRunner; use super::Run;
mod binary; mod binary;
mod unary; mod unary;
#[derive(Copy, Clone, Debug)]
pub struct EightBitArithmeticRunner;
struct OperationOutput { struct OperationOutput {
value: u8, value: u8,
flags: OperationFlagOutput, flags: OperationFlagOutput,
@ -25,31 +22,28 @@ struct OperationFlagOutput {
half_carry_flag: u8, half_carry_flag: u8,
} }
impl InstructionRunner<EightBitArithmeticInstruction> for EightBitArithmeticRunner { impl Run for EightBitArithmeticInstruction {
fn run_instruction( fn run_on(&self, processor: &mut Processor) -> Result<(), Error> {
processor: &mut Processor, match self.operation {
instruction: EightBitArithmeticInstruction, Operation::Add => binary::run_add(processor, self.operand),
) -> Result<(), Error> {
match instruction.operation {
Operation::Add => binary::run_add(processor, instruction.operand),
Operation::AddWithCarry => binary::run_add_with_carry(processor, instruction.operand), Operation::AddWithCarry => binary::run_add_with_carry(processor, self.operand),
Operation::Sub => binary::run_sub(processor, instruction.operand), Operation::Sub => binary::run_sub(processor, self.operand),
Operation::SubWithCarry => binary::run_sub_with_carry(processor, instruction.operand), Operation::SubWithCarry => binary::run_sub_with_carry(processor, self.operand),
Operation::And => binary::run_and(processor, instruction.operand), Operation::And => binary::run_and(processor, self.operand),
Operation::Xor => binary::run_xor(processor, instruction.operand), Operation::Xor => binary::run_xor(processor, self.operand),
Operation::Or => binary::run_or(processor, instruction.operand), Operation::Or => binary::run_or(processor, self.operand),
Operation::Compare => binary::run_compare(processor, instruction.operand), Operation::Compare => binary::run_compare(processor, self.operand),
Operation::Inc => unary::run_inc(processor, instruction.operand), Operation::Inc => unary::run_inc(processor, self.operand),
Operation::Dec => unary::run_dec(processor, instruction.operand), Operation::Dec => unary::run_dec(processor, self.operand),
} }
} }
} }

View File

@ -1,18 +1,13 @@
use super::arithutil::CarryingAdd; use super::arithutil::CarryingAdd;
use super::{Error, InstructionRunner}; use super::{Error, Run};
use crate::cpu::{instructions::load16::SixteenBitLoadInstruction, Processor}; use crate::cpu::{instructions::load16::SixteenBitLoadInstruction, Processor};
use crate::{memory, register}; use crate::{memory, register};
pub(super) struct SixteenBitLoadRunner; impl Run for SixteenBitLoadInstruction {
impl InstructionRunner<SixteenBitLoadInstruction> for SixteenBitLoadRunner {
// TODO: Fix this // TODO: Fix this
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn run_instruction( fn run_on(&self, processor: &mut Processor) -> Result<(), Error> {
processor: &mut Processor, match *self {
instruction: SixteenBitLoadInstruction,
) -> Result<(), Error> {
match instruction {
SixteenBitLoadInstruction::LoadImmediateToRegister { dst, value } => { SixteenBitLoadInstruction::LoadImmediateToRegister { dst, value } => {
processor.registers.set_16bit_register(dst, value); processor.registers.set_16bit_register(dst, value);

View File

@ -1,19 +1,14 @@
use super::{Error, InstructionRunner}; use super::{Error, Run};
use crate::{ use crate::{
cpu::{instructions::load8::EightBitLoadInstruction, Processor}, cpu::{instructions::load8::EightBitLoadInstruction, Processor},
memory, register, memory, register,
}; };
pub(super) struct EightBitLoadRunner; impl Run for EightBitLoadInstruction {
impl InstructionRunner<EightBitLoadInstruction> for EightBitLoadRunner {
// TODO: Break this up somehow // TODO: Break this up somehow
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn run_instruction( fn run_on(&self, processor: &mut Processor) -> Result<(), Error> {
processor: &mut Processor, match *self {
instruction: EightBitLoadInstruction,
) -> Result<(), Error> {
match instruction {
EightBitLoadInstruction::LoadImmediateToRegister { value, register } => { EightBitLoadInstruction::LoadImmediateToRegister { value, register } => {
processor processor
.registers .registers