Skip to content

Commit

Permalink
split instruction execution code across cpu execution submodules
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanballs committed Sep 11, 2024
1 parent b55cf92 commit dd0a821
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 276 deletions.
57 changes: 41 additions & 16 deletions src/cpu/alu.rs → src/cpu/execution/alu.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use crate::{
cpu::CPU,
instructions::{r16::R16, r8::R8},
mmu::MMU,
};

use super::CPU;

impl CPU {
// bitwise operations
pub(super) fn and(&mut self, b: u8) {
/*
*
* Bitwise Operations
*
*/
pub(in crate::cpu) fn and(&mut self, b: u8) {
let result = b & self.registers.a;
self.registers.a = result;

Expand All @@ -17,7 +20,7 @@ impl CPU {
self.registers.f.carry = false;
}

pub(super) fn or(&mut self, b: u8) {
pub(in crate::cpu) fn or(&mut self, b: u8) {
let result = b | self.registers.a;
self.registers.a = result;

Expand All @@ -27,7 +30,7 @@ impl CPU {
self.registers.f.subtract = false;
}

pub(super) fn xor(&mut self, b: u8) {
pub(in crate::cpu) fn xor(&mut self, b: u8) {
let result = b ^ self.registers.a;
self.registers.a = result;

Expand All @@ -37,20 +40,24 @@ impl CPU {
self.registers.f.subtract = false;
}

// increment/decrement
pub(super) fn inc_r16(&mut self, a: R16) {
/*
*
* Increment & Decrement
*
*/
pub(in crate::cpu) fn inc_r16(&mut self, a: R16) {
let value = self.registers.get_r16(a);
let result = value.wrapping_add(1);
self.registers.set_r16(a, result);
}

pub(super) fn dec_r16(&mut self, a: R16) {
pub(in crate::cpu) fn dec_r16(&mut self, a: R16) {
let value = self.registers.get_r16(a);
let result = value.wrapping_sub(1);
self.registers.set_r16(a, result);
}

pub(super) fn inc(&mut self, memory: &mut MMU, a: R8) {
pub(in crate::cpu) fn inc(&mut self, memory: &mut MMU, a: R8) {
let value = self.get_r8_byte(memory, a);
let result = value.wrapping_add(1);
self.set_r8_byte(memory, a, result);
Expand All @@ -61,7 +68,7 @@ impl CPU {
self.registers.f.half_carry = (value & 0xF) == 0xF;
}

pub(super) fn dec(&mut self, mmu: &mut MMU, a: R8) {
pub(in crate::cpu) fn dec(&mut self, mmu: &mut MMU, a: R8) {
let value = self.get_r8_byte(mmu, a);
let result = value.wrapping_sub(1);
self.set_r8_byte(mmu, a, result);
Expand All @@ -72,8 +79,12 @@ impl CPU {
self.registers.f.half_carry = (value & 0xF) == 0x0;
}

// maths
pub(super) fn add(&mut self, b: u8) {
/*
*
* Mathematic Operations
*
*/
pub(in crate::cpu) fn add(&mut self, b: u8) {
let result = self.registers.a.wrapping_add(b);

self.registers.f.zero = result == 0;
Expand All @@ -86,7 +97,7 @@ impl CPU {
self.registers.a = result;
}

pub(super) fn add_r16(&mut self, a_reg: R16, b: u16) {
pub(in crate::cpu) fn add_r16(&mut self, a_reg: R16, b: u16) {
let a = self.registers.get_r16(a_reg);
let result = a.wrapping_add(b);

Expand All @@ -96,13 +107,27 @@ impl CPU {
self.registers.set_r16(a_reg, result);
}

pub(super) fn sub(&mut self, b: u8) {
pub(in crate::cpu) fn adc(&mut self, value: u8) {
let result = self
.registers
.a
.wrapping_add(value)
.wrapping_add(self.registers.f.carry as u8);
self.registers.a = result;

self.registers.f.zero = result == 0;
self.registers.f.carry = value > self.registers.a;
self.registers.f.half_carry = (value & 0x0F) == 0x0F; // Hmmmm...
self.registers.f.subtract = false;
}

pub(in crate::cpu) fn sub(&mut self, b: u8) {
// Use flag setting from CP
self.cp(b);
self.registers.a = self.registers.a.wrapping_sub(b);
}

pub(super) fn cp(&mut self, b: u8) {
pub(in crate::cpu) fn cp(&mut self, b: u8) {
let result = self.registers.a.wrapping_sub(b);

self.registers.f.zero = result == 0;
Expand Down
117 changes: 117 additions & 0 deletions src/cpu/execution/bit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use crate::{cpu::CPU, instructions::r8::R8, mmu::MMU};

impl CPU {
/*
*
* Bit checking and setting
*
*/
pub(in crate::cpu) fn bit(&mut self, mmu: &MMU, r: R8, bit_index: u8) {
let result = self.get_r8_byte(mmu, r) & (1 << bit_index);

self.registers.f.zero = result == 0;
self.registers.f.subtract = false;
self.registers.f.half_carry = true;
}

pub(in crate::cpu) fn res(&mut self, mmu: &mut MMU, r: R8, bit_index: u8) {
let result = self.get_r8_byte(mmu, r) & !(1 << bit_index);
self.set_r8_byte(mmu, r, result);
}

pub(in crate::cpu) fn set(&mut self, mmu: &mut MMU, r: R8, bit_index: u8) {
let result = self.get_r8_byte(mmu, r) | 1 << bit_index;
self.set_r8_byte(mmu, r, result);
}

/*
*
* Bit rotation
*
*/
pub(in crate::cpu) fn swap(&mut self, mmu: &mut MMU, r: R8) {
let register_value = self.get_r8_byte(mmu, r);
let result = (register_value >> 4) | (register_value << 4);
self.set_r8_byte(mmu, r, result);
self.registers.f.zero = result == 0;
self.registers.f.carry = false;
self.registers.f.half_carry = false;
self.registers.f.subtract = false;
}

pub(in crate::cpu) fn rl(&mut self, mmu: &mut MMU, r: R8) {
let value = self.get_r8_byte(mmu, r);
let result = (value << 1) | self.registers.f.carry as u8;
self.set_r8_byte(mmu, r, result);
self.registers.f.zero = result == 0;
self.registers.f.subtract = false;
self.registers.f.half_carry = false;
self.registers.f.carry = value >> 7 == 1;
}

pub(in crate::cpu) fn rla(&mut self, mmu: &mut MMU) {
self.rl(mmu, R8::A);
self.registers.f.zero = false;
}

pub(in crate::cpu) fn srl(&mut self, mmu: &mut MMU, reg: R8) {
let value = self.get_r8_byte(mmu, reg);
let result = value >> 1;
self.set_r8_byte(mmu, reg, result);
self.registers.f.carry = value & 1 == 1;
self.registers.f.half_carry = false;
self.registers.f.subtract = false;
self.registers.f.zero = result == 0;
}

pub(in crate::cpu) fn sla(&mut self, mmu: &mut MMU, reg: R8) {
let value = self.get_r8_byte(mmu, R8::A);
let new_value = (value << 1) | self.registers.f.carry as u8;
self.set_r8_byte(mmu, reg, new_value);
self.registers.f.carry = value >> 7 == 1;
self.registers.f.half_carry = false;
self.registers.f.subtract = false;
self.registers.f.zero = new_value == 0;
}

pub(in crate::cpu) fn rlca(&mut self) {
let value = self.registers.a;
self.registers.f.carry = value >> 7 > 0;
self.registers.f.zero = false;
self.registers.f.half_carry = false;
self.registers.f.subtract = false;
self.registers.a = (self.registers.a << 1) | (self.registers.a >> 7);
}

pub(in crate::cpu) fn cpl(&mut self) {
self.registers.a = !self.registers.a;
self.registers.f.half_carry = true;
self.registers.f.subtract = true;
}

pub(in crate::cpu) fn daa(&mut self) {
let mut correction = 0;
let mut set_carry = false;

if self.registers.f.half_carry
|| (!self.registers.f.subtract && (self.registers.a & 0xf) > 9)
{
correction |= 0x6;
}

if self.registers.f.carry || (!self.registers.f.subtract && self.registers.a > 0x99) {
correction |= 0x60;
set_carry = true;
}

if self.registers.f.subtract {
self.registers.a = self.registers.a.wrapping_sub(correction);
} else {
self.registers.a = self.registers.a.wrapping_add(correction);
}

self.registers.f.zero = self.registers.a == 0;
self.registers.f.half_carry = false;
self.registers.f.carry = set_carry;
}
}
88 changes: 88 additions & 0 deletions src/cpu/execution/control_flow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::{
cpu::CPU,
instructions::{cond::Cond, r16stk::R16stk},
mmu::MMU,
};

impl CPU {
/*
*
* Jumps
*
*/
pub(in crate::cpu) fn jp(&mut self, addr: u16) {
self.registers.pc = addr;
}

pub(in crate::cpu) fn jp_cond(&mut self, addr: u16, cond: Cond) {
if self.registers.f.evaluate_condition(cond) {
self.jp(addr)
}
}

pub(in crate::cpu) fn jr(&mut self, offset: i8) {
self.registers.pc = self.registers.pc.wrapping_add((offset as i16) as u16);
}

pub(in crate::cpu) fn jr_cond(&mut self, offset: i8, cond: Cond) {
if self.registers.f.evaluate_condition(cond) {
self.jr(offset)
}
}

/*
*
* Call and Return
*
*/
pub(in crate::cpu) fn call(&mut self, mmu: &mut MMU, addr: u16) {
self.set_memory_word(mmu, self.registers.sp - 2, self.registers.pc + 3);
self.registers.sp -= 2;
self.registers.pc = addr;
}

pub(in crate::cpu) fn call_cond(&mut self, mmu: &mut MMU, cond: Cond, addr: u16) {
if self.registers.f.evaluate_condition(cond) {
self.call(mmu, addr)
}
}

pub(in crate::cpu) fn rst_tgt3(&mut self, mmu: &mut MMU, addr: u16) {
self.set_memory_word(mmu, self.registers.sp - 2, self.registers.pc + 1);
self.registers.sp -= 2;
self.registers.pc = addr - 1
}

pub(in crate::cpu) fn ret(&mut self, mmu: &mut MMU) {
self.registers.pc = self.get_memory_word(mmu, self.registers.sp) - 1;
self.registers.sp += 2;
}

pub(in crate::cpu) fn ret_cond(&mut self, mmu: &mut MMU, cond: Cond) {
if self.registers.f.evaluate_condition(cond) {
self.registers.pc = self.get_memory_word(mmu, self.registers.sp) - 1;
self.registers.sp += 2;
}
}

pub(in crate::cpu) fn reti(&mut self, mmu: &mut MMU) {
self.ret(mmu);
self.ime = true;
}

/*
*
* Push and pop
*
*/
pub(in crate::cpu) fn push(&mut self, mmu: &mut MMU, value: u16) {
self.set_memory_word(mmu, self.registers.sp - 2, value);
self.registers.sp -= 2;
}

pub(in crate::cpu) fn pop(&mut self, mmu: &mut MMU, reg: R16stk) {
let value = self.get_memory_word(mmu, self.registers.sp);
self.registers.set_r16_stk(reg, value);
self.registers.sp += 2;
}
}
31 changes: 31 additions & 0 deletions src/cpu/execution/load.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::{
cpu::CPU,
instructions::{r16::R16, r16mem::R16mem, r8::R8},
mmu::MMU,
};

impl CPU {
pub(in crate::cpu) fn lda(&mut self, value: u8) {
self.registers.a = value;
}

pub(in crate::cpu) fn lda_r16mem(&mut self, mmu: &mut MMU, reg: R16mem) {
self.registers.a = mmu.read_byte(self.registers.get_r16_mem(reg))
}

pub(in crate::cpu) fn ld_r16mem(&mut self, mmu: &mut MMU, reg: R16mem, value: u8) {
mmu.write_byte(self.registers.get_r16_mem(reg), value)
}

pub(in crate::cpu) fn ld_r8(&mut self, mmu: &mut MMU, reg: R8, value: u8) {
self.set_r8_byte(mmu, reg, value);
}

pub(in crate::cpu) fn ld_r16(&mut self, reg: R16, value: u16) {
self.registers.set_r16(reg, value)
}

pub(in crate::cpu) fn ldh_addr(&mut self, mmu: &mut MMU, offset: u8, value: u8) {
mmu.write_byte(0xFF00 + offset as u16, value)
}
}
4 changes: 4 additions & 0 deletions src/cpu/execution/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod alu;
mod bit;
mod control_flow;
mod load;
Loading

0 comments on commit dd0a821

Please sign in to comment.