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

feat: initial Gameboy structure

parent 10d591ee
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ A Game Boy emulator that is written in Rust 🦀. ...@@ -11,6 +11,7 @@ A Game Boy emulator that is written in Rust 🦀.
* [GitHub - binjgb](https://github.com/binji/binjgb) * [GitHub - binjgb](https://github.com/binji/binjgb)
* [GitHub - gameroy](https://github.com/Rodrigodd/gameroy) * [GitHub - gameroy](https://github.com/Rodrigodd/gameroy)
* [Game Boy CPU Opcodes](https://izik1.github.io/gbops) * [Game Boy CPU Opcodes](https://izik1.github.io/gbops)
* [GitHub - c-sp/gameboy-test-roms](https://github.com/c-sp/gameboy-test-roms)
## License ## License
......
pub const RAM_SIZE: usize = 8192; use crate::mmu::Mmu;
pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 11] = [ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 11] = [
// 0x0 opcodes // 0x0 opcodes
...@@ -30,11 +30,11 @@ pub struct Cpu { ...@@ -30,11 +30,11 @@ pub struct Cpu {
sub: bool, sub: bool,
half_carry: bool, half_carry: bool,
carry: bool, carry: bool,
ram: [u8; RAM_SIZE], mmu: Mmu,
} }
impl Cpu { impl Cpu {
pub fn new() -> Cpu { pub fn new<'n>(mmu: Mmu) -> Cpu {
Cpu { Cpu {
pc: 0x0, pc: 0x0,
sp: 0x0, sp: 0x0,
...@@ -49,17 +49,22 @@ impl Cpu { ...@@ -49,17 +49,22 @@ impl Cpu {
sub: false, sub: false,
half_carry: false, half_carry: false,
carry: false, carry: false,
ram: [0u8; RAM_SIZE], mmu: mmu,
} }
} }
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.mmu.read(self.pc);
self.pc += 1; self.pc += 1;
} }
#[inline(always)]
pub fn mmu(&mut self) -> &mut Mmu {
&mut self.mmu
}
#[inline(always)] #[inline(always)]
fn af(&self) -> u16 { fn af(&self) -> u16 {
(self.a as u16) << 8 | self.f() as u16 (self.a as u16) << 8 | self.f() as u16
...@@ -118,7 +123,7 @@ impl Cpu { ...@@ -118,7 +123,7 @@ impl Cpu {
#[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.mmu.read(self.pc);
self.pc = self.pc.wrapping_add(1); self.pc = self.pc.wrapping_add(1);
byte byte
} }
...@@ -180,7 +185,7 @@ fn ld_bc_u16(cpu: &mut Cpu) { ...@@ -180,7 +185,7 @@ fn ld_bc_u16(cpu: &mut Cpu) {
} }
fn ld_mbc_a(cpu: &mut Cpu) { fn ld_mbc_a(cpu: &mut Cpu) {
cpu.ram[cpu.bc() as usize] = cpu.a; cpu.mmu.write(cpu.bc(), cpu.a);
} }
fn inc_bc(cpu: &mut Cpu) { fn inc_bc(cpu: &mut Cpu) {
...@@ -225,8 +230,8 @@ fn rlca(cpu: &mut Cpu) { ...@@ -225,8 +230,8 @@ fn rlca(cpu: &mut Cpu) {
fn ld_mu16_sp(cpu: &mut Cpu) { fn ld_mu16_sp(cpu: &mut Cpu) {
let word = cpu.read_u16(); let word = cpu.read_u16();
cpu.ram[word as usize] = cpu.sp as u8; cpu.mmu.write(word, cpu.sp as u8);
cpu.ram[word as usize + 1] = (cpu.sp >> 8) as u8; cpu.mmu.write(word + 1, (cpu.sp >> 8) as u8);
} }
fn add_hl_bc(cpu: &mut Cpu) { fn add_hl_bc(cpu: &mut Cpu) {
......
use std::{cell::RefCell, rc::Rc};
use crate::{cpu::Cpu, mmu::Mmu, util::read_file};
pub type SharedMut<T> = Rc<RefCell<T>>;
pub struct GameBoy {
cpu: Cpu,
}
impl GameBoy {
pub fn new() -> GameBoy {
let mmu = Mmu::new();
let cpu = Cpu::new(mmu);
GameBoy { cpu: cpu }
}
pub fn load_boot(&mut self, path: &str) {
let data = read_file(path);
self.cpu.mmu().write_buffer(0x0000, &data);
}
pub fn load_boot_default(&mut self) {
self.load_boot("./res/mbr_rom.bin");
}
}
pub const RAM_SIZE: usize = 8192;
pub const VRAM_SIZE: usize = 8192;
pub struct Mmu {
ram: [u8; RAM_SIZE],
vram: [u8; VRAM_SIZE],
}
impl Mmu {
pub fn new() -> Mmu {
Mmu {
ram: [0u8; RAM_SIZE],
vram: [0u8; VRAM_SIZE],
}
}
pub fn read(&self, addr: u16) -> u8 {
self.ram[addr as usize]
}
pub fn write(&mut self, addr: u16, value: u8) {
self.ram[addr as usize] = value;
}
pub fn write_buffer(&mut self, addr: u16, buffer: &[u8]) {
self.ram[addr as usize..addr as usize + buffer.len()].clone_from_slice(buffer);
}
}
use std::{fs::File, io::Read}; use std::{cell::RefCell, fs::File, io::Read, rc::Rc};
pub type SharedMut<T> = Rc<RefCell<T>>;
pub fn read_file(path: &str) -> Vec<u8> { pub fn read_file(path: &str) -> Vec<u8> {
let mut file = File::open(path).unwrap(); let mut file = File::open(path).unwrap();
......
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