From 5a7ddc3895ff0508c998f469f88b6c0fe5f16412 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 4 Jun 2023 19:08:16 +0100
Subject: [PATCH] chore: support for mulitple cycles Running under a single
 call. This required increasing variable size from u8 to u16.

---
 src/apu.rs    | 12 ++++++------
 src/dma.rs    |  2 +-
 src/gb.rs     | 40 ++++++++++++++++++++++++++++++++--------
 src/mmu.rs    |  2 +-
 src/ppu.rs    |  2 +-
 src/serial.rs |  2 +-
 src/timer.rs  |  2 +-
 7 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/src/apu.rs b/src/apu.rs
index 3b2f08f8..dbbe2891 100644
--- a/src/apu.rs
+++ b/src/apu.rs
@@ -264,7 +264,7 @@ impl Apu {
         self.clear_audio_buffer()
     }
 
-    pub fn clock(&mut self, cycles: u8) {
+    pub fn clock(&mut self, cycles: u16) {
         if !self.sound_enabled {
             return;
         }
@@ -802,7 +802,7 @@ impl Apu {
     }
 
     #[inline(always)]
-    fn tick_ch_all(&mut self, cycles: u8) {
+    fn tick_ch_all(&mut self, cycles: u16) {
         self.tick_ch1(cycles);
         self.tick_ch2(cycles);
         self.tick_ch3(cycles);
@@ -810,7 +810,7 @@ impl Apu {
     }
 
     #[inline(always)]
-    fn tick_ch1(&mut self, cycles: u8) {
+    fn tick_ch1(&mut self, cycles: u16) {
         self.ch1_timer = self.ch1_timer.saturating_sub(cycles as i16);
         if self.ch1_timer > 0 {
             return;
@@ -832,7 +832,7 @@ impl Apu {
     }
 
     #[inline(always)]
-    fn tick_ch2(&mut self, cycles: u8) {
+    fn tick_ch2(&mut self, cycles: u16) {
         self.ch2_timer = self.ch2_timer.saturating_sub(cycles as i16);
         if self.ch2_timer > 0 {
             return;
@@ -854,7 +854,7 @@ impl Apu {
     }
 
     #[inline(always)]
-    fn tick_ch3(&mut self, cycles: u8) {
+    fn tick_ch3(&mut self, cycles: u16) {
         self.ch3_timer = self.ch3_timer.saturating_sub(cycles as i16);
         if self.ch3_timer > 0 {
             return;
@@ -883,7 +883,7 @@ impl Apu {
     }
 
     #[inline(always)]
-    fn tick_ch4(&mut self, cycles: u8) {
+    fn tick_ch4(&mut self, cycles: u16) {
         self.ch4_timer = self.ch4_timer.saturating_sub(cycles as i32);
         if self.ch4_timer > 0 {
             return;
diff --git a/src/dma.rs b/src/dma.rs
index f477b860..8414356d 100644
--- a/src/dma.rs
+++ b/src/dma.rs
@@ -33,7 +33,7 @@ impl Dma {
         self.active = false;
     }
 
-    pub fn clock(&mut self, _cycles: u8) {}
+    pub fn clock(&mut self, _cycles: u16) {}
 
     pub fn read(&mut self, addr: u16) -> u8 {
         match addr {
diff --git a/src/gb.rs b/src/gb.rs
index 66c37c44..a43b6b11 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -391,9 +391,33 @@ impl GameBoy {
         self.cpu.reset();
     }
 
-    pub fn clock(&mut self) -> u8 {
-        let cycles = self.cpu_clock();
-        let cycles_n = cycles / self.multiplier();
+    pub fn clock(&mut self) -> u16 {
+        let cycles = self.cpu_clock() as u16;
+        let cycles_n = cycles / self.multiplier() as u16;
+        if self.ppu_enabled {
+            self.ppu_clock(cycles_n);
+        }
+        if self.apu_enabled {
+            self.apu_clock(cycles_n);
+        }
+        if self.dma_enabled {
+            self.dma_clock(cycles);
+        }
+        if self.timer_enabled {
+            self.timer_clock(cycles);
+        }
+        if self.serial_enabled {
+            self.serial_clock(cycles);
+        }
+        cycles
+    }
+
+    pub fn clock_m(&mut self, count: usize) -> u16 {
+        let mut cycles = 0u16;
+        for _ in 0..count {
+            cycles += self.clock() as u16;
+        }
+        let cycles_n = cycles / self.multiplier() as u16;
         if self.ppu_enabled {
             self.ppu_clock(cycles_n);
         }
@@ -424,23 +448,23 @@ impl GameBoy {
         self.cpu.clock()
     }
 
-    pub fn ppu_clock(&mut self, cycles: u8) {
+    pub fn ppu_clock(&mut self, cycles: u16) {
         self.ppu().clock(cycles)
     }
 
-    pub fn apu_clock(&mut self, cycles: u8) {
+    pub fn apu_clock(&mut self, cycles: u16) {
         self.apu().clock(cycles)
     }
 
-    pub fn dma_clock(&mut self, cycles: u8) {
+    pub fn dma_clock(&mut self, cycles: u16) {
         self.mmu().clock_dma(cycles);
     }
 
-    pub fn timer_clock(&mut self, cycles: u8) {
+    pub fn timer_clock(&mut self, cycles: u16) {
         self.timer().clock(cycles)
     }
 
-    pub fn serial_clock(&mut self, cycles: u8) {
+    pub fn serial_clock(&mut self, cycles: u16) {
         self.serial().clock(cycles)
     }
 
diff --git a/src/mmu.rs b/src/mmu.rs
index 00eb6322..2a592445 100644
--- a/src/mmu.rs
+++ b/src/mmu.rs
@@ -236,7 +236,7 @@ impl Mmu {
         self.boot_active = value;
     }
 
-    pub fn clock_dma(&mut self, _cycles: u8) {
+    pub fn clock_dma(&mut self, _cycles: u16) {
         if !self.dma.active() {
             return;
         }
diff --git a/src/ppu.rs b/src/ppu.rs
index d8c64c84..946f6ac4 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -589,7 +589,7 @@ impl Ppu {
         self.dmg_compat = false;
     }
 
-    pub fn clock(&mut self, cycles: u8) {
+    pub fn clock(&mut self, cycles: u16) {
         // in case the LCD is currently off then we skip the current
         // clock operation the PPU should not work
         if !self.switch_lcd {
diff --git a/src/serial.rs b/src/serial.rs
index a9bd6205..7d0d1d44 100644
--- a/src/serial.rs
+++ b/src/serial.rs
@@ -68,7 +68,7 @@ impl Serial {
         self.int_serial = false;
     }
 
-    pub fn clock(&mut self, cycles: u8) {
+    pub fn clock(&mut self, cycles: u16) {
         if !self.transferring {
             return;
         }
diff --git a/src/timer.rs b/src/timer.rs
index 0150496f..7adc5fd9 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -39,7 +39,7 @@ impl Timer {
         self.int_tima = false;
     }
 
-    pub fn clock(&mut self, cycles: u8) {
+    pub fn clock(&mut self, cycles: u16) {
         self.div_clock += cycles as u16;
         while self.div_clock >= 256 {
             self.div = self.div.wrapping_add(1);
-- 
GitLab