Skip to content

Commit

Permalink
refactor loads
Browse files Browse the repository at this point in the history
  • Loading branch information
pcasaretto committed Apr 9, 2024
1 parent beac7ee commit 5acc4cf
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 58 deletions.
65 changes: 22 additions & 43 deletions src/instructions/ld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,10 @@ use crate::{Register16bTarget, RegisterTarget, CPU};

pub fn ld_d16_r16(reg: Register16bTarget) -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let low = cpu.bus.memory[(cpu.pc + 1) as usize];
let high = cpu.bus.memory[(cpu.pc + 2) as usize];
cpu.registers.set_u16(reg, u16::from_le_bytes([low, high]));
cpu.pc = cpu.pc.wrapping_add(2);
}
}

pub fn ld_d8_u8(reg: RegisterTarget) -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let value = cpu.bus.memory[(cpu.pc + 1) as usize];
cpu.registers.set_u8(reg, value);
cpu.pc = cpu.pc.wrapping_add(1);
let low = cpu.read_next_byte();
let high = cpu.read_next_byte();
let addr = u16::from_be_bytes([high, low]);
cpu.registers.set_u16(reg, addr);
}
}

Expand All @@ -27,44 +19,40 @@ pub fn ld_r_r(src: RegisterTarget, dest: RegisterTarget) -> impl Fn(&mut CPU) {
pub fn ld_hl_inc() -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let hl = cpu.registers.get_u16(Register16bTarget::HL);
let value = cpu.bus.memory[hl as usize];
let value = cpu.bus.read_byte(hl);
cpu.registers.set_u8(RegisterTarget::A, value);
cpu.registers
.set_u16(Register16bTarget::HL, hl.wrapping_add(1));
}
}

pub fn ld_u_16_r(src: RegisterTarget) -> impl Fn(&mut CPU) {
pub fn ld_r_mem_at_d16(src: RegisterTarget) -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let addr = u16::from_be_bytes([
cpu.bus.memory[cpu.pc as usize],
cpu.bus.memory[(cpu.pc + 1) as usize],
]);
let addr = u16::from_be_bytes([cpu.read_next_byte(), cpu.read_next_byte()]);
let value = cpu.registers.get_u8(src);
cpu.bus.memory[addr as usize] = value;
cpu.pc = cpu.pc.wrapping_add(1);
cpu.bus.write_byte(addr, value);
}
}

pub fn ld_mem_at_r16_r(reg: Register16bTarget, target: RegisterTarget) -> impl Fn(&mut CPU) {
pub fn ld_r_mem_at_r16(reg: Register16bTarget, target: RegisterTarget) -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let addr = cpu.registers.get_u16(reg);
let value = cpu.registers.get_u8(target);
cpu.bus.memory[addr as usize] = value;
cpu.bus.write_byte(addr, value);
}
}

pub fn ld_d8_mem_at_r16(reg: Register16bTarget) -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let addr = cpu.registers.get_u16(reg);
let value = cpu.bus.memory[cpu.pc as usize];
cpu.bus.memory[addr as usize] = value;
let value = cpu.read_next_byte();
cpu.bus.write_byte(addr, value);
}
}

pub fn ld_d8_r(target: RegisterTarget) -> impl Fn(&mut CPU) {
move |cpu: &mut CPU| {
let value = cpu.bus.memory[cpu.pc as usize];
let value = cpu.read_next_byte();
cpu.registers.set_u8(target, value);
}
}
Expand All @@ -75,10 +63,10 @@ mod tests {
use crate::Registers;

#[test]
fn test_ld_d16_u16() {
fn test_ld_d16_r16() {
let mut cpu = CPU::default();
cpu.bus.memory[1] = 0x01;
cpu.bus.memory[2] = 0x02;
cpu.bus.memory[0] = 0x01;
cpu.bus.memory[1] = 0x02;
ld_d16_r16(Register16bTarget::BC)(&mut cpu);
assert_eq!(cpu.registers.get_u16(Register16bTarget::BC), 0x0201);
assert_eq!(cpu.pc, 2);
Expand All @@ -98,15 +86,6 @@ mod tests {
assert_eq!(cpu.registers.get_u8(RegisterTarget::A), 0x01);
}

#[test]
fn test_d8_u8() {
let mut cpu = CPU::default();
cpu.bus.memory[1] = 0x01;
ld_d8_u8(RegisterTarget::B)(&mut cpu);
assert_eq!(cpu.registers.get_u8(RegisterTarget::B), 0x01);
assert_eq!(cpu.pc, 1);
}

#[test]
fn test_ld_hl_inc() {
let mut cpu = CPU::default();
Expand All @@ -118,12 +97,12 @@ mod tests {
}

#[test]
fn test_ld_mem_at_u16_r() {
fn test_ld_r_mem_at_r16() {
let mut cpu = CPU::default();
cpu.registers.set_u16(Register16bTarget::BC, 0x1000);
cpu.registers.set_u8(RegisterTarget::A, 0x34);
ld_mem_at_r16_r(Register16bTarget::BC, RegisterTarget::A)(&mut cpu);
assert_eq!(cpu.bus.memory[0x1000], 0x34);
ld_r_mem_at_r16(Register16bTarget::BC, RegisterTarget::A)(&mut cpu);
assert_eq!(cpu.bus.read_byte(0x1000), 0x34);
}

#[test]
Expand All @@ -132,15 +111,15 @@ mod tests {
cpu.registers.set_u8(RegisterTarget::A, 0x34);
cpu.bus.memory[0] = 0x01;
cpu.bus.memory[1] = 0x23;
ld_u_16_r(RegisterTarget::A)(&mut cpu);
ld_r_mem_at_d16(RegisterTarget::A)(&mut cpu);
assert_eq!(cpu.bus.memory[0x0123], 0x34);
}

#[test]
fn test_ld_u_16_r_advances_pc() {
let mut cpu = CPU::default();
ld_u_16_r(RegisterTarget::A)(&mut cpu);
assert_eq!(cpu.pc, 1);
ld_r_mem_at_d16(RegisterTarget::A)(&mut cpu);
assert_eq!(cpu.pc, 2);
}

#[test]
Expand Down
20 changes: 7 additions & 13 deletions src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ pub fn from_byte(byte: u8) -> Box<dyn Fn(&mut CPU)> {
match byte {
0x00 => Box::new(nop::nop()),
0x01 => Box::new(ld::ld_d16_r16(Register16bTarget::BC)),
0x02 => Box::new(ld::ld_mem_at_r16_r(
0x02 => Box::new(ld::ld_r_mem_at_r16(
Register16bTarget::BC,
RegisterTarget::A,
)),
0x12 => Box::new(ld::ld_mem_at_r16_r(
0x12 => Box::new(ld::ld_r_mem_at_r16(
Register16bTarget::DE,
RegisterTarget::A,
)),
Expand All @@ -44,22 +44,16 @@ pub fn from_byte(byte: u8) -> Box<dyn Fn(&mut CPU)> {

0x31 => Box::new(ld::ld_d16_r16(Register16bTarget::SP)),
0x21 => Box::new(ld::ld_d16_r16(Register16bTarget::HL)),
0x06 => Box::new(ld::ld_d8_u8(RegisterTarget::B)),
0x16 => Box::new(ld::ld_d8_u8(RegisterTarget::B)),
0x26 => Box::new(ld::ld_d8_u8(RegisterTarget::B)),
0x0E => Box::new(ld::ld_d8_u8(RegisterTarget::C)),
0x1E => Box::new(ld::ld_d8_u8(RegisterTarget::C)),
0x2E => Box::new(ld::ld_d8_u8(RegisterTarget::C)),
0x2A => Box::new(ld::ld_hl_inc()),
// 0x33 => Box::new(inc::inc_sp()),
0x06 => Box::new(ld::ld_d8_r(RegisterTarget::B)),
0x16 => Box::new(ld::ld_d8_r(RegisterTarget::D)),
0x26 => Box::new(ld::ld_d8_r(RegisterTarget::H)),
0x36 => Box::new(ld::ld_d8_mem_at_r16(Register16bTarget::HL)),
0x0A => Box::new(ld::ld_d8_r(RegisterTarget::C)),
0x1A => Box::new(ld::ld_d8_r(RegisterTarget::E)),
0x2A => Box::new(ld::ld_d8_r(RegisterTarget::L)),
0x3A => Box::new(ld::ld_d8_r(RegisterTarget::A)),
0x0E => Box::new(ld::ld_d8_r(RegisterTarget::C)),
0x1E => Box::new(ld::ld_d8_r(RegisterTarget::E)),
0x2E => Box::new(ld::ld_d8_r(RegisterTarget::L)),
0x3E => Box::new(ld::ld_d8_r(RegisterTarget::A)),
0xC3 => Box::new(jmp::jmp_a16()),
0x40 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::B)),
0x41 => Box::new(ld::ld_r_r(RegisterTarget::B, RegisterTarget::C)),
Expand Down Expand Up @@ -149,7 +143,7 @@ pub fn from_byte(byte: u8) -> Box<dyn Fn(&mut CPU)> {

0xD6 => Box::new(sub::sub_d8()),

0xEA => Box::new(ld::ld_u_16_r(RegisterTarget::A)),
0xEA => Box::new(ld::ld_r_mem_at_d16(RegisterTarget::A)),

0xF3 => Box::new(int::di()),
0xFB => Box::new(int::ei()),
Expand Down
13 changes: 11 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ impl MemoryBus {
fn read_byte(&self, address: u16) -> u8 {
self.memory[address as usize]
}

fn write_byte(&mut self, address: u16, value: u8) {
self.memory[address as usize] = value;
}
}

impl Default for CPU {
Expand All @@ -156,8 +160,7 @@ impl Default for CPU {

impl CPU {
pub fn step(&mut self) {
let instruction_byte = self.bus.read_byte(self.pc);
self.pc = self.pc.wrapping_add(1);
let instruction_byte = self.read_next_byte();
let instruction = instructions::from_byte(instruction_byte);
instruction(self);
log::debug!(
Expand All @@ -178,6 +181,12 @@ impl CPU {
RegisterTarget::L => self.registers.l,
}
}

fn read_next_byte(&mut self) -> u8 {
let byte = self.bus.read_byte(self.pc);
self.pc = self.pc.wrapping_add(1);
byte
}
}

#[cfg(test)]
Expand Down

0 comments on commit 5acc4cf

Please sign in to comment.