From 14cfdc15f627d21121a8eeb13fb2bc15b54db279 Mon Sep 17 00:00:00 2001 From: Cedrik Hoffmann Date: Thu, 23 Nov 2023 22:37:00 +0100 Subject: [PATCH] Add POP and PUSH --- src/cpu/cpu.rs | 26 ++++++++++++++++++++++++++ src/cpu/instructions.rs | 21 +++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/cpu/cpu.rs b/src/cpu/cpu.rs index b8e081f..34c0d21 100644 --- a/src/cpu/cpu.rs +++ b/src/cpu/cpu.rs @@ -74,9 +74,35 @@ impl CPU { self.add_memory_ff00(a_value, n); return self.pc.wrapping_add(2); } + Instruction::PUSH(target) => { + println!("[CPU] PUSH {:?}", target); + return self.pc.wrapping_add(1); + } + Instruction::POP(target) => { + println!("[CPU] POP {:?}", target); + return self.pc.wrapping_add(1); + } } } + fn push(&mut self, value: u16) { + let sp_value = self.register.get_16bit(&Register16BitName::SP).wrapping_sub(1); + self.register.set_16bit(&Register16BitName::SP, sp_value); + self.memory.write_byte(sp_value, ((value & 0xff00) >> 8) as u8); + + let sp_value = self.register.get_16bit(&Register16BitName::SP).wrapping_sub(1); + self.register.set_16bit(&Register16BitName::SP, sp_value); + self.memory.write_byte(sp_value, (value & 0xff) as u8); + } + + fn pop(&mut self) -> u16 { + let lsb = self.memory.read_byte(self.register.get_16bit(&Register16BitName::SP)) as u16; + self.register.set_16bit(&Register16BitName::SP, self.register.get_16bit(&Register16BitName::SP).wrapping_add(1)); + + let msb = self.memory.read_byte(self.register.get_16bit(&Register16BitName::SP)) as u16; + self.register.set_16bit(&Register16BitName::SP, self.register.get_16bit(&Register16BitName::SP).wrapping_add(1)); + return (msb << 8) | lsb; + } fn add_memory_ff00(&mut self, register_value: u8, n: u8) { let address = 0xff00 + (n as u16); diff --git a/src/cpu/instructions.rs b/src/cpu/instructions.rs index cf3fd3e..f1c2472 100644 --- a/src/cpu/instructions.rs +++ b/src/cpu/instructions.rs @@ -3,6 +3,8 @@ use super::registers::{Register16BitName, Register8BitName}; #[derive(Debug)] pub enum Instruction { NOP, + PUSH(StackTarget), + POP(StackTarget), // Arithmetic Instructions ADD(Target8Bit), ADC(Target8Bit), @@ -36,6 +38,15 @@ pub enum Instruction { SET(u8, Target8Bit), } + +#[derive(Debug)] +pub enum StackTarget { + AF, + BC, + DE, + HL, +} + #[derive(Debug, PartialEq)] pub enum Target8Bit { A, @@ -581,6 +592,16 @@ impl Instruction { 0xe2 => Some(Instruction::LDC), 0xe0 => Some(Instruction::LDHA), + 0xf5 => Some(Instruction::PUSH(StackTarget::AF)), + 0xc5 => Some(Instruction::PUSH(StackTarget::BC)), + 0xd5 => Some(Instruction::PUSH(StackTarget::DE)), + 0xe5 => Some(Instruction::PUSH(StackTarget::HL)), + + 0xf1 => Some(Instruction::POP(StackTarget::AF)), + 0xc1 => Some(Instruction::POP(StackTarget::BC)), + 0xd1 => Some(Instruction::POP(StackTarget::DE)), + 0xe1 => Some(Instruction::POP(StackTarget::HL)), + _ => { eprintln!("[INS] Missing byte Instruction 0x{:x}", byte); None