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