From 1e013086050e8ae69f1701c3e596416b1c9e0a97 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Fri, 17 Mar 2023 10:42:27 +1100 Subject: [PATCH] serial clock kinda sux tbh... put it behind a feature flag --- lib/Cargo.toml | 1 + lib/src/processor/memory/mmio/serial.rs | 79 ++++++++++++++----------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index e99a305..04f8761 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [features] default = [] async = [] +clocked-serial = [] [dependencies] rand = "0.8.5" diff --git a/lib/src/processor/memory/mmio/serial.rs b/lib/src/processor/memory/mmio/serial.rs index 2683487..e3065e6 100644 --- a/lib/src/processor/memory/mmio/serial.rs +++ b/lib/src/processor/memory/mmio/serial.rs @@ -1,11 +1,12 @@ +use crate::util::get_bit; +use serde::{Deserialize, Serialize}; use std::{ io::{stdout, Write}, sync::mpsc::{Receiver, Sender}, }; -use serde::{Deserialize, Serialize}; - -use crate::{constants::CLOCK_SPEED, util::get_bit}; +#[cfg(feature = "clocked-serial")] +use crate::constants::CLOCK_SPEED; #[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] enum ClockSource { @@ -58,6 +59,7 @@ struct InputByte { } const BYTE_DELAY: usize = 2000; +#[cfg(feature = "clocked-serial")] const CLOCK_DIV: usize = CLOCK_SPEED / 8192; impl InputByte { @@ -105,6 +107,7 @@ pub struct Serial { bits_remaining: u8, control: SerialControl, target: SerialTarget, + #[cfg(feature = "clocked-serial")] clock_inc: usize, } @@ -115,6 +118,7 @@ pub struct SerialSaveState { input_byte: InputByte, bits_remaining: u8, control: SerialControl, + #[cfg(feature = "clocked-serial")] clock_inc: usize, } @@ -126,6 +130,7 @@ impl SerialSaveState { input_byte: serial.input_byte, bits_remaining: serial.bits_remaining, control: serial.control, + #[cfg(feature = "clocked-serial")] clock_inc: serial.clock_inc, } } @@ -140,6 +145,7 @@ impl Serial { bits_remaining: 7, control: SerialControl::default(), target, + #[cfg(feature = "clocked-serial")] clock_inc: 0, } } @@ -152,6 +158,7 @@ impl Serial { bits_remaining: state.bits_remaining, control: state.control, target, + #[cfg(feature = "clocked-serial")] clock_inc: state.clock_inc, } } @@ -171,40 +178,44 @@ impl Serial { &None }; for _ in 0..steps { - self.clock_inc += 1; - if self.clock_inc >= CLOCK_DIV { - self.clock_inc %= CLOCK_DIV; - if ime { - self.input_byte.input_delay = self.input_byte.input_delay.saturating_sub(1); + #[cfg(feature = "clocked-serial")] + { + self.clock_inc += 1; + if self.clock_inc < CLOCK_DIV { + continue; } - if (self.control.transfer_in_progress - && self.control.clock_source == ClockSource::Internal) - || (self.control.clock_source == ClockSource::External - && self.input_byte.is_ready(rx) - && ime) - { - self.output_byte = self.output_byte << 1 | self.byte >> 7; - self.byte = (self.byte << 1) | self.input_byte.advance(rx); - let (remainder, finished) = self.bits_remaining.overflowing_sub(1); - self.bits_remaining = if finished { - self.control.transfer_in_progress = false; - will_interrupt = true; - match &self.target { - SerialTarget::Stdout => { - print!("{}", self.output_byte as char); - stdout().flush().unwrap(); - } - SerialTarget::Custom { rx: _, tx } => { - if let Some(tx) = tx { - tx.send(self.output_byte).unwrap(); - } - } - SerialTarget::None => {} + self.clock_inc %= CLOCK_DIV; + } + if ime { + self.input_byte.input_delay = self.input_byte.input_delay.saturating_sub(1); + } + if (self.control.transfer_in_progress + && self.control.clock_source == ClockSource::Internal) + || (self.control.clock_source == ClockSource::External + && self.input_byte.is_ready(rx) + && ime) + { + self.output_byte = self.output_byte << 1 | self.byte >> 7; + self.byte = (self.byte << 1) | self.input_byte.advance(rx); + let (remainder, finished) = self.bits_remaining.overflowing_sub(1); + self.bits_remaining = if finished { + self.control.transfer_in_progress = false; + will_interrupt = true; + match &self.target { + SerialTarget::Stdout => { + print!("{}", self.output_byte as char); + stdout().flush().unwrap(); } - 7 - } else { - remainder + SerialTarget::Custom { rx: _, tx } => { + if let Some(tx) = tx { + tx.send(self.output_byte).unwrap(); + } + } + SerialTarget::None => {} } + 7 + } else { + remainder } } }