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(
src: register::Combined,
dst: register::Single,
src: register::Combined,
data: &[u8],
) -> (RunnableInstruction, &[u8]) {
(

View File

@ -1,118 +1,152 @@
use crate::register;
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)]
pub struct 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 {
let opcode = parse::get_opcode_from_data(data)?;
match opcode {
0x7E => Ok(RunnableInstruction::make_ld_from_register_address(
register::Combined::HL,
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)),
let parse_funcs = &[
parse_load_from_register_to_address,
parse_load_from_address_to_register,
parse_load_immediate_instructions,
];
0xFA => Ok(RunnableInstruction::make_ld_from_immediate_address(
register::Single::A,
data,
)),
0x0A => Ok(RunnableInstruction::make_ld_from_register_address(
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)),
for parse_func in parse_funcs {
match parse_func(data) {
Ok(parsed_data) => return Ok(parsed_data),
Err(Error::UnknownOpcode(_)) => continue,
Err(err) => return Err(err),
}
}
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)),
}
}