From 7b85fc28204a32d0e0c54879dc209eed72d0ff9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Thu, 7 Jul 2022 22:05:26 +0100 Subject: [PATCH] feat: initial timer strcture --- examples/sdl/src/main.rs | 2 +- src/cpu.rs | 7 ++++++- src/gb.rs | 11 ++++++++--- src/lib.rs | 1 + src/mmu.rs | 21 +++++++++++++++------ src/ppu.rs | 12 ++++++------ src/timer.rs | 27 +++++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 src/timer.rs diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs index 2c916122..f72bf2aa 100644 --- a/examples/sdl/src/main.rs +++ b/examples/sdl/src/main.rs @@ -34,7 +34,7 @@ fn start_sdl() -> Graphics { // creates the system window that is going to be used to // show the emulator and sets it to the central are o screen - let mut window = video_subsystem + let window = video_subsystem .window( TITLE, 2 as u32 * DISPLAY_WIDTH as u32, //@todo check screen scale diff --git a/src/cpu.rs b/src/cpu.rs index 1e29d760..34d659d3 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -4,7 +4,7 @@ use crate::{ inst::{EXTENDED, INSTRUCTIONS}, mmu::Mmu, pad::Pad, - ppu::Ppu, + ppu::Ppu, timer::Timer, }; pub const PREFIX: u8 = 0xcb; @@ -191,6 +191,11 @@ impl Cpu { pub fn pad(&mut self) -> &mut Pad { self.mmu().pad() } + + #[inline(always)] + pub fn timer(&mut self) -> &mut Timer { + self.mmu().timer() + } #[inline(always)] pub fn halted(&self) -> bool { diff --git a/src/gb.rs b/src/gb.rs index b58146b6..f9a12c84 100644 --- a/src/gb.rs +++ b/src/gb.rs @@ -4,7 +4,7 @@ use crate::{ mmu::Mmu, pad::{Pad, PadKey}, ppu::{Ppu, Tile, FRAME_BUFFER_SIZE}, - util::read_file, + util::read_file, timer::Timer, }; #[cfg(feature = "wasm")] @@ -22,9 +22,10 @@ pub struct GameBoy { impl GameBoy { #[cfg_attr(feature = "wasm", wasm_bindgen(constructor))] pub fn new() -> Self { - let pad = Pad::new(); let ppu = Ppu::new(); - let mmu = Mmu::new(ppu, pad); + let pad = Pad::new(); + let timer = Timer::new(); + let mmu = Mmu::new(ppu, pad, timer); let cpu = Cpu::new(mmu); Self { cpu: cpu } } @@ -144,6 +145,10 @@ impl GameBoy { self.cpu.pad() } + pub fn timer(&mut self) -> &mut Timer { + self.cpu.timer() + } + pub fn frame_buffer(&mut self) -> &Box<[u8; FRAME_BUFFER_SIZE]> { &(self.ppu().frame_buffer) } diff --git a/src/lib.rs b/src/lib.rs index cd9b622a..11af82a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,4 +5,5 @@ pub mod inst; pub mod mmu; pub mod pad; pub mod ppu; +pub mod timer; pub mod util; diff --git a/src/mmu.rs b/src/mmu.rs index a64f6a6a..ed98c3ec 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -1,4 +1,4 @@ -use crate::{pad::Pad, ppu::Ppu}; +use crate::{pad::Pad, ppu::Ppu, timer::Timer}; pub const BIOS_SIZE: usize = 256; pub const ROM_SIZE: usize = 32768; @@ -6,24 +6,29 @@ pub const RAM_SIZE: usize = 8192; pub const ERAM_SIZE: usize = 8192; pub struct Mmu { + /// Register that controls the interrupts that are considered + /// to be enabled and should be triggered. + pub ie: u8, + + /// Reference to the PPU (Pixel Processing Unit) that is going + /// to be used both for VRAM reading/writing and to forward + /// some of the access operations. ppu: Ppu, pad: Pad, + timer: Timer, boot_active: bool, boot: [u8; BIOS_SIZE], rom: [u8; ROM_SIZE], ram: [u8; RAM_SIZE], eram: [u8; RAM_SIZE], - - /// Registers that controls the interrupts that are considered - /// to be enabled and should be triggered. - pub ie: u8, } impl Mmu { - pub fn new(ppu: Ppu, pad: Pad) -> Self { + pub fn new(ppu: Ppu, pad: Pad, timer: Timer) -> Self { Self { ppu: ppu, pad: pad, + timer: timer, boot_active: true, boot: [0u8; BIOS_SIZE], rom: [0u8; ROM_SIZE], @@ -49,6 +54,10 @@ impl Mmu { &mut self.pad } + pub fn timer(&mut self) -> &mut Timer { + &mut self.timer + } + pub fn boot_active(&self) -> bool { self.boot_active } diff --git a/src/ppu.rs b/src/ppu.rs index 6cb2b802..66a5c397 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -327,22 +327,22 @@ impl Ppu { match self.mode { PpuMode::OamRead => { if self.mode_clock >= 80 { - self.mode_clock = 0; self.mode = PpuMode::VramRead; + self.mode_clock = self.mode_clock - 80; } } PpuMode::VramRead => { if self.mode_clock >= 172 { self.render_line(); - self.mode_clock = 0; self.mode = PpuMode::HBlank; + self.mode_clock = self.mode_clock - 172; } } PpuMode::HBlank => { if self.mode_clock >= 204 { // increments the register that holds the - // information about the current line in drawign + // information about the current line in drawing self.ly += 1; // in case we've reached the end of the @@ -354,7 +354,7 @@ impl Ppu { self.mode = PpuMode::OamRead; } - self.mode_clock = 0; + self.mode_clock = self.mode_clock - 204; } } PpuMode::VBlank => { @@ -369,7 +369,7 @@ impl Ppu { self.ly = 0; } - self.mode_clock = 0; + self.mode_clock = self.mode_clock - 456; } } } @@ -711,7 +711,7 @@ impl Ppu { let pixel = tile_row[if obj.xflip { 7 - x } else { x }]; let color = palette[pixel as usize]; - // set the color pixel in the frame buffer + // sets the color pixel in the frame buffer self.frame_buffer[frame_offset] = color[0]; self.frame_buffer[frame_offset + 1] = color[1]; self.frame_buffer[frame_offset + 2] = color[2]; diff --git a/src/timer.rs b/src/timer.rs new file mode 100644 index 00000000..0302f9be --- /dev/null +++ b/src/timer.rs @@ -0,0 +1,27 @@ +pub struct Timer { + div: u8, + tima: u8, + tma: u8, + tac: u8, + ratio: u16, +} + +impl Timer { + pub fn new() -> Self { + Self { + div: 0, + tima: 0, + tma: 0, + tac: 0x0, + ratio: 1024 + } + } + + pub fn read(&mut self, addr: u16) -> u8 { + 0x00 + } + + pub fn write(&mut self, addr: u16, value: u8) { + } +} + -- GitLab