From ef2aff5a8e63b4f7eea72a348562e4def4641d91 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Sat, 9 Apr 2022 13:32:12 -0400 Subject: [PATCH] Rename Single to SingleEightBit --- src/register.rs | 40 ++-- src/run.rs | 199 ++++++++++---------- src/run/instructions.rs | 30 +-- src/run/parse/load8/immediate.rs | 18 +- src/run/parse/load8/memory.rs | 123 ++++++++----- src/run/parse/load8/transfer.rs | 302 +++++++++++++++++++++++++------ 6 files changed, 479 insertions(+), 233 deletions(-) diff --git a/src/register.rs b/src/register.rs index 7b09acf..62dcda1 100644 --- a/src/register.rs +++ b/src/register.rs @@ -12,7 +12,7 @@ pub enum Flag { } #[derive(Debug, Clone, Copy, strum_macros::Display)] -pub enum Single { +pub enum SingleEightBit { A, B, C, @@ -23,7 +23,7 @@ pub enum Single { L, } -// Combined represents a pair of two registers taht can be acted on as a single +// Combined represents a pair of two registers taht can be acted on as a single 8 bit // 16 bit register. #[derive(Debug, Clone, Copy, strum_macros::Display)] pub enum Combined { @@ -113,29 +113,29 @@ impl Registers { self.flags |= bit << pos; } - pub fn get_single_register(&self, register: Single) -> u8 { + pub fn get_single_8bit_register(&self, register: SingleEightBit) -> u8 { match register { - Single::A => self.a, - Single::B => self.b, - Single::C => self.c, - Single::D => self.d, - Single::E => self.e, - Single::F => self.f, - Single::H => self.h, - Single::L => self.l, + SingleEightBit::A => self.a, + SingleEightBit::B => self.b, + SingleEightBit::C => self.c, + SingleEightBit::D => self.d, + SingleEightBit::E => self.e, + SingleEightBit::F => self.f, + SingleEightBit::H => self.h, + SingleEightBit::L => self.l, } } - pub fn set_single_register(&mut self, register: Single, value: u8) { + pub fn set_single_8bit_register(&mut self, register: SingleEightBit, value: u8) { let register_ref = match register { - Single::A => &mut self.a, - Single::B => &mut self.b, - Single::C => &mut self.c, - Single::D => &mut self.d, - Single::E => &mut self.e, - Single::F => &mut self.f, - Single::H => &mut self.h, - Single::L => &mut self.l, + SingleEightBit::A => &mut self.a, + SingleEightBit::B => &mut self.b, + SingleEightBit::C => &mut self.c, + SingleEightBit::D => &mut self.d, + SingleEightBit::E => &mut self.e, + SingleEightBit::F => &mut self.f, + SingleEightBit::H => &mut self.h, + SingleEightBit::L => &mut self.l, }; *register_ref = value; diff --git a/src/run.rs b/src/run.rs index 768c1bc..b59cd9c 100644 --- a/src/run.rs +++ b/src/run.rs @@ -39,12 +39,12 @@ impl Processor { fn run(&mut self, instruction: &RunnableInstruction) { match instruction.instruction { Instruction::LD8BitImmediateToRegister { value, register } => { - self.registers.set_single_register(register, value); + self.registers.set_single_8bit_register(register, value); } Instruction::LDr1r2 { dst, src } => { - let src_value = self.registers.get_single_register(src); - self.registers.set_single_register(dst, src_value); + let src_value = self.registers.get_single_8bit_register(src); + self.registers.set_single_8bit_register(dst, src_value); } Instruction::LDFromRegisterAddress { src, dst } => { @@ -77,7 +77,7 @@ impl Processor { offset_register, dst, } => { - let src_address_offset = self.registers.get_single_register(offset_register); + let src_address_offset = self.registers.get_single_8bit_register(offset_register); let src_address = memory::IO_REGISTER_START_ADDRESS + usize::from(src_address_offset); let load_res = self.load_from_address_to_register(dst, src_address); @@ -87,7 +87,7 @@ impl Processor { src, offset_register, } => { - let dst_address_offset = self.registers.get_single_register(offset_register); + let dst_address_offset = self.registers.get_single_8bit_register(offset_register); let dst_address = memory::IO_REGISTER_START_ADDRESS + usize::from(dst_address_offset); let load_res = self.load_from_register_to_address(dst_address, src); @@ -128,7 +128,7 @@ impl Processor { fn load_from_register_to_register_address( &mut self, register_with_dst_address: register::Combined, - src: register::Single, + src: register::SingleEightBit, ) -> Result<(), Error> { let dst_address = self .registers @@ -150,9 +150,9 @@ impl Processor { fn load_from_register_to_address( &mut self, dst_address: usize, - src: register::Single, + src: register::SingleEightBit, ) -> Result<(), Error> { - let register_value = self.registers.get_single_register(src); + let register_value = self.registers.get_single_8bit_register(src); self.load_8bit_immediate_to_address(dst_address, register_value) } @@ -170,7 +170,7 @@ impl Processor { fn load_from_address_to_register( &mut self, - dst: register::Single, + dst: register::SingleEightBit, src_address: usize, ) -> Result<(), Error> { let memory_value = self.memory.get(src_address); @@ -179,7 +179,7 @@ impl Processor { None => Err(Error::InvalidImmediateAddress(src_address)), Some(value) => { // technically this could be done with map but I think this is more readable - self.registers.set_single_register(dst, value); + self.registers.set_single_8bit_register(dst, value); Ok(()) } } @@ -187,7 +187,7 @@ impl Processor { fn load_from_register_address_to_register( &mut self, - dst: register::Single, + dst: register::SingleEightBit, register_with_src_address: register::Combined, ) -> Result<(), Error> { let src_address = self @@ -213,14 +213,14 @@ mod tests { use super::*; use test_case::test_case; - #[test_case(0x3E, register::Single::A)] - #[test_case(0x06, register::Single::B)] - #[test_case(0x0E, register::Single::C)] - #[test_case(0x16, register::Single::D)] - #[test_case(0x1E, register::Single::E)] - #[test_case(0x26, register::Single::H)] - #[test_case(0x2E, register::Single::L)] - fn test_load_immediate(ld_opcode: u8, expected_register: register::Single) { + #[test_case(0x3E, register::SingleEightBit::A)] + #[test_case(0x06, register::SingleEightBit::B)] + #[test_case(0x0E, register::SingleEightBit::C)] + #[test_case(0x16, register::SingleEightBit::D)] + #[test_case(0x1E, register::SingleEightBit::E)] + #[test_case(0x26, register::SingleEightBit::H)] + #[test_case(0x2E, register::SingleEightBit::L)] + fn test_load_immediate(ld_opcode: u8, expected_register: register::SingleEightBit) { let mut processor = Processor::default(); let data = [ld_opcode, 0x23, 0x00, 0x01]; let (ins, extra_data) = @@ -233,67 +233,71 @@ mod tests { processor.run(&ins); assert_eq!( 0x23, - processor.registers.get_single_register(expected_register) + processor + .registers + .get_single_8bit_register(expected_register) ); } // lol going from a register to itself is kind of a weird thing to test - #[test_case(0x7F, register::Single::A, register::Single::A)] - #[test_case(0x78, register::Single::A, register::Single::B)] - #[test_case(0x79, register::Single::A, register::Single::C)] - #[test_case(0x7A, register::Single::A, register::Single::D)] - #[test_case(0x7B, register::Single::A, register::Single::E)] - #[test_case(0x7C, register::Single::A, register::Single::H)] - #[test_case(0x7D, register::Single::A, register::Single::L)] - #[test_case(0x40, register::Single::B, register::Single::B)] - #[test_case(0x41, register::Single::B, register::Single::C)] - #[test_case(0x42, register::Single::B, register::Single::D)] - #[test_case(0x43, register::Single::B, register::Single::E)] - #[test_case(0x44, register::Single::B, register::Single::H)] - #[test_case(0x45, register::Single::B, register::Single::L)] - #[test_case(0x48, register::Single::C, register::Single::B)] - #[test_case(0x49, register::Single::C, register::Single::C)] - #[test_case(0x4A, register::Single::C, register::Single::D)] - #[test_case(0x4B, register::Single::C, register::Single::E)] - #[test_case(0x4C, register::Single::C, register::Single::H)] - #[test_case(0x4D, register::Single::C, register::Single::L)] - #[test_case(0x50, register::Single::D, register::Single::B)] - #[test_case(0x51, register::Single::D, register::Single::C)] - #[test_case(0x52, register::Single::D, register::Single::D)] - #[test_case(0x53, register::Single::D, register::Single::E)] - #[test_case(0x54, register::Single::D, register::Single::H)] - #[test_case(0x55, register::Single::D, register::Single::L)] - #[test_case(0x58, register::Single::E, register::Single::B)] - #[test_case(0x59, register::Single::E, register::Single::C)] - #[test_case(0x5A, register::Single::E, register::Single::D)] - #[test_case(0x5B, register::Single::E, register::Single::E)] - #[test_case(0x5C, register::Single::E, register::Single::H)] - #[test_case(0x5D, register::Single::E, register::Single::L)] - #[test_case(0x60, register::Single::H, register::Single::B)] - #[test_case(0x61, register::Single::H, register::Single::C)] - #[test_case(0x62, register::Single::H, register::Single::D)] - #[test_case(0x63, register::Single::H, register::Single::E)] - #[test_case(0x64, register::Single::H, register::Single::H)] - #[test_case(0x65, register::Single::H, register::Single::L)] - #[test_case(0x68, register::Single::L, register::Single::B)] - #[test_case(0x69, register::Single::L, register::Single::C)] - #[test_case(0x6A, register::Single::L, register::Single::D)] - #[test_case(0x6B, register::Single::L, register::Single::E)] - #[test_case(0x6C, register::Single::L, register::Single::H)] - #[test_case(0x6D, register::Single::L, register::Single::L)] - #[test_case(0x47, register::Single::B, register::Single::A)] - #[test_case(0x4F, register::Single::C, register::Single::A)] - #[test_case(0x57, register::Single::D, register::Single::A)] - #[test_case(0x5F, register::Single::E, register::Single::A)] - #[test_case(0x67, register::Single::H, register::Single::A)] - #[test_case(0x6F, register::Single::L, register::Single::A)] + #[test_case(0x7F, register::SingleEightBit::A, register::SingleEightBit::A)] + #[test_case(0x78, register::SingleEightBit::A, register::SingleEightBit::B)] + #[test_case(0x79, register::SingleEightBit::A, register::SingleEightBit::C)] + #[test_case(0x7A, register::SingleEightBit::A, register::SingleEightBit::D)] + #[test_case(0x7B, register::SingleEightBit::A, register::SingleEightBit::E)] + #[test_case(0x7C, register::SingleEightBit::A, register::SingleEightBit::H)] + #[test_case(0x7D, register::SingleEightBit::A, register::SingleEightBit::L)] + #[test_case(0x40, register::SingleEightBit::B, register::SingleEightBit::B)] + #[test_case(0x41, register::SingleEightBit::B, register::SingleEightBit::C)] + #[test_case(0x42, register::SingleEightBit::B, register::SingleEightBit::D)] + #[test_case(0x43, register::SingleEightBit::B, register::SingleEightBit::E)] + #[test_case(0x44, register::SingleEightBit::B, register::SingleEightBit::H)] + #[test_case(0x45, register::SingleEightBit::B, register::SingleEightBit::L)] + #[test_case(0x48, register::SingleEightBit::C, register::SingleEightBit::B)] + #[test_case(0x49, register::SingleEightBit::C, register::SingleEightBit::C)] + #[test_case(0x4A, register::SingleEightBit::C, register::SingleEightBit::D)] + #[test_case(0x4B, register::SingleEightBit::C, register::SingleEightBit::E)] + #[test_case(0x4C, register::SingleEightBit::C, register::SingleEightBit::H)] + #[test_case(0x4D, register::SingleEightBit::C, register::SingleEightBit::L)] + #[test_case(0x50, register::SingleEightBit::D, register::SingleEightBit::B)] + #[test_case(0x51, register::SingleEightBit::D, register::SingleEightBit::C)] + #[test_case(0x52, register::SingleEightBit::D, register::SingleEightBit::D)] + #[test_case(0x53, register::SingleEightBit::D, register::SingleEightBit::E)] + #[test_case(0x54, register::SingleEightBit::D, register::SingleEightBit::H)] + #[test_case(0x55, register::SingleEightBit::D, register::SingleEightBit::L)] + #[test_case(0x58, register::SingleEightBit::E, register::SingleEightBit::B)] + #[test_case(0x59, register::SingleEightBit::E, register::SingleEightBit::C)] + #[test_case(0x5A, register::SingleEightBit::E, register::SingleEightBit::D)] + #[test_case(0x5B, register::SingleEightBit::E, register::SingleEightBit::E)] + #[test_case(0x5C, register::SingleEightBit::E, register::SingleEightBit::H)] + #[test_case(0x5D, register::SingleEightBit::E, register::SingleEightBit::L)] + #[test_case(0x60, register::SingleEightBit::H, register::SingleEightBit::B)] + #[test_case(0x61, register::SingleEightBit::H, register::SingleEightBit::C)] + #[test_case(0x62, register::SingleEightBit::H, register::SingleEightBit::D)] + #[test_case(0x63, register::SingleEightBit::H, register::SingleEightBit::E)] + #[test_case(0x64, register::SingleEightBit::H, register::SingleEightBit::H)] + #[test_case(0x65, register::SingleEightBit::H, register::SingleEightBit::L)] + #[test_case(0x68, register::SingleEightBit::L, register::SingleEightBit::B)] + #[test_case(0x69, register::SingleEightBit::L, register::SingleEightBit::C)] + #[test_case(0x6A, register::SingleEightBit::L, register::SingleEightBit::D)] + #[test_case(0x6B, register::SingleEightBit::L, register::SingleEightBit::E)] + #[test_case(0x6C, register::SingleEightBit::L, register::SingleEightBit::H)] + #[test_case(0x6D, register::SingleEightBit::L, register::SingleEightBit::L)] + #[test_case(0x47, register::SingleEightBit::B, register::SingleEightBit::A)] + #[test_case(0x4F, register::SingleEightBit::C, register::SingleEightBit::A)] + #[test_case(0x57, register::SingleEightBit::D, register::SingleEightBit::A)] + #[test_case(0x5F, register::SingleEightBit::E, register::SingleEightBit::A)] + #[test_case(0x67, register::SingleEightBit::H, register::SingleEightBit::A)] + #[test_case(0x6F, register::SingleEightBit::L, register::SingleEightBit::A)] fn test_load_register( ld_opcode: u8, - dst_register: register::Single, - src_register: register::Single, + dst_register: register::SingleEightBit, + src_register: register::SingleEightBit, ) { let mut processor = Processor::default(); - processor.registers.set_single_register(src_register, 0x45); + processor + .registers + .set_single_8bit_register(src_register, 0x45); let data = [ld_opcode, 0x00]; let (ins, extra_data) = @@ -303,22 +307,25 @@ mod tests { assert_eq!(extra_data, &[0x00]); processor.run(&ins); - assert_eq!(0x45, processor.registers.get_single_register(dst_register)); + assert_eq!( + 0x45, + processor.registers.get_single_8bit_register(dst_register) + ); } - #[test_case(0x7E, register::Combined::HL, register::Single::A)] - #[test_case(0x46, register::Combined::HL, register::Single::B)] - #[test_case(0x4E, register::Combined::HL, register::Single::C)] - #[test_case(0x56, register::Combined::HL, register::Single::D)] - #[test_case(0x5E, register::Combined::HL, register::Single::E)] - #[test_case(0x66, register::Combined::HL, register::Single::H)] - #[test_case(0x6E, register::Combined::HL, register::Single::L)] - #[test_case(0x0A, register::Combined::BC, register::Single::A)] - #[test_case(0x1A, register::Combined::DE, register::Single::A)] + #[test_case(0x7E, register::Combined::HL, register::SingleEightBit::A)] + #[test_case(0x46, register::Combined::HL, register::SingleEightBit::B)] + #[test_case(0x4E, register::Combined::HL, register::SingleEightBit::C)] + #[test_case(0x56, register::Combined::HL, register::SingleEightBit::D)] + #[test_case(0x5E, register::Combined::HL, register::SingleEightBit::E)] + #[test_case(0x66, register::Combined::HL, register::SingleEightBit::H)] + #[test_case(0x6E, register::Combined::HL, register::SingleEightBit::L)] + #[test_case(0x0A, register::Combined::BC, register::SingleEightBit::A)] + #[test_case(0x1A, register::Combined::DE, register::SingleEightBit::A)] fn test_load_from_memory( opcode: u8, expected_deref_register: register::Combined, - expected_register: register::Single, + expected_register: register::SingleEightBit, ) { let mut processor = Processor::default(); let set_val = processor.memory.set(0xCCDD, 105); @@ -337,23 +344,25 @@ mod tests { processor.run(&ins); assert_eq!( 105, - processor.registers.get_single_register(expected_register) + processor + .registers + .get_single_8bit_register(expected_register) ); } - #[test_case(0x70, register::Combined::HL, register::Single::B)] - #[test_case(0x71, register::Combined::HL, register::Single::C)] - #[test_case(0x72, register::Combined::HL, register::Single::D)] - #[test_case(0x73, register::Combined::HL, register::Single::E)] - #[test_case(0x74, register::Combined::HL, register::Single::H)] - #[test_case(0x75, register::Combined::HL, register::Single::L)] - #[test_case(0x02, register::Combined::BC, register::Single::A)] - #[test_case(0x12, register::Combined::DE, register::Single::A)] - #[test_case(0x77, register::Combined::HL, register::Single::A)] + #[test_case(0x70, register::Combined::HL, register::SingleEightBit::B)] + #[test_case(0x71, register::Combined::HL, register::SingleEightBit::C)] + #[test_case(0x72, register::Combined::HL, register::SingleEightBit::D)] + #[test_case(0x73, register::Combined::HL, register::SingleEightBit::E)] + #[test_case(0x74, register::Combined::HL, register::SingleEightBit::H)] + #[test_case(0x75, register::Combined::HL, register::SingleEightBit::L)] + #[test_case(0x02, register::Combined::BC, register::SingleEightBit::A)] + #[test_case(0x12, register::Combined::DE, register::SingleEightBit::A)] + #[test_case(0x77, register::Combined::HL, register::SingleEightBit::A)] fn test_load_to_memory( opcode: u8, expected_deref_register: register::Combined, - expected_register: register::Single, + expected_register: register::SingleEightBit, ) { let mut processor = Processor::default(); // This test does a bit of a sneaky - because we want to use CC as the high/low addresses @@ -361,7 +370,7 @@ mod tests { // be careful that the stored immediate value is also part of the address in these cases. processor .registers - .set_single_register(expected_register, 0xCC); + .set_single_8bit_register(expected_register, 0xCC); processor .registers diff --git a/src/run/instructions.rs b/src/run/instructions.rs index 9f6ddc2..0c2fa6c 100644 --- a/src/run/instructions.rs +++ b/src/run/instructions.rs @@ -7,58 +7,58 @@ pub enum Instruction { // 3.3.1.1 LD8BitImmediateToRegister { value: u8, - register: register::Single, + register: register::SingleEightBit, }, // 3.3.1.2, excluding the (hl) instructions, 3.3.1.3, excluding the (nn) instructions // and 3.3.1.4 excluding the (nn) instructions LDr1r2 { - dst: register::Single, - src: register::Single, + dst: register::SingleEightBit, + src: register::SingleEightBit, }, // 3.3.1.2/3.3.1.3, only the loading from (nn) instructions LDFromRegisterAddress { // src, unlike some of the other instructions, is a 16bit combined register that will be // dereferenced to get the value to place into the dst register src: register::Combined, - dst: register::Single, + dst: register::SingleEightBit, }, // 3.3.1.5 - load to register relative to $FF00 (the address of the i/o registers) LDFromMemoryRelativeToIORegisterStart { // A register whose value will be used to get the address relative to FF00 - offset_register: register::Single, - dst: register::Single, + offset_register: register::SingleEightBit, + dst: register::SingleEightBit, }, // 3.3.1.6 - load to memory relative to $FF00 (the address of the i/o registers) LDToMemoryRelativeToIORegisterStart { - src: register::Single, + src: register::SingleEightBit, // A register whose value will be used to get the address relative to FF00 - offset_register: register::Single, + offset_register: register::SingleEightBit, }, // 3.3.1.20 LDFromMemoryRelativeToIORegisterStartByImmediate { - dst: register::Single, + dst: register::SingleEightBit, offset: u8, }, // 3.3.1.19 LDToMemoryRelativeToIORegisterStartByImmediate { offset: u8, - src: register::Single, + src: register::SingleEightBit, }, LDFromImmediateAddress { src_address: u16, - dst: register::Single, + dst: register::SingleEightBit, }, // 3.3.1.2, only the loading to (hl) instructions // 3.3.1.4, only the loading to (nn) instructions LDToRegisterAddress { - src: register::Single, + src: register::SingleEightBit, // dst, unlike some other instructions, is a 16bit combined register that holds // the address we will write the value to dst: register::Combined, }, // 3.3.1.4, only the loading to (nn) immediate instrution LDToImmediateAddress { - src: register::Single, + src: register::SingleEightBit, dst_address: u16, }, // 3.3.1.2, but the (hl), n instruction [why is this in this section? it's so out of place] @@ -67,14 +67,14 @@ pub enum Instruction { }, // 3.3.1.{10,11,12} LDToRegisterAddressThenDec { - src: register::Single, + src: register::SingleEightBit, // The destination, unlike some other destination instructions, refers to a register // whose address will be dereferenced (and then decremented after the load) dst: register::Combined, }, // 3.3.1.{13,14,15} LDToRegisterAddressThenInc { - src: register::Single, + src: register::SingleEightBit, // The destination, unlike some other destination instructions, refers to a register // whose address will be dereferenced (and then incremented after the load) dst: register::Combined, diff --git a/src/run/parse/load8/immediate.rs b/src/run/parse/load8/immediate.rs index ff6822a..f2e6999 100644 --- a/src/run/parse/load8/immediate.rs +++ b/src/run/parse/load8/immediate.rs @@ -10,25 +10,25 @@ use crate::run::{ pub struct Immediate8BitLoadParser; impl OpcodeParser for Immediate8BitLoadParser { - /// Parses an opcode that will transfer an immediate 8 bit value into a single register. + /// Parses an opcode that will transfer an immediate 8 bit value into a single 8 bit register. fn parse_opcode(data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; match opcode { - 0x3E => make_load_immediate_data(register::Single::A, data), - 0x06 => make_load_immediate_data(register::Single::B, data), - 0x0E => make_load_immediate_data(register::Single::C, data), - 0x16 => make_load_immediate_data(register::Single::D, data), - 0x1E => make_load_immediate_data(register::Single::E, data), - 0x26 => make_load_immediate_data(register::Single::H, data), - 0x2E => make_load_immediate_data(register::Single::L, data), + 0x3E => make_load_immediate_data(register::SingleEightBit::A, data), + 0x06 => make_load_immediate_data(register::SingleEightBit::B, data), + 0x0E => make_load_immediate_data(register::SingleEightBit::C, data), + 0x16 => make_load_immediate_data(register::SingleEightBit::D, data), + 0x1E => make_load_immediate_data(register::SingleEightBit::E, data), + 0x26 => make_load_immediate_data(register::SingleEightBit::H, data), + 0x2E => make_load_immediate_data(register::SingleEightBit::L, data), _ => Err(Error::UnknownOpcode(opcode)), } } } -fn make_load_immediate_data(register: register::Single, data: &[u8]) -> ParseResult { +fn make_load_immediate_data(register: register::SingleEightBit, data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; let value = data.get(1).ok_or(Error::NotEnoughArgs(opcode))?; diff --git a/src/run/parse/load8/memory.rs b/src/run/parse/load8/memory.rs index 2105a9e..9eae4bb 100644 --- a/src/run/parse/load8/memory.rs +++ b/src/run/parse/load8/memory.rs @@ -6,7 +6,7 @@ use crate::run::parse::{self, Error, OpcodeParser, ParseResult}; pub struct Memory8BitLoadParser; impl OpcodeParser for Memory8BitLoadParser { - // Parses a single instruction to load an 8 bit value to/from memory + // Parses a single 8 bit instruction to load an 8 bit value to/from memory fn parse_opcode(data: &[u8]) -> ParseResult { let parse_funcs = &[ parse_load_from_register_to_address, @@ -32,15 +32,33 @@ impl OpcodeParser for Memory8BitLoadParser { fn parse_load_from_register_to_address(data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; match opcode { - 0x02 => make_ld_to_register_address(register::Combined::BC, register::Single::A, data), - 0x12 => make_ld_to_register_address(register::Combined::DE, register::Single::A, data), - 0x70 => make_ld_to_register_address(register::Combined::HL, register::Single::B, data), - 0x71 => make_ld_to_register_address(register::Combined::HL, register::Single::C, data), - 0x72 => make_ld_to_register_address(register::Combined::HL, register::Single::D, data), - 0x73 => make_ld_to_register_address(register::Combined::HL, register::Single::E, data), - 0x74 => make_ld_to_register_address(register::Combined::HL, register::Single::H, data), - 0x75 => make_ld_to_register_address(register::Combined::HL, register::Single::L, data), - 0x77 => make_ld_to_register_address(register::Combined::HL, register::Single::A, data), + 0x02 => { + make_ld_to_register_address(register::Combined::BC, register::SingleEightBit::A, data) + } + 0x12 => { + make_ld_to_register_address(register::Combined::DE, register::SingleEightBit::A, data) + } + 0x70 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::B, data) + } + 0x71 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::C, data) + } + 0x72 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::D, data) + } + 0x73 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::E, data) + } + 0x74 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::H, data) + } + 0x75 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::L, data) + } + 0x77 => { + make_ld_to_register_address(register::Combined::HL, register::SingleEightBit::A, data) + } _ => Err(Error::UnknownOpcode(opcode)), } } @@ -48,33 +66,52 @@ fn parse_load_from_register_to_address(data: &[u8]) -> ParseResult { fn parse_load_from_address_to_register(data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; match opcode { - 0x0A => make_ld_from_register_address(register::Single::A, register::Combined::BC, data), - 0x1A => make_ld_from_register_address(register::Single::A, register::Combined::DE, data), - 0x46 => make_ld_from_register_address(register::Single::B, register::Combined::HL, data), - 0x4E => make_ld_from_register_address(register::Single::C, register::Combined::HL, data), - 0x56 => make_ld_from_register_address(register::Single::D, register::Combined::HL, data), - 0x5E => make_ld_from_register_address(register::Single::E, register::Combined::HL, data), - 0x66 => make_ld_from_register_address(register::Single::H, register::Combined::HL, data), - 0x6E => make_ld_from_register_address(register::Single::L, register::Combined::HL, data), - 0x7E => make_ld_from_register_address(register::Single::A, register::Combined::HL, data), + 0x0A => { + make_ld_from_register_address(register::SingleEightBit::A, register::Combined::BC, data) + } + 0x1A => { + make_ld_from_register_address(register::SingleEightBit::A, register::Combined::DE, data) + } + 0x46 => { + make_ld_from_register_address(register::SingleEightBit::B, register::Combined::HL, data) + } + 0x4E => { + make_ld_from_register_address(register::SingleEightBit::C, register::Combined::HL, data) + } + 0x56 => { + make_ld_from_register_address(register::SingleEightBit::D, register::Combined::HL, data) + } + 0x5E => { + make_ld_from_register_address(register::SingleEightBit::E, register::Combined::HL, data) + } + 0x66 => { + make_ld_from_register_address(register::SingleEightBit::H, register::Combined::HL, data) + } + 0x6E => { + make_ld_from_register_address(register::SingleEightBit::L, register::Combined::HL, data) + } + 0x7E => { + make_ld_from_register_address(register::SingleEightBit::A, register::Combined::HL, data) + } 0xF2 => make_ld_from_memory_relative_to_io_register_start( - register::Single::C, - register::Single::A, + register::SingleEightBit::C, + register::SingleEightBit::A, data, ), 0xE2 => make_ld_to_memory_relative_to_io_register_start( - register::Single::C, - register::Single::A, + register::SingleEightBit::C, + register::SingleEightBit::A, data, ), 0xF0 => make_ld_from_memory_relative_to_io_register_start_by_immediate( - register::Single::A, + register::SingleEightBit::A, + data, + ), + 0xE0 => make_ld_to_memory_relative_to_io_register_start_by_immediate( + register::SingleEightBit::A, data, ), - 0xE0 => { - make_ld_to_memory_relative_to_io_register_start_by_immediate(register::Single::A, data) - } _ => Err(Error::UnknownOpcode(opcode)), } @@ -84,8 +121,8 @@ fn parse_load_immediate_instructions(data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; match opcode { 0x36 => make_ld_n_to_hl_address(data), - 0xFA => make_ld_from_immediate_address(register::Single::A, data), - 0xEA => make_ld_to_immediate_address(register::Single::A, data), + 0xFA => make_ld_from_immediate_address(register::SingleEightBit::A, data), + 0xEA => make_ld_to_immediate_address(register::SingleEightBit::A, data), _ => Err(Error::UnknownOpcode(opcode)), } } @@ -95,13 +132,13 @@ fn parse_load_from_register_to_address_then_do_arithmetic(data: &[u8]) -> ParseR match opcode { 0x32 => make_ld_to_address_then_do_arithmetic( register::Combined::HL, - register::Single::A, + register::SingleEightBit::A, |dst, src| Instruction::LDToRegisterAddressThenDec { dst, src }, data, ), 0x2A => make_ld_to_address_then_do_arithmetic( register::Combined::HL, - register::Single::A, + register::SingleEightBit::A, |dst, src| Instruction::LDToRegisterAddressThenInc { dst, src }, data, ), @@ -110,7 +147,7 @@ fn parse_load_from_register_to_address_then_do_arithmetic(data: &[u8]) -> ParseR } fn make_ld_from_register_address( - dst: register::Single, + dst: register::SingleEightBit, src: register::Combined, data: &[u8], ) -> ParseResult { @@ -129,7 +166,7 @@ fn make_ld_from_register_address( fn make_ld_to_register_address( dst: register::Combined, - src: register::Single, + src: register::SingleEightBit, data: &[u8], ) -> ParseResult { data.get(1..) @@ -145,7 +182,7 @@ fn make_ld_to_register_address( .ok_or(Error::NoData) } -fn make_ld_from_immediate_address(dst: register::Single, data: &[u8]) -> ParseResult { +fn make_ld_from_immediate_address(dst: register::SingleEightBit, data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; let args = data.get(1..=2).ok_or(Error::NotEnoughArgs(opcode))?; @@ -161,7 +198,7 @@ fn make_ld_from_immediate_address(dst: register::Single, data: &[u8]) -> ParseRe )) } -fn make_ld_to_immediate_address(src: register::Single, data: &[u8]) -> ParseResult { +fn make_ld_to_immediate_address(src: register::SingleEightBit, data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; let args = data.get(1..=2).ok_or(Error::NotEnoughArgs(opcode))?; @@ -191,8 +228,8 @@ fn make_ld_n_to_hl_address(data: &[u8]) -> ParseResult { } fn make_ld_from_memory_relative_to_io_register_start( - offset_register: register::Single, - dst: register::Single, + offset_register: register::SingleEightBit, + dst: register::SingleEightBit, data: &[u8], ) -> ParseResult { data.get(1..) @@ -213,8 +250,8 @@ fn make_ld_from_memory_relative_to_io_register_start( } fn make_ld_to_memory_relative_to_io_register_start( - offset_register: register::Single, - src: register::Single, + offset_register: register::SingleEightBit, + src: register::SingleEightBit, data: &[u8], ) -> ParseResult { data.get(1..) @@ -235,7 +272,7 @@ fn make_ld_to_memory_relative_to_io_register_start( } fn make_ld_to_memory_relative_to_io_register_start_by_immediate( - src: register::Single, + src: register::SingleEightBit, data: &[u8], ) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; @@ -255,7 +292,7 @@ fn make_ld_to_memory_relative_to_io_register_start_by_immediate( } fn make_ld_from_memory_relative_to_io_register_start_by_immediate( - dst: register::Single, + dst: register::SingleEightBit, data: &[u8], ) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; @@ -275,10 +312,10 @@ fn make_ld_from_memory_relative_to_io_register_start_by_immediate( } fn make_ld_to_address_then_do_arithmetic< - F: Fn(register::Combined, register::Single) -> Instruction, + F: Fn(register::Combined, register::SingleEightBit) -> Instruction, >( dst: register::Combined, - src: register::Single, + src: register::SingleEightBit, make: F, data: &[u8], ) -> ParseResult { diff --git a/src/run/parse/load8/transfer.rs b/src/run/parse/load8/transfer.rs index be821ef..1cf371f 100644 --- a/src/run/parse/load8/transfer.rs +++ b/src/run/parse/load8/transfer.rs @@ -8,72 +8,272 @@ use crate::run::{ pub struct Between8BitRegisterParser; impl OpcodeParser for Between8BitRegisterParser { - /// Parses an opcode that transfers an 8bit values between single registers. + /// Parses an opcode that transfers an 8bit values between single 8 bit registers. fn parse_opcode(data: &[u8]) -> ParseResult { let opcode = parse::get_opcode_from_data(data)?; match opcode { - 0x7f => make_ldr1r2_data(register::Single::A, register::Single::A, data), - 0x78 => make_ldr1r2_data(register::Single::A, register::Single::B, data), - 0x79 => make_ldr1r2_data(register::Single::A, register::Single::C, data), - 0x7A => make_ldr1r2_data(register::Single::A, register::Single::D, data), - 0x7B => make_ldr1r2_data(register::Single::A, register::Single::E, data), - 0x7C => make_ldr1r2_data(register::Single::A, register::Single::H, data), - 0x7D => make_ldr1r2_data(register::Single::A, register::Single::L, data), + 0x7f => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::A, + data, + ), + 0x78 => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::B, + data, + ), + 0x79 => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::C, + data, + ), + 0x7A => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::D, + data, + ), + 0x7B => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::E, + data, + ), + 0x7C => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::H, + data, + ), + 0x7D => make_ldr1r2_data( + register::SingleEightBit::A, + register::SingleEightBit::L, + data, + ), - 0x47 => make_ldr1r2_data(register::Single::B, register::Single::A, data), - 0x40 => make_ldr1r2_data(register::Single::B, register::Single::B, data), - 0x41 => make_ldr1r2_data(register::Single::B, register::Single::C, data), - 0x42 => make_ldr1r2_data(register::Single::B, register::Single::D, data), - 0x43 => make_ldr1r2_data(register::Single::B, register::Single::E, data), - 0x44 => make_ldr1r2_data(register::Single::B, register::Single::H, data), - 0x45 => make_ldr1r2_data(register::Single::B, register::Single::L, data), + 0x47 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::A, + data, + ), + 0x40 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::B, + data, + ), + 0x41 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::C, + data, + ), + 0x42 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::D, + data, + ), + 0x43 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::E, + data, + ), + 0x44 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::H, + data, + ), + 0x45 => make_ldr1r2_data( + register::SingleEightBit::B, + register::SingleEightBit::L, + data, + ), - 0x4F => make_ldr1r2_data(register::Single::C, register::Single::A, data), - 0x48 => make_ldr1r2_data(register::Single::C, register::Single::B, data), - 0x49 => make_ldr1r2_data(register::Single::C, register::Single::C, data), - 0x4A => make_ldr1r2_data(register::Single::C, register::Single::D, data), - 0x4B => make_ldr1r2_data(register::Single::C, register::Single::E, data), - 0x4C => make_ldr1r2_data(register::Single::C, register::Single::H, data), - 0x4D => make_ldr1r2_data(register::Single::C, register::Single::L, data), + 0x4F => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::A, + data, + ), + 0x48 => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::B, + data, + ), + 0x49 => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::C, + data, + ), + 0x4A => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::D, + data, + ), + 0x4B => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::E, + data, + ), + 0x4C => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::H, + data, + ), + 0x4D => make_ldr1r2_data( + register::SingleEightBit::C, + register::SingleEightBit::L, + data, + ), - 0x57 => make_ldr1r2_data(register::Single::D, register::Single::A, data), - 0x50 => make_ldr1r2_data(register::Single::D, register::Single::B, data), - 0x51 => make_ldr1r2_data(register::Single::D, register::Single::C, data), - 0x52 => make_ldr1r2_data(register::Single::D, register::Single::D, data), - 0x53 => make_ldr1r2_data(register::Single::D, register::Single::E, data), - 0x54 => make_ldr1r2_data(register::Single::D, register::Single::H, data), - 0x55 => make_ldr1r2_data(register::Single::D, register::Single::L, data), + 0x57 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::A, + data, + ), + 0x50 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::B, + data, + ), + 0x51 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::C, + data, + ), + 0x52 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::D, + data, + ), + 0x53 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::E, + data, + ), + 0x54 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::H, + data, + ), + 0x55 => make_ldr1r2_data( + register::SingleEightBit::D, + register::SingleEightBit::L, + data, + ), - 0x5F => make_ldr1r2_data(register::Single::E, register::Single::A, data), - 0x58 => make_ldr1r2_data(register::Single::E, register::Single::B, data), - 0x59 => make_ldr1r2_data(register::Single::E, register::Single::C, data), - 0x5A => make_ldr1r2_data(register::Single::E, register::Single::D, data), - 0x5B => make_ldr1r2_data(register::Single::E, register::Single::E, data), - 0x5C => make_ldr1r2_data(register::Single::E, register::Single::H, data), - 0x5D => make_ldr1r2_data(register::Single::E, register::Single::L, data), + 0x5F => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::A, + data, + ), + 0x58 => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::B, + data, + ), + 0x59 => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::C, + data, + ), + 0x5A => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::D, + data, + ), + 0x5B => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::E, + data, + ), + 0x5C => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::H, + data, + ), + 0x5D => make_ldr1r2_data( + register::SingleEightBit::E, + register::SingleEightBit::L, + data, + ), - 0x67 => make_ldr1r2_data(register::Single::H, register::Single::A, data), - 0x60 => make_ldr1r2_data(register::Single::H, register::Single::B, data), - 0x61 => make_ldr1r2_data(register::Single::H, register::Single::C, data), - 0x62 => make_ldr1r2_data(register::Single::H, register::Single::D, data), - 0x63 => make_ldr1r2_data(register::Single::H, register::Single::E, data), - 0x64 => make_ldr1r2_data(register::Single::H, register::Single::H, data), - 0x65 => make_ldr1r2_data(register::Single::H, register::Single::L, data), + 0x67 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::A, + data, + ), + 0x60 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::B, + data, + ), + 0x61 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::C, + data, + ), + 0x62 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::D, + data, + ), + 0x63 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::E, + data, + ), + 0x64 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::H, + data, + ), + 0x65 => make_ldr1r2_data( + register::SingleEightBit::H, + register::SingleEightBit::L, + data, + ), - 0x6F => make_ldr1r2_data(register::Single::L, register::Single::A, data), - 0x68 => make_ldr1r2_data(register::Single::L, register::Single::B, data), - 0x69 => make_ldr1r2_data(register::Single::L, register::Single::C, data), - 0x6A => make_ldr1r2_data(register::Single::L, register::Single::D, data), - 0x6B => make_ldr1r2_data(register::Single::L, register::Single::E, data), - 0x6c => make_ldr1r2_data(register::Single::L, register::Single::H, data), - 0x6D => make_ldr1r2_data(register::Single::L, register::Single::L, data), + 0x6F => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::A, + data, + ), + 0x68 => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::B, + data, + ), + 0x69 => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::C, + data, + ), + 0x6A => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::D, + data, + ), + 0x6B => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::E, + data, + ), + 0x6c => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::H, + data, + ), + 0x6D => make_ldr1r2_data( + register::SingleEightBit::L, + register::SingleEightBit::L, + data, + ), _ => Err(Error::UnknownOpcode(opcode)), } } } -fn make_ldr1r2_data(dst: register::Single, src: register::Single, data: &[u8]) -> ParseResult { +fn make_ldr1r2_data( + dst: register::SingleEightBit, + src: register::SingleEightBit, + data: &[u8], +) -> ParseResult { data.get(1..) .map(|remaining_data| { (