From 7feea042f1a9b1768cf21b32e91911e8a0adbd9c Mon Sep 17 00:00:00 2001 From: pcasaretto Date: Sun, 7 Apr 2024 17:17:14 -0300 Subject: [PATCH] implement the ld r r instruction family --- src/instructions/ld.rs | 26 ++++++++++++++++- src/instructions/mod.rs | 64 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 24 ++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/src/instructions/ld.rs b/src/instructions/ld.rs index c675404..5d36377 100644 --- a/src/instructions/ld.rs +++ b/src/instructions/ld.rs @@ -1,4 +1,4 @@ -use crate::{Register16bTarget, CPU}; +use crate::{Register16bTarget, RegisterTarget, CPU}; pub fn ld_d16_u16(reg: Register16bTarget) -> impl Fn(&mut CPU) { move |cpu: &mut CPU| { @@ -9,9 +9,18 @@ pub fn ld_d16_u16(reg: Register16bTarget) -> impl Fn(&mut CPU) { } } +pub fn ld_r_r(src: RegisterTarget, dest: RegisterTarget) -> impl Fn(&mut CPU) { + move |cpu: &mut CPU| { + let value = cpu.registers.get_u8(src); + cpu.registers.set_u8(dest, value); + cpu.pc += 1; + } +} + #[cfg(test)] mod tests { use super::*; + use crate::Registers; #[test] fn test_ld_d16_u16() { @@ -22,4 +31,19 @@ mod tests { assert_eq!(cpu.registers.get_u16(Register16bTarget::BC), 0x0201); assert_eq!(cpu.pc, 3); } + + #[test] + fn test_ld_r_r() { + let mut cpu = CPU { + registers: Registers { + a: 0, + b: 1, + ..Default::default() + }, + ..Default::default() + }; + ld_r_r(RegisterTarget::B, RegisterTarget::A)(&mut cpu); + assert_eq!(cpu.registers.get_u8(RegisterTarget::A), 0x01); + assert_eq!(cpu.pc, 1); + } } diff --git a/src/instructions/mod.rs b/src/instructions/mod.rs index 9c5c688..1542735 100644 --- a/src/instructions/mod.rs +++ b/src/instructions/mod.rs @@ -13,6 +13,70 @@ pub fn from_byte(byte: u8) -> Box { 0x00 => Box::new(nop::nop()), 0x21 => Box::new(ld::ld_d16_u16(Register16bTarget::HL)), 0x33 => Box::new(inc::inc_sp()), + 0x40 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::B)), + 0x41 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::C)), + 0x42 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::D)), + 0x43 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::E)), + 0x44 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::H)), + 0x45 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::L)), + // 0x46 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::A)), + 0x47 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::A)), + 0x48 => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::B)), + 0x49 => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::C)), + 0x4a => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::D)), + 0x4b => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::E)), + 0x4c => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::H)), + 0x4d => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::L)), + // 0x4e => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::A)), + 0x4f => Box::new(ld::ld_r_r(RegisterTarget::C, RegisterTarget::A)), + 0x50 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::B)), + 0x51 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::C)), + 0x52 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::D)), + 0x53 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::E)), + 0x54 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::H)), + 0x55 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::L)), + // 0x56 => Box::new(ld::ld_r_r(RegisterTarget::D, Register16bTarget::HL)), + 0x57 => Box::new(ld::ld_r_r(RegisterTarget::D, RegisterTarget::A)), + 0x58 => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::B)), + 0x59 => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::C)), + 0x5A => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::D)), + 0x5B => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::E)), + 0x5C => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::H)), + 0x5D => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::L)), + // 0x5E => Box::new(ld::ld_r_r(RegisterTarget::E, Register16bTarget::HL)), + 0x5F => Box::new(ld::ld_r_r(RegisterTarget::E, RegisterTarget::A)), + 0x60 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::B)), + 0x61 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::C)), + 0x62 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::D)), + 0x63 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::E)), + 0x64 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::H)), + 0x65 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::L)), + // 0x66 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::A)), + 0x67 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::A)), + 0x68 => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::B)), + 0x69 => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::C)), + 0x6A => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::D)), + 0x6B => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::E)), + 0x6C => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::H)), + 0x6D => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::L)), + // 0x6E => Box::new(ld::ld_r_r(RegisterTarget::L, Register16bTarget::HL)), + 0x6F => Box::new(ld::ld_r_r(RegisterTarget::L, RegisterTarget::A)), + // 0x70 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::B)), + // 0x71 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::C)), + // 0x72 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::D)), + // 0x73 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::E)), + // 0x74 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::H)), + // 0x75 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::L)), + // 0x76 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::A)), + // 0x77 => Box::new(ld::ld_r_r(RegisterTarget::H, RegisterTarget::A)), + 0x78 => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::B)), + 0x79 => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::C)), + 0x7A => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::D)), + 0x7B => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::E)), + 0x7C => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::H)), + 0x7D => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::L)), + // 0x7E => Box::new(ld::ld_r_r(RegisterTarget::A, Register16bTarget::HL)), + 0x7F => Box::new(ld::ld_r_r(RegisterTarget::A, RegisterTarget::A)), 0x87 => Box::new(add::add(RegisterTarget::A)), 0x80 => Box::new(add::add(RegisterTarget::B)), 0x81 => Box::new(add::add(RegisterTarget::C)), diff --git a/src/lib.rs b/src/lib.rs index 5783d35..bf6b87e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,30 @@ pub struct Registers { } impl Registers { + pub fn get_u8(&self, target: RegisterTarget) -> u8 { + match target { + RegisterTarget::A => self.a, + RegisterTarget::B => self.b, + RegisterTarget::C => self.c, + RegisterTarget::D => self.d, + RegisterTarget::E => self.e, + RegisterTarget::H => self.h, + RegisterTarget::L => self.l, + } + } + + pub fn set_u8(&mut self, target: RegisterTarget, value: u8) { + match target { + RegisterTarget::A => self.a = value, + RegisterTarget::B => self.b = value, + RegisterTarget::C => self.c = value, + RegisterTarget::D => self.d = value, + RegisterTarget::E => self.e = value, + RegisterTarget::H => self.h = value, + RegisterTarget::L => self.l = value, + } + } + pub fn get_u16(&self, target: Register16bTarget) -> u16 { match target { Register16bTarget::BC => u16::from_be_bytes([self.b, self.c]),