diff --git a/src/main.rs b/src/main.rs index 949b788..5a59a66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,10 @@ -#![feature(exclusive_range_pattern, let_chains, slice_flatten, async_closure)] +#![feature( + exclusive_range_pattern, + let_chains, + slice_flatten, + async_closure, + bigint_helper_methods +)] mod constants; mod processor; diff --git a/src/processor/instructions/instructions.rs b/src/processor/instructions/instructions.rs index 356665c..b39e8bc 100644 --- a/src/processor/instructions/instructions.rs +++ b/src/processor/instructions/instructions.rs @@ -32,25 +32,25 @@ impl Cpu { } pub(crate) fn cp(&mut self, first: u8, second: u8) { - self.sub_u8s(first, second); + self.sub_u8s(first, second, false); } pub(crate) fn add(&mut self, first: u8, second: u8) -> u8 { - self.add_u8s(first, second) + self.add_u8s(first, second, false) } pub(crate) fn adc(&mut self, first: u8, second: u8) -> u8 { - let val = second.wrapping_add(self.get_flag(Flags::Carry)); - self.add_u8s(first, val) + let carry = self.is_flag(Flags::Carry); + self.clear_flag(Flags::Carry); + self.add_u8s(first, second, carry) } pub(crate) fn sub(&mut self, first: u8, second: u8) -> u8 { - self.sub_u8s(first, second) + self.sub_u8s(first, second, false) } pub(crate) fn sbc(&mut self, first: u8, second: u8) -> u8 { - let val = second.wrapping_add(self.get_flag(Flags::Carry)); - self.sub_u8s(first, val) + self.sub_u8s(first, second, self.is_flag(Flags::Carry)) } pub(crate) fn inc(&mut self, reg: Reg8) { diff --git a/src/processor/instructions/primitives.rs b/src/processor/instructions/primitives.rs index 0520a1d..e50cfac 100644 --- a/src/processor/instructions/primitives.rs +++ b/src/processor/instructions/primitives.rs @@ -1,6 +1,6 @@ use crate::{ processor::{Cpu, Direction, Flags, SplitRegister}, - util::{get_bit, get_rotation_carry, rotate}, + util::{get_bit, get_rotation_carry, rotate, Nibbles}, }; use std::ops::{BitAnd, BitOr}; @@ -82,14 +82,6 @@ impl Cpu { rotated } - pub(crate) fn get_flag(&mut self, flag: Flags) -> u8 { - if get_bit(self.reg.af.get_low(), flag as u8) { - 0x1 - } else { - 0x0 - } - } - pub(crate) fn is_flag(&self, flag: Flags) -> bool { get_bit(self.reg.af.get_low(), flag as u8) } @@ -128,14 +120,14 @@ impl Cpu { result } - pub(crate) fn add_u8s(&mut self, first: u8, second: u8) -> u8 { - let (result, carry) = first.overflowing_add(second); + pub(crate) fn add_u8s(&mut self, first: u8, second: u8, with_carry: bool) -> u8 { + let (result, carry) = first.carrying_add(second, with_carry); 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, - (((first & 0xF).wrapping_add(second & 0xF)) & 0x10) == 0x10, + first.get_low_nibble() + second.get_low_nibble() + if with_carry { 1 } else { 0 } > 0xF, ); result } @@ -151,14 +143,15 @@ impl Cpu { result } - pub(crate) fn sub_u8s(&mut self, first: u8, second: u8) -> u8 { - let (result, carry) = first.overflowing_sub(second); + pub(crate) fn sub_u8s(&mut self, first: u8, second: u8, with_carry: bool) -> u8 { + let (result, carry) = first.borrowing_sub(second, with_carry); 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, - (((first & 0xF).wrapping_sub(second & 0xF)) & 0x10) == 0x10, + first.get_low_nibble() - (second.get_low_nibble() + if with_carry { 1 } else { 0 }) + > 0xF, ); result } diff --git a/src/processor/opcodes.rs b/src/processor/opcodes.rs index b76a9b2..2bc00fc 100644 --- a/src/processor/opcodes.rs +++ b/src/processor/opcodes.rs @@ -951,7 +951,7 @@ impl Cpu { } 0xC6 => { let byte = self.ld_immediate_byte(); - let val = self.add_u8s(self.reg.get_8(Reg8::A), byte); + let val = self.add_u8s(self.reg.get_8(Reg8::A), byte, false); self.reg.set_8(Reg8::A, val); 2 } @@ -1047,7 +1047,7 @@ impl Cpu { } 0xD6 => { let byte = self.ld_immediate_byte(); - let val = self.sub_u8s(self.reg.get_8(Reg8::A), byte); + let val = self.sub_u8s(self.reg.get_8(Reg8::A), byte, false); self.reg.set_8(Reg8::A, val); 2 }