From 9a6ccf6d480d53a95181c959388a4f01a3a8e413 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Sat, 18 Nov 2023 10:02:51 -0500 Subject: [PATCH] Simplify load8 parsing to use bitwise ops --- src/cpu/parse/load8/transfer.rs | 92 +++++++++++---------------------- 1 file changed, 30 insertions(+), 62 deletions(-) diff --git a/src/cpu/parse/load8/transfer.rs b/src/cpu/parse/load8/transfer.rs index 383a09b..d341cb7 100644 --- a/src/cpu/parse/load8/transfer.rs +++ b/src/cpu/parse/load8/transfer.rs @@ -13,71 +13,39 @@ pub struct Parser; impl OpcodeParser for Parser { /// Parses an opcode that transfers an 8bit values between single 8 bit registers. fn parse_opcode(data: &View) -> ParseResult { - // I don't normally like doing this but this function was ridiculous with the line length wrapping - // caused by not doing it - #[allow(clippy::enum_glob_use)] - use register::SingleEightBit::*; - let opcode = parse::get_opcode_from_data(data); - match opcode { - 0x7f => Ok(make_load_between_register_data(A, A)), - 0x78 => Ok(make_load_between_register_data(A, B)), - 0x79 => Ok(make_load_between_register_data(A, C)), - 0x7A => Ok(make_load_between_register_data(A, D)), - 0x7B => Ok(make_load_between_register_data(A, E)), - 0x7C => Ok(make_load_between_register_data(A, H)), - 0x7D => Ok(make_load_between_register_data(A, L)), + let dst = parse_destination_register(opcode)?; + let src = parse_source_register(opcode)?; - 0x47 => Ok(make_load_between_register_data(B, A)), - 0x40 => Ok(make_load_between_register_data(B, B)), - 0x41 => Ok(make_load_between_register_data(B, C)), - 0x42 => Ok(make_load_between_register_data(B, D)), - 0x43 => Ok(make_load_between_register_data(B, E)), - 0x44 => Ok(make_load_between_register_data(B, H)), - 0x45 => Ok(make_load_between_register_data(B, L)), + Ok(make_load_between_register_data(dst, src)) + } +} +fn parse_destination_register(opcode: u8) -> Result { + let source_part = opcode & 0xF0; + let offset = opcode & 0x0F; + match source_part { + 0x40 if offset <= 7 => Ok(register::SingleEightBit::B), + 0x40 if offset > 7 => Ok(register::SingleEightBit::C), + 0x50 if offset <= 7 => Ok(register::SingleEightBit::D), + 0x50 if offset > 7 => Ok(register::SingleEightBit::E), + 0x60 if offset <= 7 => Ok(register::SingleEightBit::H), + 0x60 if offset > 7 => Ok(register::SingleEightBit::L), + 0x70 if offset > 7 => Ok(register::SingleEightBit::A), + _ => Err(Error::UnknownOpcode(opcode)) + } +} - 0x4F => Ok(make_load_between_register_data(C, A)), - 0x48 => Ok(make_load_between_register_data(C, B)), - 0x49 => Ok(make_load_between_register_data(C, C)), - 0x4A => Ok(make_load_between_register_data(C, D)), - 0x4B => Ok(make_load_between_register_data(C, E)), - 0x4C => Ok(make_load_between_register_data(C, H)), - 0x4D => Ok(make_load_between_register_data(C, L)), - - 0x57 => Ok(make_load_between_register_data(D, A)), - 0x50 => Ok(make_load_between_register_data(D, B)), - 0x51 => Ok(make_load_between_register_data(D, C)), - 0x52 => Ok(make_load_between_register_data(D, D)), - 0x53 => Ok(make_load_between_register_data(D, E)), - 0x54 => Ok(make_load_between_register_data(D, H)), - 0x55 => Ok(make_load_between_register_data(D, L)), - - 0x5F => Ok(make_load_between_register_data(E, A)), - 0x58 => Ok(make_load_between_register_data(E, B)), - 0x59 => Ok(make_load_between_register_data(E, C)), - 0x5A => Ok(make_load_between_register_data(E, D)), - 0x5B => Ok(make_load_between_register_data(E, E)), - 0x5C => Ok(make_load_between_register_data(E, H)), - 0x5D => Ok(make_load_between_register_data(E, L)), - - 0x67 => Ok(make_load_between_register_data(H, A)), - 0x60 => Ok(make_load_between_register_data(H, B)), - 0x61 => Ok(make_load_between_register_data(H, C)), - 0x62 => Ok(make_load_between_register_data(H, D)), - 0x63 => Ok(make_load_between_register_data(H, E)), - 0x64 => Ok(make_load_between_register_data(H, H)), - 0x65 => Ok(make_load_between_register_data(H, L)), - - 0x6F => Ok(make_load_between_register_data(L, A)), - 0x68 => Ok(make_load_between_register_data(L, B)), - 0x69 => Ok(make_load_between_register_data(L, C)), - 0x6A => Ok(make_load_between_register_data(L, D)), - 0x6B => Ok(make_load_between_register_data(L, E)), - 0x6c => Ok(make_load_between_register_data(L, H)), - 0x6D => Ok(make_load_between_register_data(L, L)), - - _ => Err(Error::UnknownOpcode(opcode)), - } +fn parse_source_register(opcode: u8) -> Result { + let offset = opcode & 0x07; + match offset { + 0x00 => Ok(register::SingleEightBit::B), + 0x01 => Ok(register::SingleEightBit::C), + 0x02 => Ok(register::SingleEightBit::D), + 0x03 => Ok(register::SingleEightBit::E), + 0x04 => Ok(register::SingleEightBit::H), + 0x05 => Ok(register::SingleEightBit::L), + 0x07 => Ok(register::SingleEightBit::A), + _ => Err(Error::UnknownOpcode(opcode)) } }