From 5fc2d300c24df84a840a24607608cbb91ffef3f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 25 Feb 2024 23:31:13 +0000
Subject: [PATCH] fix: interrupt timing issue

Allows blargg's test ROM to pass.
---
 CHANGELOG.md                                    |   2 +-
 .../blargg/interrupt_time/interrupt_time.png    | Bin 0 -> 480 bytes
 frontends/sdl/src/test.rs                       |  16 ++++++++++++++++
 src/cpu.rs                                      |  10 +++++-----
 4 files changed, 22 insertions(+), 6 deletions(-)
 create mode 100644 frontends/sdl/res/test/blargg/interrupt_time/interrupt_time.png

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac870e90..e951e8fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Fixed
 
-*
+* Issue related to interrupt timing, reduce interrupt to 20 cycles instead of 24
 
 ## [0.9.18] - 2024-01-02
 
diff --git a/frontends/sdl/res/test/blargg/interrupt_time/interrupt_time.png b/frontends/sdl/res/test/blargg/interrupt_time/interrupt_time.png
new file mode 100644
index 0000000000000000000000000000000000000000..67638ca4b6baee0f7ecc321b2ce1a5fbf3d007ac
GIT binary patch
literal 480
zcmeAS@N?(olHy`uVBq!ia0y~yU|7Jwz%YS>fq{Wx)jj(d1_s9Eo-U3d6}R5rx;d@M
zfT!VM(e&^2x8im=dN=E|>N(b*PrPz!O1_h4kqq1W9DB9~21X_p4gm!RVi`L8BH`|l
zDfjXP&&-W@AOD5Fj_K%L^(oh*?d|;a_ejY<{(JMvzeaI;iFz-KhW!Oy%b8z)ufAQy
zqWWv{-)_doM}BRHbkMhR*`rgyY0X}ezF7SFf>|z?OlL4HKdNr1ut>@H|KFXT-blTf
z;j%&n<hF`ElXQ$~-&N>7*tBie)LFZ2<AgPmFHYIA{<QRZj*?*OCzm~*_Wu8>xsBJP
zUi5#CT#oR8?CgLj)mM9KmN!1S6?gRZPrv!6ci3k>Q_H^aC$wh1&5H0TTk8Vq8xz;b
zUlBC9&ac;a?AJkk!7WqS&oWJZzbMpqvHY5u?6bc&tA9$kU00yYf9nPN^-l|C)_oBF
zoN&9&z?}aQKRC<|T+orx<Lv#{xi_qPE%WoO;r9)U<=<C!J-v{tA*&>@OGMUi{yqE4
uqB}%w|L)3W`6~2gADibDkf$<!ePq}wtD?Vh&YJI_sPlC7b6Mw<&;$UgX~c^F

literal 0
HcmV?d00001

diff --git a/frontends/sdl/src/test.rs b/frontends/sdl/src/test.rs
index 44dd24f7..e1beab0a 100644
--- a/frontends/sdl/src/test.rs
+++ b/frontends/sdl/src/test.rs
@@ -70,6 +70,22 @@ mod tests {
         assert!(image_result);
     }
 
+    #[test]
+    fn test_blargg_interrupt_time() {
+        let result: [u8; FRAME_BUFFER_SIZE] = run_image_test(
+            "../../res/roms/test/blargg/interrupt_time/interrupt_time.gb",
+            Some(20000000),
+            TestOptions {
+                mode: Some(GameBoyMode::Cgb),
+                ..TestOptions::default()
+            },
+        )
+        .unwrap();
+        let image_result =
+            compare_images(&result, "res/test/blargg/interrupt_time/interrupt_time.png");
+        assert!(image_result);
+    }
+
     #[test]
     fn test_blargg_dmg_sound() {
         let result: [u8; FRAME_BUFFER_SIZE] = run_image_test(
diff --git a/src/cpu.rs b/src/cpu.rs
index 91037dbb..ad5c3f96 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -172,7 +172,7 @@ impl Cpu {
                     self.halted = false;
                 }
 
-                return 24;
+                return 20;
             } else if (self.mmu.ie & 0x02 == 0x02) && self.mmu.ppu().int_stat() {
                 debugln!("Going to run LCD STAT interrupt handler (0x48)");
 
@@ -190,7 +190,7 @@ impl Cpu {
                     self.halted = false;
                 }
 
-                return 24;
+                return 20;
             } else if (self.mmu.ie & 0x04 == 0x04) && self.mmu.timer().int_tima() {
                 debugln!("Going to run Timer interrupt handler (0x50)");
 
@@ -208,7 +208,7 @@ impl Cpu {
                     self.halted = false;
                 }
 
-                return 24;
+                return 20;
             } else if (self.mmu.ie & 0x08 == 0x08) && self.mmu.serial().int_serial() {
                 debugln!("Going to run Serial interrupt handler (0x58)");
 
@@ -226,7 +226,7 @@ impl Cpu {
                     self.halted = false;
                 }
 
-                return 24;
+                return 20;
             } else if (self.mmu.ie & 0x10 == 0x10) && self.mmu.pad().int_pad() {
                 debugln!("Going to run JoyPad interrupt handler (0x60)");
 
@@ -244,7 +244,7 @@ impl Cpu {
                     self.halted = false;
                 }
 
-                return 24;
+                return 20;
             }
         }
 
-- 
GitLab