152 lines
4.3 KiB
Rust
152 lines
4.3 KiB
Rust
use crate::{
|
|
connect::{PocketCamera, Renderer},
|
|
processor::{memory::mmio::gpu::Colour, Cpu, Direction, Flags, Reg8, SplitRegister},
|
|
util::{clear_bit, get_bit, set_bit},
|
|
};
|
|
|
|
impl<ColourFormat, R, C> Cpu<ColourFormat, R, C>
|
|
where
|
|
ColourFormat: From<Colour> + Clone,
|
|
R: Renderer<ColourFormat>,
|
|
C: PocketCamera + Send + 'static,
|
|
{
|
|
pub(crate) fn and(&mut self, first: u8, second: u8) -> u8 {
|
|
let result = first & second;
|
|
self.set_or_clear_flag(Flags::Zero, result == 0x0);
|
|
self.clear_flag(Flags::NSubtract);
|
|
self.clear_flag(Flags::Carry);
|
|
self.set_flag(Flags::HalfCarry);
|
|
result
|
|
}
|
|
|
|
pub(crate) fn xor(&mut self, first: u8, second: u8) -> u8 {
|
|
let result = first ^ second;
|
|
self.set_or_clear_flag(Flags::Zero, result == 0x0);
|
|
self.clear_flag(Flags::NSubtract);
|
|
self.clear_flag(Flags::Carry);
|
|
self.clear_flag(Flags::HalfCarry);
|
|
result
|
|
}
|
|
|
|
pub(crate) fn or(&mut self, first: u8, second: u8) -> u8 {
|
|
let result = first | second;
|
|
self.set_or_clear_flag(Flags::Zero, result == 0x0);
|
|
self.clear_flag(Flags::NSubtract);
|
|
self.clear_flag(Flags::Carry);
|
|
self.clear_flag(Flags::HalfCarry);
|
|
result
|
|
}
|
|
|
|
pub(crate) fn cp(&mut self, first: u8, second: u8) {
|
|
self.sub_u8s(first, second, false);
|
|
}
|
|
|
|
pub(crate) fn add(&mut self, first: u8, second: u8) -> u8 {
|
|
self.add_u8s(first, second, false)
|
|
}
|
|
|
|
pub(crate) fn adc(&mut self, first: u8, second: u8) -> u8 {
|
|
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, false)
|
|
}
|
|
|
|
pub(crate) fn sbc(&mut self, first: u8, second: u8) -> u8 {
|
|
self.sub_u8s(first, second, self.is_flag(Flags::Carry))
|
|
}
|
|
|
|
pub(crate) fn inc(&mut self, reg: Reg8) {
|
|
let result = self.reg.get_8(reg);
|
|
let val = self.inc_raw(result);
|
|
self.reg.set_8(reg, val);
|
|
}
|
|
|
|
pub(crate) fn dec(&mut self, reg: Reg8) {
|
|
let result = self.reg.get_8(reg);
|
|
let val = self.dec_flags(result);
|
|
self.reg.set_8(reg, val);
|
|
}
|
|
|
|
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_with_carry(byte, Direction::Left)
|
|
}
|
|
|
|
pub(crate) fn rrc(&mut self, byte: u8) -> u8 {
|
|
self.rotate_with_carry(byte, Direction::Right)
|
|
}
|
|
|
|
pub(crate) fn rl(&mut self, byte: u8) -> u8 {
|
|
self.rotate(byte, Direction::Left)
|
|
}
|
|
|
|
pub(crate) fn rr(&mut self, byte: u8) -> u8 {
|
|
self.rotate(byte, Direction::Right)
|
|
}
|
|
|
|
pub(crate) fn sla(&mut self, byte: u8) -> u8 {
|
|
self.shift(byte, Direction::Left)
|
|
}
|
|
|
|
pub(crate) fn sra(&mut self, byte: u8) -> u8 {
|
|
let b = get_bit(byte, 7);
|
|
let val = self.shift(byte, Direction::Right);
|
|
if b {
|
|
val + 0b10000000
|
|
} else {
|
|
val
|
|
}
|
|
}
|
|
|
|
pub(crate) fn srl(&mut self, byte: u8) -> u8 {
|
|
self.shift(byte, Direction::Right)
|
|
}
|
|
|
|
pub(crate) fn swap(&mut self, byte: u8) -> u8 {
|
|
let swapped = (byte & 0x0F) << 4 | (byte & 0xF0) >> 4;
|
|
self.set_or_clear_flag(Flags::Zero, swapped == 0x0);
|
|
self.clear_flag(Flags::Carry);
|
|
self.clear_flag(Flags::HalfCarry);
|
|
self.clear_flag(Flags::NSubtract);
|
|
swapped
|
|
}
|
|
|
|
pub(crate) fn bit(&mut self, byte: u8, bit: u8) {
|
|
self.set_or_clear_flag(Flags::Zero, !get_bit(byte, bit));
|
|
self.clear_flag(Flags::NSubtract);
|
|
self.set_flag(Flags::HalfCarry);
|
|
}
|
|
|
|
pub(crate) fn rst(&mut self, address: u8) {
|
|
self.push(self.reg.pc);
|
|
self.reg.pc.set_high(0x0);
|
|
self.reg.pc.set_low(address);
|
|
}
|
|
|
|
pub(crate) fn ret(&mut self) {
|
|
self.reg.pc = self.pop_word();
|
|
}
|
|
|
|
pub(crate) fn jr(&mut self, jump: i8) {
|
|
self.reg.pc = self.reg.pc.wrapping_add_signed(jump.into());
|
|
}
|
|
}
|
|
|
|
pub(crate) fn res(byte: u8, bit: u8) -> u8 {
|
|
clear_bit(byte, bit)
|
|
}
|
|
|
|
pub(crate) fn set(byte: u8, bit: u8) -> u8 {
|
|
set_bit(byte, bit)
|
|
}
|