Skip to content
Snippets Groups Projects
Verified Commit 8952ff35 authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

feat: more instructions added

parent 214b8c52
No related branches found
No related tags found
No related merge requests found
pub const RAM_SIZE: usize = 8192; pub const RAM_SIZE: usize = 8192;
pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 4] = [ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 11] = [
// 0x0 opcodes // 0x0 opcodes
(nop, 4, "NOP"), (nop, 4, "NOP"),
(ld_bc_u16, 12, "LD BC, NN"), (ld_bc_u16, 12, "LD BC, NN"),
(ld_bc_a, 8, "LD BC, A"), (ld_mbc_a, 8, "LD [BC], A"),
(inc_bc, 8, "INC BC"),
(inc_b, 4, "INC B"),
(dec_b, 4, "DEC B"),
(ld_b_u8, 8, "LD B, N"),
(rlca, 4, "RLCA"),
(ld_mu16_sp, 20, "LD [u16], SP"),
(add_hl_bc, 8, "ADD HL, BC"),
// 0x2 opcodes // 0x2 opcodes
(ld_sp_u16, 12, "LD SP, NN"), (ld_sp_u16, 12, "LD SP, NN"),
]; ];
...@@ -12,14 +19,17 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 4] = [ ...@@ -12,14 +19,17 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 4] = [
pub struct Cpu { pub struct Cpu {
pc: u16, pc: u16,
sp: u16, sp: u16,
reg_a: u8, a: u8,
reg_b: u8, b: u8,
reg_c: u8, c: u8,
reg_d: u8, d: u8,
reg_e: u8, e: u8,
reg_f: u8, h: u8,
reg_h: u8, l: u8,
reg_l: u8, zero: bool,
sub: bool,
half_carry: bool,
carry: bool,
ram: [u8; RAM_SIZE], ram: [u8; RAM_SIZE],
} }
...@@ -28,14 +38,17 @@ impl Cpu { ...@@ -28,14 +38,17 @@ impl Cpu {
Cpu { Cpu {
pc: 0x0, pc: 0x0,
sp: 0x0, sp: 0x0,
reg_a: 0x0, a: 0x0,
reg_b: 0x0, b: 0x0,
reg_c: 0x0, c: 0x0,
reg_d: 0x0, d: 0x0,
reg_e: 0x0, e: 0x0,
reg_f: 0x0, h: 0x0,
reg_h: 0x0, l: 0x0,
reg_l: 0x0, zero: false,
sub: false,
half_carry: false,
carry: false,
ram: [0u8; RAM_SIZE], ram: [0u8; RAM_SIZE],
} }
} }
...@@ -43,74 +56,187 @@ impl Cpu { ...@@ -43,74 +56,187 @@ impl Cpu {
pub fn clock(&mut self) { pub fn clock(&mut self) {
// fetches the current instruction and increments // fetches the current instruction and increments
// the PC (program counter) accordingly // the PC (program counter) accordingly
let instruction = self.ram[self.pc as usize]; let _instruction = self.ram[self.pc as usize];
self.pc += 1; self.pc += 1;
} }
#[inline(always)] #[inline(always)]
fn reg_af(&self) -> u16 { fn af(&self) -> u16 {
(self.reg_a as u16) << 8 | self.reg_f as u16 (self.a as u16) << 8 | self.f() as u16
} }
#[inline(always)] #[inline(always)]
fn reg_bc(&self) -> u16 { fn bc(&self) -> u16 {
(self.reg_b as u16) << 8 | self.reg_c as u16 (self.b as u16) << 8 | self.c as u16
} }
#[inline(always)] #[inline(always)]
fn reg_de(&self) -> u16 { fn f(&self) -> u8 {
(self.reg_d as u16) << 8 | self.reg_e as u16 let mut f = 0x0u8;
if self.zero {
f |= 0x80;
}
if self.sub {
f |= 0x40;
}
if self.half_carry {
f |= 0x20;
}
if self.carry {
f |= 0x10;
}
f
}
#[inline(always)]
fn set_bc(&mut self, value: u16) {
self.b = (value >> 8) as u8;
self.c = value as u8;
}
#[inline(always)]
fn de(&self) -> u16 {
(self.d as u16) << 8 | self.e as u16
}
#[inline(always)]
fn set_de(&mut self, value: u16) {
self.d = (value >> 8) as u8;
self.e = value as u8;
} }
#[inline(always)] #[inline(always)]
fn reg_hl(&self) -> u16 { fn hl(&self) -> u16 {
(self.reg_h as u16) << 8 | self.reg_l as u16 (self.h as u16) << 8 | self.l as u16
}
#[inline(always)]
fn set_hl(&mut self, value: u16) {
self.h = (value >> 8) as u8;
self.l = value as u8;
} }
#[inline(always)] #[inline(always)]
fn read_u8(&mut self) -> u8 { fn read_u8(&mut self) -> u8 {
let byte = self.ram[self.pc as usize]; let byte = self.ram[self.pc as usize];
self.pc += 1; self.pc = self.pc.wrapping_add(1);
byte byte
} }
#[inline(always)] #[inline(always)]
fn read_u16(&mut self) -> u16 { fn read_u16(&mut self) -> u16 {
let word = (self.ram[self.pc as usize] as u16) << 8 | self.ram[self.pc as usize + 1] as u16; let byte1 = self.read_u8();
self.pc += 2; let byte2 = self.read_u8();
let word = byte1 as u16 | ((byte2 as u16) << 8);
word word
} }
#[inline(always)] #[inline(always)]
fn get_zero(&self) -> bool { fn get_zero(&self) -> bool {
self.reg_f & 0x40 == 1 self.zero
}
#[inline(always)]
fn set_zero(&mut self, value: bool) {
self.zero = value
} }
#[inline(always)] #[inline(always)]
fn get_sub(&self) -> bool { fn get_sub(&self) -> bool {
self.reg_f & 0x20 == 1 self.sub
}
#[inline(always)]
fn set_sub(&mut self, value: bool) {
self.sub = value;
} }
#[inline(always)] #[inline(always)]
fn get_half_carry(&self) -> bool { fn get_half_carry(&self) -> bool {
self.reg_f & 0x10 == 1 self.half_carry
}
#[inline(always)]
fn set_half_carry(&mut self, value: bool) {
self.half_carry = value
} }
#[inline(always)] #[inline(always)]
fn get_carry(&self) -> bool { fn get_carry(&self) -> bool {
self.reg_f & 0x08 == 1 self.carry
}
#[inline(always)]
fn set_carry(&mut self, value: bool) {
self.carry = value;
} }
} }
fn nop(_cpu: &mut Cpu) {} fn nop(_cpu: &mut Cpu) {}
fn ld_bc_u16(cpu: &mut Cpu) { fn ld_bc_u16(cpu: &mut Cpu) {
cpu.reg_b = cpu.read_u8(); let word = cpu.read_u16();
cpu.reg_c = cpu.read_u8(); cpu.set_bc(word);
}
fn ld_mbc_a(cpu: &mut Cpu) {
cpu.ram[cpu.bc() as usize] = cpu.a;
}
fn inc_bc(cpu: &mut Cpu) {
cpu.set_bc(cpu.bc().wrapping_add(1));
} }
fn ld_bc_a(cpu: &mut Cpu) { fn inc_b(cpu: &mut Cpu) {
cpu.ram[cpu.reg_bc() as usize] = cpu.reg_a; let value = cpu.b.wrapping_add(1);
cpu.set_sub(false);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.b = value;
}
fn dec_b(cpu: &mut Cpu) {
let value = cpu.b.wrapping_sub(1);
cpu.set_sub(true);
cpu.set_zero(value == 0);
cpu.set_half_carry((value & 0xf) == 0xf);
cpu.b = value;
}
fn ld_b_u8(cpu: &mut Cpu) {
let byte = cpu.read_u8();
cpu.b = byte;
}
fn rlca(cpu: &mut Cpu) {
let carry = cpu.a >> 7;
cpu.a = cpu.a << 1 | carry;
cpu.set_sub(false);
cpu.set_zero(false);
cpu.set_half_carry(false);
cpu.set_carry(carry == 1);
}
fn ld_mu16_sp(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.ram[word as usize] = cpu.sp as u8;
cpu.ram[word as usize + 1] = (cpu.sp >> 8) as u8;
}
fn add_hl_bc(cpu: &mut Cpu) {
let value = cpu.hl() as u32 + cpu.bc() as u32;
cpu.set_sub(false);
cpu.set_carry(value & 0x1000 == 0x1000);
cpu.set_half_carry((value & 0xff) == 0xff); //@todo I'm not sure about this one
cpu.set_hl(value as u16);
} }
fn ld_sp_u16(cpu: &mut Cpu) { fn ld_sp_u16(cpu: &mut Cpu) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment