Use simplified arithmetic instructions to simplify parsers

old-bit-manip
Nick Krichevsky 2023-05-13 13:54:20 -04:00
parent b4a24120a2
commit 97d6df639f
5 changed files with 49 additions and 127 deletions

View File

@ -1,5 +1,8 @@
use crate::{
cpu::instructions::{Instruction, RunnableInstruction},
cpu::instructions::{
arith8::{EightBitArithmeticInstruction, Operand, Operation},
Instruction, RunnableInstruction,
},
memory::{GetViewTuple, View},
register,
};
@ -11,38 +14,53 @@ pub mod and;
pub mod sub;
pub mod xor;
fn build_operation_between_register_and_a_data<F: Fn(register::SingleEightBit) -> Instruction>(
fn build_instruction_between_register_and_a_data(
operation: Operation,
src: register::SingleEightBit,
make_instruction: F,
) -> ParseOutput {
let instruction = EightBitArithmeticInstruction {
operand: Operand::SingleRegister(src),
operation,
};
(
RunnableInstruction {
instruction: make_instruction(src),
instruction: Instruction::EightBitArithmetic(instruction),
cycles: 4,
},
1,
)
}
fn build_operation_between_hl_value_and_a_data(instruction: Instruction) -> ParseOutput {
fn build_instruction_between_hl_value_and_a_data(operation: Operation) -> ParseOutput {
let instruction = EightBitArithmeticInstruction {
operand: Operand::HLAddressValue,
operation,
};
(
RunnableInstruction {
instruction,
instruction: Instruction::EightBitArithmetic(instruction),
cycles: 8,
},
1,
)
}
fn build_operation_between_immediate_and_a_data<F: Fn(u8) -> Instruction>(
fn build_instruction_between_immediate_and_a_data(
operation: Operation,
data: &View,
make_instruction: F,
) -> ParseOutput {
let (_opcode, n) = data.get_tuple();
let instruction = EightBitArithmeticInstruction {
operand: Operand::Immediate(n),
operation,
};
(
RunnableInstruction {
instruction: make_instruction(n),
instruction: Instruction::EightBitArithmetic(instruction),
cycles: 8,
},
2,

View File

@ -1,9 +1,6 @@
use crate::{
cpu::{
instructions::{
arith8::{EightBitArithmeticInstruction, Operand, Operation},
Instruction,
},
instructions::arith8::Operation,
parse::{self, Error, OpcodeParser, ParseOutput, ParseResult},
},
memory::View,
@ -58,53 +55,25 @@ impl OpcodeParser for EightBitAddParser {
}
fn build_add_register_to_a_data(src: register::SingleEightBit) -> ParseOutput {
super::build_operation_between_register_and_a_data(src, |register| {
build_add_instruction(Operand::SingleRegister(register))
})
super::build_instruction_between_register_and_a_data(Operation::Add, src)
}
fn build_add_register_to_a_with_carry_data(src: register::SingleEightBit) -> ParseOutput {
super::build_operation_between_register_and_a_data(src, |register| {
build_add_with_carry_instruction(Operand::SingleRegister(register))
})
super::build_instruction_between_register_and_a_data(Operation::AddWithCarry, src)
}
fn build_add_hl_address_to_a_data() -> ParseOutput {
let ins = build_add_instruction(Operand::HLAddressValue);
super::build_operation_between_hl_value_and_a_data(ins)
super::build_instruction_between_hl_value_and_a_data(Operation::Add)
}
fn build_add_hl_address_to_a_with_carry_data() -> ParseOutput {
let ins = build_add_with_carry_instruction(Operand::HLAddressValue);
super::build_operation_between_hl_value_and_a_data(ins)
super::build_instruction_between_hl_value_and_a_data(Operation::AddWithCarry)
}
fn build_add_immediate_to_a_data(data: &View) -> ParseOutput {
super::build_operation_between_immediate_and_a_data(data, |n| {
build_add_instruction(Operand::Immediate(n))
})
super::build_instruction_between_immediate_and_a_data(Operation::Add, data)
}
fn build_add_immediate_to_a_with_carry_data(data: &View) -> ParseOutput {
super::build_operation_between_immediate_and_a_data(data, |n| {
build_add_with_carry_instruction(Operand::Immediate(n))
})
}
fn build_add_instruction(operand: Operand) -> Instruction {
let arith_instruction = EightBitArithmeticInstruction {
operand,
operation: Operation::Add,
};
Instruction::EightBitArithmetic(arith_instruction)
}
fn build_add_with_carry_instruction(operand: Operand) -> Instruction {
let arith_instruction = EightBitArithmeticInstruction {
operand,
operation: Operation::AddWithCarry,
};
Instruction::EightBitArithmetic(arith_instruction)
super::build_instruction_between_immediate_and_a_data(Operation::AddWithCarry, data)
}

View File

@ -1,9 +1,6 @@
use crate::{
cpu::{
instructions::{
arith8::{EightBitArithmeticInstruction, Operand, Operation},
Instruction,
},
instructions::arith8::Operation,
parse::{self, Error, OpcodeParser, ParseOutput, ParseResult},
},
memory::View,
@ -31,27 +28,13 @@ impl OpcodeParser for EightBitAndParser {
}
fn build_and_register_with_a_data(src: register::SingleEightBit) -> ParseOutput {
super::build_operation_between_register_and_a_data(src, |register| {
build_and_instruction(Operand::SingleRegister(register))
})
super::build_instruction_between_register_and_a_data(Operation::And, src)
}
fn build_and_hl_value_with_a_data() -> ParseOutput {
let ins = build_and_instruction(Operand::HLAddressValue);
super::build_operation_between_hl_value_and_a_data(ins)
super::build_instruction_between_hl_value_and_a_data(Operation::And)
}
fn build_and_immediate_with_a_data(data: &View) -> ParseOutput {
super::build_operation_between_immediate_and_a_data(data, |n| {
build_and_instruction(Operand::Immediate(n))
})
}
fn build_and_instruction(operand: Operand) -> Instruction {
let arith_instruction = EightBitArithmeticInstruction {
operand,
operation: Operation::And,
};
Instruction::EightBitArithmetic(arith_instruction)
super::build_instruction_between_immediate_and_a_data(Operation::And, data)
}

View File

@ -1,9 +1,6 @@
use crate::{
cpu::{
instructions::{
arith8::{EightBitArithmeticInstruction, Operand, Operation},
Instruction,
},
instructions::arith8::Operation,
parse::{self, Error, OpcodeParser, ParseOutput, ParseResult},
},
memory::View,
@ -54,55 +51,27 @@ impl OpcodeParser for EightBitSubParser {
}
fn build_sub_register_from_a_data(src_register: register::SingleEightBit) -> ParseOutput {
super::build_operation_between_register_and_a_data(src_register, |register| {
build_sub_instruction(Operand::SingleRegister(register))
})
super::build_instruction_between_register_and_a_data(Operation::Sub, src_register)
}
fn build_sub_register_from_a_with_carry_data(
src_register: register::SingleEightBit,
) -> ParseOutput {
super::build_operation_between_register_and_a_data(src_register, |register| {
build_sub_with_carry_instruction(Operand::SingleRegister(register))
})
super::build_instruction_between_register_and_a_data(Operation::SubWithCarry, src_register)
}
fn build_sub_hl_value_from_a_data() -> ParseOutput {
let ins = build_sub_instruction(Operand::HLAddressValue);
super::build_operation_between_hl_value_and_a_data(ins)
super::build_instruction_between_hl_value_and_a_data(Operation::Sub)
}
fn build_sub_hl_value_from_a_with_carry_data() -> ParseOutput {
let ins = build_sub_with_carry_instruction(Operand::HLAddressValue);
super::build_operation_between_hl_value_and_a_data(ins)
super::build_instruction_between_hl_value_and_a_data(Operation::SubWithCarry)
}
fn build_sub_immediate_from_a_data(data: &View) -> ParseOutput {
super::build_operation_between_immediate_and_a_data(data, |n| {
build_sub_instruction(Operand::Immediate(n))
})
super::build_instruction_between_immediate_and_a_data(Operation::Sub, data)
}
fn build_sub_immediate_from_a_with_carry_data(data: &View) -> ParseOutput {
super::build_operation_between_immediate_and_a_data(data, |n| {
build_sub_with_carry_instruction(Operand::Immediate(n))
})
}
fn build_sub_instruction(operand: Operand) -> Instruction {
let arith_instruction = EightBitArithmeticInstruction {
operand,
operation: Operation::Sub,
};
Instruction::EightBitArithmetic(arith_instruction)
}
fn build_sub_with_carry_instruction(operand: Operand) -> Instruction {
let arith_instruction = EightBitArithmeticInstruction {
operand,
operation: Operation::SubWithCarry,
};
Instruction::EightBitArithmetic(arith_instruction)
super::build_instruction_between_immediate_and_a_data(Operation::SubWithCarry, data)
}

View File

@ -1,9 +1,6 @@
use crate::{
cpu::{
instructions::{
arith8::{EightBitArithmeticInstruction, Operand, Operation},
Instruction,
},
instructions::arith8::Operation,
parse::{self, Error, OpcodeParser, ParseOutput, ParseResult},
},
memory::View,
@ -31,27 +28,13 @@ impl OpcodeParser for EightBitXorParser {
}
fn build_xor_register_with_a_data(src: register::SingleEightBit) -> ParseOutput {
super::build_operation_between_register_and_a_data(src, |register| {
build_xor_instruction(Operand::SingleRegister(register))
})
super::build_instruction_between_register_and_a_data(Operation::Xor, src)
}
fn build_xor_hl_value_with_a_data() -> ParseOutput {
let ins = build_xor_instruction(Operand::HLAddressValue);
super::build_operation_between_hl_value_and_a_data(ins)
super::build_instruction_between_hl_value_and_a_data(Operation::Xor)
}
fn build_xor_immediate_with_a_data(data: &View) -> ParseOutput {
super::build_operation_between_immediate_and_a_data(data, |n| {
build_xor_instruction(Operand::Immediate(n))
})
}
fn build_xor_instruction(operand: Operand) -> Instruction {
let arith_instruction = EightBitArithmeticInstruction {
operand,
operation: Operation::Xor,
};
Instruction::EightBitArithmetic(arith_instruction)
super::build_instruction_between_immediate_and_a_data(Operation::Xor, data)
}