From 8dc01b59c207da7841999ee88cedf828d0f5cb35 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Thu, 16 Mar 2023 18:42:23 +1100 Subject: [PATCH] serial clock @ 8khz --- lib/src/processor/memory/mmio/serial.rs | 66 ++++++++++++++----------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/lib/src/processor/memory/mmio/serial.rs b/lib/src/processor/memory/mmio/serial.rs index a5407b9..2683487 100644 --- a/lib/src/processor/memory/mmio/serial.rs +++ b/lib/src/processor/memory/mmio/serial.rs @@ -5,7 +5,7 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::util::get_bit; +use crate::{constants::CLOCK_SPEED, util::get_bit}; #[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] enum ClockSource { @@ -58,6 +58,7 @@ struct InputByte { } const BYTE_DELAY: usize = 2000; +const CLOCK_DIV: usize = CLOCK_SPEED / 8192; impl InputByte { fn advance(&mut self, rx: &Option>) -> u8 { @@ -104,6 +105,7 @@ pub struct Serial { bits_remaining: u8, control: SerialControl, target: SerialTarget, + clock_inc: usize, } #[derive(Serialize, Deserialize)] @@ -113,6 +115,7 @@ pub struct SerialSaveState { input_byte: InputByte, bits_remaining: u8, control: SerialControl, + clock_inc: usize, } impl SerialSaveState { @@ -123,6 +126,7 @@ impl SerialSaveState { input_byte: serial.input_byte, bits_remaining: serial.bits_remaining, control: serial.control, + clock_inc: serial.clock_inc, } } } @@ -136,6 +140,7 @@ impl Serial { bits_remaining: 7, control: SerialControl::default(), target, + clock_inc: 0, } } @@ -147,6 +152,7 @@ impl Serial { bits_remaining: state.bits_remaining, control: state.control, target, + clock_inc: state.clock_inc, } } @@ -165,36 +171,40 @@ impl Serial { &None }; for _ in 0..steps { - 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(); - } - SerialTarget::Custom { rx: _, tx } => { - if let Some(tx) = tx { - tx.send(self.output_byte).unwrap(); + 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); + } + 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 => {} } - SerialTarget::None => {} + 7 + } else { + remainder } - 7 - } else { - remainder } } }