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

feat: initial MMU support

Added more instructions
parent 489b5dba
No related branches found
No related tags found
No related merge requests found
...@@ -7,4 +7,6 @@ fn main() { ...@@ -7,4 +7,6 @@ fn main() {
game_boy.clock(); game_boy.clock();
game_boy.clock(); game_boy.clock();
game_boy.clock(); game_boy.clock();
game_boy.clock();
game_boy.clock();
} }
use crate::mmu::Mmu; use crate::mmu::Mmu;
pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 208] = [
// 0x0 opcodes // 0x0 opcodes
(nop, 4, "NOP"), (nop, 4, "NOP"),
(ld_bc_u16, 12, "LD BC, NN"), (ld_bc_u16, 12, "LD BC, NN"),
...@@ -37,7 +37,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [ ...@@ -37,7 +37,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
(nop, 4, "NOP"), (nop, 4, "NOP"),
// 0x2 opcodes // 0x2 opcodes
(nop, 4, "NOP"), (nop, 4, "NOP"),
(nop, 4, "NOP"), (ld_hl_u16, 12, "LD HL, u16"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
...@@ -55,7 +55,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [ ...@@ -55,7 +55,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
// 0x3 opcodes // 0x3 opcodes
(nop, 4, "NOP"), (nop, 4, "NOP"),
(ld_sp_u16, 12, "LD SP, NN"), (ld_sp_u16, 12, "LD SP, NN"),
(nop, 4, "NOP"), (ld_mhld_a, 8, "LD [HL]-, A"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
...@@ -188,6 +188,40 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [ ...@@ -188,6 +188,40 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 176] = [
(nop, 4, "NOP"), (nop, 4, "NOP"),
(nop, 4, "NOP"), (nop, 4, "NOP"),
(xor_a_a, 4, "XOR A, A"), (xor_a_a, 4, "XOR A, A"),
// 0xb opcodes
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
// 0xc opcodes
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
(nop, 4, "NOP"),
]; ];
pub struct Cpu { pub struct Cpu {
...@@ -238,10 +272,10 @@ impl Cpu { ...@@ -238,10 +272,10 @@ impl Cpu {
let instruction = INSTRUCTIONS[opcode as usize]; let instruction = INSTRUCTIONS[opcode as usize];
let (instruction_fn, instruction_size, instruction_str) = instruction; let (instruction_fn, instruction_size, instruction_str) = instruction;
println!("{} ({:#x})", instruction_str, opcode);
instruction_fn(self); instruction_fn(self);
self.clocks = self.clocks.wrapping_add(instruction_size as u32); self.clocks = self.clocks.wrapping_add(instruction_size as u32);
println!("{} ({:#x})", instruction_str, opcode)
} }
#[inline(always)] #[inline(always)]
...@@ -423,12 +457,27 @@ fn add_hl_bc(cpu: &mut Cpu) { ...@@ -423,12 +457,27 @@ fn add_hl_bc(cpu: &mut Cpu) {
cpu.set_hl(value); cpu.set_hl(value);
} }
fn ld_hl_u16(cpu: &mut Cpu) {
let word = cpu.read_u16();
cpu.set_hl(word);
}
fn ld_sp_u16(cpu: &mut Cpu) { fn ld_sp_u16(cpu: &mut Cpu) {
cpu.sp = cpu.read_u16(); cpu.sp = cpu.read_u16();
} }
fn ld_mhld_a(cpu: &mut Cpu) {
cpu.mmu.write(cpu.hl(), cpu.a);
cpu.set_hl(cpu.hl().wrapping_sub(1));
}
fn xor_a_a(cpu: &mut Cpu) { fn xor_a_a(cpu: &mut Cpu) {
cpu.a ^= cpu.a cpu.a ^= cpu.a;
cpu.set_sub(false);
cpu.set_zero(cpu.a == 0);
cpu.set_half_carry(false);
cpu.set_carry(false);
} }
fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 { fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 {
......
...@@ -20,7 +20,35 @@ impl Mmu { ...@@ -20,7 +20,35 @@ impl Mmu {
} }
pub fn write(&mut self, addr: u16, value: u8) { pub fn write(&mut self, addr: u16, value: u8) {
self.ram[addr as usize] = value; match addr & 0xf000 {
// BIOS
0x0000 => {
println!("WRITING to BIOS")
}
// ROM0
0x1000 | 0x2000 | 0x3000 => {
println!("WRITING TO ROM 0");
}
// ROM1 (unbanked) (16k)
0x4000 | 0x5000 | 0x6000 | 0x7000 => {
println!("WRITING TO ROM 1");
}
// Graphics: VRAM (8k)
0x8000 | 0x9000 => {
println!("WRITING TO VRAM");
self.ppu.vram[(addr & 0x1fff) as usize] = value;
}
// External RAM (8k)
0xa000 | 0xb000 => {
println!("WRITING TO ERAM");
}
// Working RAM (8k)
0xc000 | 0xd000 => {
println!("WRITING TO RAM");
self.ram[(addr & 0x1fff) as usize] = value;
}
_ => panic!("asdad"),
}
} }
pub fn write_buffer(&mut self, addr: u16, buffer: &[u8]) { pub fn write_buffer(&mut self, addr: u16, buffer: &[u8]) {
......
pub const VRAM_SIZE: usize = 8192; pub const VRAM_SIZE: usize = 8192;
pub struct Ppu { pub struct Ppu {
vram: [u8; VRAM_SIZE], pub vram: [u8; VRAM_SIZE],
} }
impl Ppu { impl Ppu {
......
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