extra instructions + fix caps on flags
This commit is contained in:
parent
fffb6e0278
commit
7460d31913
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue