Break up memory parsing module

jsmoo
Nick Krichevsky 2022-04-06 23:06:03 -04:00
parent ad62658980
commit 0c53bd2c6b
2 changed files with 141 additions and 107 deletions

View File

@ -85,8 +85,8 @@ impl RunnableInstruction {
} }
pub fn make_ld_from_register_address( pub fn make_ld_from_register_address(
src: register::Combined,
dst: register::Single, dst: register::Single,
src: register::Combined,
data: &[u8], data: &[u8],
) -> (RunnableInstruction, &[u8]) { ) -> (RunnableInstruction, &[u8]) {
( (

View File

@ -1,118 +1,152 @@
use crate::register; use crate::register;
use crate::run::instructions::RunnableInstruction; use crate::run::instructions::RunnableInstruction;
use crate::run::parse::{self, OpcodeParser, Error, ParseResult}; use crate::run::parse::{self, Error, OpcodeParser, ParseResult};
#[allow(clippy::module_name_repetitions)] #[allow(clippy::module_name_repetitions)]
pub struct Memory8BitLoadParser; pub struct Memory8BitLoadParser;
impl OpcodeParser for Memory8BitLoadParser { impl OpcodeParser for Memory8BitLoadParser {
#[allow(clippy::too_many_lines)] // Parses a single instruction to load an 8 bit value to/from memory
fn parse_opcode(data: &[u8]) -> ParseResult { fn parse_opcode(data: &[u8]) -> ParseResult {
let opcode = parse::get_opcode_from_data(data)?; let parse_funcs = &[
match opcode { parse_load_from_register_to_address,
0x7E => Ok(RunnableInstruction::make_ld_from_register_address( parse_load_from_address_to_register,
register::Combined::HL, parse_load_immediate_instructions,
register::Single::A, ];
data,
)),
0x46 => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
register::Single::B,
data,
)),
0x4E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
register::Single::C,
data,
)),
0x56 => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
register::Single::D,
data,
)),
0x5E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
register::Single::E,
data,
)),
0x66 => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
register::Single::H,
data,
)),
0x6E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
register::Single::L,
data,
)),
0x70 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::B,
data,
)),
0x71 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::C,
data,
)),
0x72 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::D,
data,
)),
0x73 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::E,
data,
)),
0x74 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::H,
data,
)),
0x75 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::L,
data,
)),
0x36 => Ok(RunnableInstruction::make_ld_n_to_hl_address(data)),
0xFA => Ok(RunnableInstruction::make_ld_from_immediate_address( for parse_func in parse_funcs {
register::Single::A, match parse_func(data) {
data, Ok(parsed_data) => return Ok(parsed_data),
)), Err(Error::UnknownOpcode(_)) => continue,
0x0A => Ok(RunnableInstruction::make_ld_from_register_address( Err(err) => return Err(err),
register::Combined::BC, }
register::Single::A,
data,
)),
0x1A => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::DE,
register::Single::A,
data,
)),
0x02 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::BC,
register::Single::A,
data,
)),
0x12 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::DE,
register::Single::A,
data,
)),
0x77 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::A,
data,
)),
0xEA => Ok(RunnableInstruction::make_ld_to_immediate_address(
register::Single::A,
data,
)),
_ => Err(Error::UnknownOpcode(opcode)),
} }
let opcode = parse::get_opcode_from_data(data)?;
Err(Error::UnknownOpcode(opcode))
}
}
fn parse_load_from_register_to_address(data: &[u8]) -> ParseResult {
let opcode = parse::get_opcode_from_data(data)?;
match opcode {
0x02 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::BC,
register::Single::A,
data,
)),
0x12 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::DE,
register::Single::A,
data,
)),
0x70 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::B,
data,
)),
0x71 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::C,
data,
)),
0x72 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::D,
data,
)),
0x73 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::E,
data,
)),
0x74 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::H,
data,
)),
0x75 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::L,
data,
)),
0x77 => Ok(RunnableInstruction::make_ld_to_register_address(
register::Combined::HL,
register::Single::A,
data,
)),
_ => Err(Error::UnknownOpcode(opcode)),
}
}
fn parse_load_from_address_to_register(data: &[u8]) -> ParseResult {
let opcode = parse::get_opcode_from_data(data)?;
match opcode {
0x0A => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::A,
register::Combined::BC,
data,
)),
0x1A => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::A,
register::Combined::DE,
data,
)),
0x46 => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::B,
register::Combined::HL,
data,
)),
0x4E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::C,
register::Combined::HL,
data,
)),
0x56 => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::D,
register::Combined::HL,
data,
)),
0x5E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::E,
register::Combined::HL,
data,
)),
0x66 => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::H,
register::Combined::HL,
data,
)),
0x6E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::L,
register::Combined::HL,
data,
)),
0x7E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Single::A,
register::Combined::HL,
data,
)),
_ => Err(Error::UnknownOpcode(opcode)),
}
}
fn parse_load_immediate_instructions(data: &[u8]) -> ParseResult {
let opcode = parse::get_opcode_from_data(data)?;
match opcode {
0x36 => Ok(RunnableInstruction::make_ld_n_to_hl_address(data)),
0xFA => Ok(RunnableInstruction::make_ld_from_immediate_address(
register::Single::A,
data,
)),
0xEA => Ok(RunnableInstruction::make_ld_to_immediate_address(
register::Single::A,
data,
)),
_ => Err(Error::UnknownOpcode(opcode)),
} }
} }