diff --git a/src/processor/instructions/instructions.rs b/src/processor/instructions/instructions.rs index 8e96ca0..8683d62 100644 --- a/src/processor/instructions/instructions.rs +++ b/src/processor/instructions/instructions.rs @@ -1,4 +1,4 @@ -use crate::processor::{get_bit, Direction, SplitRegister, CPU, FLAGS}; +use crate::processor::{get_bit, Direction, Flags, Reg8, SplitRegister, CPU}; impl CPU { pub(crate) fn add(&mut self, first: u8, second: u8) -> u8 { @@ -6,7 +6,7 @@ impl CPU { } pub(crate) fn adc(&mut self, first: u8, second: u8) -> u8 { - let val = second + self.get_flag(FLAGS::Carry); + let val = second + self.get_flag(Flags::Carry); self.add_u8s(first, val) } @@ -15,24 +15,46 @@ impl CPU { } pub(crate) fn sbc(&mut self, first: u8, second: u8) -> u8 { - let val = second + self.get_flag(FLAGS::Carry); + let val = second + self.get_flag(Flags::Carry); self.sub_u8s(first, val) } - pub(crate) fn inc(&mut self, val: u8) -> u8 { - self.add_u8s(val, 0x1) + pub(crate) fn inc(&mut self, reg: Reg8) { + let result = self.reg.get_8(reg).wrapping_add(0x1); + self.clear_flag(Flags::NSubtract); + self.set_or_clear_flag(Flags::Zero, result == 0x0); + self.set_or_clear_flag( + Flags::HalfCarry, + (((self.reg.get_8(reg) & 0xF).wrapping_add(0x1 & 0xF)) & 0x10) == 0x10, + ); + self.reg.set_8(reg, result); } - pub(crate) fn dec(&mut self, val: u8) -> u8 { - self.sub_u8s(val, 0x1) + pub(crate) fn dec(&mut self, reg: Reg8) { + let result = self.reg.get_8(reg).wrapping_sub(0x1); + self.set_flag(Flags::NSubtract); + self.set_or_clear_flag(Flags::Zero, result == 0x0); + self.set_or_clear_flag( + Flags::HalfCarry, + (((self.reg.get_8(reg) & 0xF).wrapping_sub(0x1 & 0xF)) & 0x10) == 0x10, + ); + self.reg.set_8(reg, result); + } + + pub(crate) fn inc_pair(&mut self, val: u16) -> u16 { + val.wrapping_add(0x1) + } + + pub(crate) fn dec_pair(&mut self, val: u16) -> u16 { + val.wrapping_sub(0x1) } pub(crate) fn rlc(&mut self, byte: u8) -> u8 { - self.rotate_c(byte, Direction::Left) + self.rotate_with_carry(byte, Direction::Left) } pub(crate) fn rrc(&mut self, byte: u8) -> u8 { - self.rotate_c(byte, Direction::Right) + self.rotate_with_carry(byte, Direction::Right) } pub(crate) fn rl(&mut self, byte: u8) -> u8 { @@ -66,4 +88,8 @@ impl CPU { self.reg.pc.set_high(0x0); self.reg.pc.set_low(address); } + + pub(crate) fn jr(&mut self, jump: i8) { + self.reg.pc = self.reg.pc.wrapping_add_signed(jump.into()); + } } diff --git a/src/processor/instructions/primitives.rs b/src/processor/instructions/primitives.rs index 69f5bd9..4faf6cc 100644 --- a/src/processor/instructions/primitives.rs +++ b/src/processor/instructions/primitives.rs @@ -1,7 +1,7 @@ use std::ops::{BitAnd, BitOr, BitXor}; use crate::{ - processor::{get_bit, get_rotation_carry, rotate, Direction, SplitRegister, CPU, FLAGS}, + processor::{get_bit, get_rotation_carry, rotate, Direction, Flags, SplitRegister, CPU}, verbose_println, }; @@ -38,23 +38,23 @@ impl CPU { word } - pub(crate) fn rotate_c(&mut self, byte: u8, direction: Direction) -> u8 { + pub(crate) fn rotate_with_carry(&mut self, byte: u8, direction: Direction) -> u8 { let (mut rotated, carry) = rotate(byte, &direction); if carry { rotated += get_rotation_carry(&direction); - self.set_flag(FLAGS::Carry); + self.set_flag(Flags::Carry); } return rotated; } pub(crate) fn rotate(&mut self, byte: u8, direction: Direction) -> u8 { - let old_carry = self.get_flag(FLAGS::Carry); + let old_carry = self.get_flag(Flags::Carry); let (mut rotated, carry) = rotate(byte, &direction); if old_carry > 0 { rotated += get_rotation_carry(&direction); } if carry { - self.set_flag(FLAGS::Carry); + self.set_flag(Flags::Carry); } return rotated; } @@ -62,16 +62,16 @@ impl CPU { pub(crate) fn shift(&mut self, byte: u8, direction: Direction) -> u8 { let (rotated, carry) = rotate(byte, &direction); if carry { - self.set_flag(FLAGS::Carry); + self.set_flag(Flags::Carry); } return rotated; } pub(crate) fn bit(&mut self, byte: u8, bit: u8) { - self.set_or_clear_flag(FLAGS::Zero, !get_bit(byte, bit)); + self.set_or_clear_flag(Flags::Zero, !get_bit(byte, bit)); } - pub(crate) fn get_flag(&mut self, flag: FLAGS) -> u8 { + pub(crate) fn get_flag(&mut self, flag: Flags) -> u8 { if get_bit(self.reg.af.get_low(), flag as u8) { 0x1 } else { @@ -79,8 +79,12 @@ impl CPU { } } - pub(crate) fn set_flag(&mut self, flag: FLAGS) { - if flag == FLAGS::Zero { + pub(crate) fn is_flag(&mut self, flag: Flags) -> bool { + get_bit(self.reg.af.get_low(), flag as u8) + } + + pub(crate) fn set_flag(&mut self, flag: Flags) { + if flag == Flags::Zero { verbose_println!("setting z flag"); } verbose_println!( @@ -96,19 +100,19 @@ impl CPU { ); } - pub(crate) fn clear_flag(&mut self, flag: FLAGS) { + pub(crate) fn clear_flag(&mut self, flag: Flags) { self.reg .af .set_low(self.reg.af.get_low().bitand(!(1 << flag as u8))); } - pub(crate) fn toggle_flag(&mut self, flag: FLAGS) { + pub(crate) fn toggle_flag(&mut self, flag: Flags) { self.reg .af .set_low(self.reg.af.get_low().bitxor(1 << flag as u8)); } - pub(crate) fn set_or_clear_flag(&mut self, flag: FLAGS, state: bool) { + pub(crate) fn set_or_clear_flag(&mut self, flag: Flags, state: bool) { if state { self.set_flag(flag) } else { @@ -118,11 +122,11 @@ impl CPU { pub(crate) fn add_u8s(&mut self, first: u8, second: u8) -> u8 { let (result, carry) = first.overflowing_add(second); - self.clear_flag(FLAGS::NSubtract); - self.set_or_clear_flag(FLAGS::Carry, carry); - self.set_or_clear_flag(FLAGS::Zero, result == 0x0); + self.clear_flag(Flags::NSubtract); + self.set_or_clear_flag(Flags::Carry, carry); + self.set_or_clear_flag(Flags::Zero, result == 0x0); self.set_or_clear_flag( - FLAGS::HalfCarry, + Flags::HalfCarry, (((first & 0xF).wrapping_add(second & 0xF)) & 0x10) == 0x10, ); return result; @@ -130,11 +134,11 @@ impl CPU { pub(crate) fn add_u16s(&mut self, first: u16, second: u16) -> u16 { let (result, carry) = first.overflowing_add(second); - self.clear_flag(FLAGS::NSubtract); - self.set_or_clear_flag(FLAGS::Carry, carry); - self.set_or_clear_flag(FLAGS::Zero, result == 0x0); + self.clear_flag(Flags::NSubtract); + self.set_or_clear_flag(Flags::Carry, carry); + self.set_or_clear_flag(Flags::Zero, result == 0x0); self.set_or_clear_flag( - FLAGS::HalfCarry, + Flags::HalfCarry, (((first & 0xFFF).wrapping_add(second & 0xFFF)) & 0x1000) == 0x1000, ); return result; @@ -142,11 +146,11 @@ impl CPU { pub(crate) fn sub_u8s(&mut self, first: u8, second: u8) -> u8 { let (result, carry) = first.overflowing_sub(second); - self.set_flag(FLAGS::NSubtract); - self.set_or_clear_flag(FLAGS::Carry, carry); - self.set_or_clear_flag(FLAGS::Zero, result == 0x0); + self.set_flag(Flags::NSubtract); + self.set_or_clear_flag(Flags::Carry, carry); + self.set_or_clear_flag(Flags::Zero, result == 0x0); self.set_or_clear_flag( - FLAGS::HalfCarry, + Flags::HalfCarry, (((first & 0xF).wrapping_sub(second & 0xF)) & 0x10) == 0x10, ); return result; @@ -154,11 +158,11 @@ impl CPU { pub(crate) fn sub_u16s(&mut self, first: u16, second: u16) -> u16 { let (result, carry) = first.overflowing_sub(second); - self.set_flag(FLAGS::NSubtract); - self.set_or_clear_flag(FLAGS::Carry, carry); - self.set_or_clear_flag(FLAGS::Zero, result == 0x0); + self.set_flag(Flags::NSubtract); + self.set_or_clear_flag(Flags::Carry, carry); + self.set_or_clear_flag(Flags::Zero, result == 0x0); self.set_or_clear_flag( - FLAGS::HalfCarry, + Flags::HalfCarry, (((first & 0xFFF).wrapping_sub(second & 0xFFF)) & 0x1000) == 0x1000, ); return result; diff --git a/src/processor/mod.rs b/src/processor/mod.rs index cf5bd8e..7f5fd78 100644 --- a/src/processor/mod.rs +++ b/src/processor/mod.rs @@ -6,7 +6,7 @@ mod instructions; mod opcodes; #[derive(PartialEq)] -pub(crate) enum FLAGS { +pub(crate) enum Flags { Zero = 7, NSubtract = 6, HalfCarry = 5, @@ -45,6 +45,7 @@ impl CPU { } } +#[derive(Clone, Copy)] pub enum Reg8 { A, F,