From e3a1748eb1d7e8937c4a6915843175fdead3d5f0 Mon Sep 17 00:00:00 2001 From: Cedrik Hoffmann Date: Thu, 23 Nov 2023 22:22:14 +0100 Subject: [PATCH] Add missing load instructions --- src/cpu/cpu.rs | 76 ++++++++++++++++++++++++++++++++++------- src/cpu/instructions.rs | 9 +++-- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/cpu/cpu.rs b/src/cpu/cpu.rs index c1d3aff..b8e081f 100644 --- a/src/cpu/cpu.rs +++ b/src/cpu/cpu.rs @@ -1,5 +1,5 @@ use crate::cpu::instructions::{JumpCondition, Target16Bit}; -use crate::cpu::registers::Registers; +use crate::cpu::registers::{Register8BitName, Registers}; use crate::memory::Memory; use super::instructions::Target8Bit; @@ -50,10 +50,7 @@ impl CPU { println!("[CPU] SET 0x{:x} {:?}", value, target); return self.pc.wrapping_add(2); } - Instruction::LD8(target, source) => { - println!("[CPU] LD {:?} to {:?}", source, target); - return self.pc.wrapping_add(2); - } + Instruction::LD8(target, source) => self.match_8bit_load(&target, &source), Instruction::LD16(target, source) => { let value = self.match_16bit_load_source(source); return self.match_16bit_load(target, value); @@ -65,9 +62,27 @@ impl CPU { self.match_dec16(Target16Bit::HL); return self.pc.wrapping_add(1); } + Instruction::LDC => { + let a_value = self.register.read_a(); + let c_value = self.register.get_8bit(&Register8BitName::C); + self.add_memory_ff00(a_value, c_value); + return self.pc.wrapping_add(1); + } + Instruction::LDHA => { + let a_value = self.register.read_a(); + let n = self.read_next_mem(); + self.add_memory_ff00(a_value, n); + return self.pc.wrapping_add(2); + } } } + + fn add_memory_ff00(&mut self, register_value: u8, n: u8) { + let address = 0xff00 + (n as u16); + self.memory.write_byte(address, register_value); + } + fn match_bit(&mut self, target: Target8Bit, value: u8) -> u16 { match target { Target8Bit::A | @@ -90,8 +105,20 @@ impl CPU { } } - fn match_8bit_load(&mut self, target: Target8Bit, value: u8) -> u16 { - return match target { + fn match_8bit_load(&mut self, target: &Target8Bit, source: &Target8Bit) -> u16 { + let value = match source { + Target8Bit::A | + Target8Bit::B | + Target8Bit::C | + Target8Bit::D | + Target8Bit::E | + Target8Bit::H | + Target8Bit::L => self.register.get_8bit(source.into()), + Target8Bit::D8 => self.read_next_mem(), + Target8Bit::HLI => self.get_memory_by_hl() + }; + + match target { Target8Bit::A | Target8Bit::B | Target8Bit::C @@ -100,15 +127,27 @@ impl CPU { | Target8Bit::H | Target8Bit::L => { self.register.set_8bit(target.into(), value); - self.pc.wrapping_add(1) } Target8Bit::D8 => { - self.pc.wrapping_add(2) + self.register.set_8bit(target.into(), value); } Target8Bit::HLI => { - self.pc.wrapping_add(2) + let address = self.register.get_16bit(&Register16BitName::HL); + self.memory.write_byte(address, value); } }; + + return match source { + Target8Bit::A | + Target8Bit::B | + Target8Bit::C | + Target8Bit::D | + Target8Bit::E | + Target8Bit::H | + Target8Bit::L => self.pc.wrapping_add(1), + Target8Bit::D8 | + Target8Bit::HLI => self.pc.wrapping_add(2), + }; } fn match_16bit_load(&mut self, target: Target16Bit, value: u16) -> u16 { @@ -179,9 +218,20 @@ impl CPU { | Target8Bit::D | Target8Bit::E | Target8Bit::H - | Target8Bit::L => self.exec_inc(self.register.get_8bit(target.into())), - Target8Bit::D8 => self.exec_inc(self.read_next_mem()), - Target8Bit::HLI => self.exec_inc(self.get_memory_by_hl()), + | Target8Bit::L => { + let register: &Register8BitName = target.into(); + let register_value = self.register.get_8bit(register); + let value = self.inc(register_value); + self.register.set_8bit(register, value); + return self.pc.wrapping_add(1); + } + Target8Bit::HLI => { + let register_value = self.get_memory_by_hl(); + let value = self.inc(register_value); + self.memory.write_byte(self.register.get_16bit(&Register16BitName::HL), value); + return self.pc.wrapping_add(2); + } + Target8Bit::D8 => panic!("Should not possible"), } } diff --git a/src/cpu/instructions.rs b/src/cpu/instructions.rs index e5ddd61..cf3fd3e 100644 --- a/src/cpu/instructions.rs +++ b/src/cpu/instructions.rs @@ -27,6 +27,8 @@ pub enum Instruction { LD8(Target8Bit, Target8Bit), LD16(Target16Bit, Source16Bit), LDD, + LDC, + LDHA, // CB Flag BIT(u8, Target8Bit), @@ -34,7 +36,7 @@ pub enum Instruction { SET(u8, Target8Bit), } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Target8Bit { A, B, @@ -496,6 +498,7 @@ impl Instruction { 0x7c => Some(Instruction::LD8(Target8Bit::A, Target8Bit::H)), 0x7d => Some(Instruction::LD8(Target8Bit::A, Target8Bit::L)), 0x7e => Some(Instruction::LD8(Target8Bit::A, Target8Bit::HLI)), + 0x3e => Some(Instruction::LD8(Target8Bit::A, Target8Bit::D8)), 0x40 => Some(Instruction::LD8(Target8Bit::B, Target8Bit::B)), 0x41 => Some(Instruction::LD8(Target8Bit::B, Target8Bit::C)), @@ -552,6 +555,7 @@ impl Instruction { 0x74 => Some(Instruction::LD8(Target8Bit::HLI, Target8Bit::H)), 0x75 => Some(Instruction::LD8(Target8Bit::HLI, Target8Bit::L)), 0x36 => Some(Instruction::LD8(Target8Bit::HLI, Target8Bit::D8)), + 0x77 => Some(Instruction::LD8(Target8Bit::HLI, Target8Bit::A)), 0x01 => Some(Instruction::LD16(Target16Bit::BC, Source16Bit::D16)), 0x11 => Some(Instruction::LD16(Target16Bit::DE, Source16Bit::D16)), @@ -574,7 +578,8 @@ impl Instruction { 0x33 => Some(Instruction::INC16(Target16Bit::SP)), 0x32 => Some(Instruction::LDD), - + 0xe2 => Some(Instruction::LDC), + 0xe0 => Some(Instruction::LDHA), _ => { eprintln!("[INS] Missing byte Instruction 0x{:x}", byte);