From 21ce4632e4c0ae6b08d6bbff1116fbdebece6465 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 16 Apr 2023 02:19:33 +0100
Subject: [PATCH] feat: added allow slave flag

---
 src/devices/printer.rs |  4 ++++
 src/devices/stdout.rs  |  4 ++++
 src/serial.rs          | 22 +++++++++++++++++-----
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/devices/printer.rs b/src/devices/printer.rs
index a9ede2b1..c262fc43 100644
--- a/src/devices/printer.rs
+++ b/src/devices/printer.rs
@@ -246,6 +246,10 @@ impl SerialDevice for PrinterDevice {
             self.state = PrinterState::from_u8(self.state as u8 + 1);
         }
     }
+
+    fn allow_slave(&self) -> bool {
+        false
+    }
 }
 
 impl Default for PrinterDevice {
diff --git a/src/devices/stdout.rs b/src/devices/stdout.rs
index f9a7ad4f..a2f7528c 100644
--- a/src/devices/stdout.rs
+++ b/src/devices/stdout.rs
@@ -23,6 +23,10 @@ impl SerialDevice for StdoutDevice {
             stdout().flush().unwrap();
         }
     }
+
+    fn allow_slave(&self) -> bool {
+        false
+    }
 }
 
 impl Default for StdoutDevice {
diff --git a/src/serial.rs b/src/serial.rs
index 5726ac29..6e79b68f 100644
--- a/src/serial.rs
+++ b/src/serial.rs
@@ -3,6 +3,11 @@ use crate::warnln;
 pub trait SerialDevice {
     fn send(&mut self) -> u8;
     fn receive(&mut self, byte: u8);
+
+    /// Whether the serial device "driver" supports slave mode
+    /// simulating an external clock source. Or if instead the
+    /// clock should always be generated by the running device.
+    fn allow_slave(&self) -> bool;
 }
 
 pub struct Serial {
@@ -89,15 +94,18 @@ impl Serial {
                 self.clock_speed = value & 0x02 == 0x02;
                 self.transferring = value & 0x80 == 0x80;
 
-                // @TODO: THIS SEEMS LIKE A HACK, we'll need to check with
-                // the device driver how to handle no communication and receive
-                // we must simulate no cable communication
-                if self.transferring && !self.shift_clock {
+                // in case the clock is meant to be set by the attached device
+                // and the current Game Boy is meant to be running in slave mode
+                // then checks if the attached device "driver" allows clock set
+                // by external device and if not then ignores the transfer request
+                // by immediately disabling the transferring flag
+                if !self.shift_clock && !self.device.allow_slave() {
                     self.transferring = false;
                 }
+
                 // in case a transfer of byte has been requested and
                 // this is the then we need to start the transfer setup
-                else if self.transferring {
+                if self.transferring {
                     // @TODO: if the GBC mode exists there should
                     // be special check logic here
                     //self.length = if self.gb.is_cgb() && self.clock_speed { 16 } else { 512 };
@@ -189,6 +197,10 @@ impl SerialDevice for NullDevice {
     }
 
     fn receive(&mut self, _: u8) {}
+
+    fn allow_slave(&self) -> bool {
+        false
+    }
 }
 
 impl Default for NullDevice {
-- 
GitLab