serial clock kinda sux tbh... put it behind a feature flag

This commit is contained in:
Alex Janka 2023-03-17 10:42:27 +11:00
parent 8dc01b59c2
commit 1e01308605
2 changed files with 46 additions and 34 deletions

View file

@ -6,6 +6,7 @@ edition = "2021"
[features] [features]
default = [] default = []
async = [] async = []
clocked-serial = []
[dependencies] [dependencies]
rand = "0.8.5" rand = "0.8.5"

View file

@ -1,11 +1,12 @@
use crate::util::get_bit;
use serde::{Deserialize, Serialize};
use std::{ use std::{
io::{stdout, Write}, io::{stdout, Write},
sync::mpsc::{Receiver, Sender}, sync::mpsc::{Receiver, Sender},
}; };
use serde::{Deserialize, Serialize}; #[cfg(feature = "clocked-serial")]
use crate::constants::CLOCK_SPEED;
use crate::{constants::CLOCK_SPEED, util::get_bit};
#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] #[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)]
enum ClockSource { enum ClockSource {
@ -58,6 +59,7 @@ struct InputByte {
} }
const BYTE_DELAY: usize = 2000; const BYTE_DELAY: usize = 2000;
#[cfg(feature = "clocked-serial")]
const CLOCK_DIV: usize = CLOCK_SPEED / 8192; const CLOCK_DIV: usize = CLOCK_SPEED / 8192;
impl InputByte { impl InputByte {
@ -105,6 +107,7 @@ pub struct Serial {
bits_remaining: u8, bits_remaining: u8,
control: SerialControl, control: SerialControl,
target: SerialTarget, target: SerialTarget,
#[cfg(feature = "clocked-serial")]
clock_inc: usize, clock_inc: usize,
} }
@ -115,6 +118,7 @@ pub struct SerialSaveState {
input_byte: InputByte, input_byte: InputByte,
bits_remaining: u8, bits_remaining: u8,
control: SerialControl, control: SerialControl,
#[cfg(feature = "clocked-serial")]
clock_inc: usize, clock_inc: usize,
} }
@ -126,6 +130,7 @@ impl SerialSaveState {
input_byte: serial.input_byte, input_byte: serial.input_byte,
bits_remaining: serial.bits_remaining, bits_remaining: serial.bits_remaining,
control: serial.control, control: serial.control,
#[cfg(feature = "clocked-serial")]
clock_inc: serial.clock_inc, clock_inc: serial.clock_inc,
} }
} }
@ -140,6 +145,7 @@ impl Serial {
bits_remaining: 7, bits_remaining: 7,
control: SerialControl::default(), control: SerialControl::default(),
target, target,
#[cfg(feature = "clocked-serial")]
clock_inc: 0, clock_inc: 0,
} }
} }
@ -152,6 +158,7 @@ impl Serial {
bits_remaining: state.bits_remaining, bits_remaining: state.bits_remaining,
control: state.control, control: state.control,
target, target,
#[cfg(feature = "clocked-serial")]
clock_inc: state.clock_inc, clock_inc: state.clock_inc,
} }
} }
@ -171,40 +178,44 @@ impl Serial {
&None &None
}; };
for _ in 0..steps { for _ in 0..steps {
self.clock_inc += 1; #[cfg(feature = "clocked-serial")]
if self.clock_inc >= CLOCK_DIV { {
self.clock_inc %= CLOCK_DIV; self.clock_inc += 1;
if ime { if self.clock_inc < CLOCK_DIV {
self.input_byte.input_delay = self.input_byte.input_delay.saturating_sub(1); continue;
} }
if (self.control.transfer_in_progress self.clock_inc %= CLOCK_DIV;
&& self.control.clock_source == ClockSource::Internal) }
|| (self.control.clock_source == ClockSource::External if ime {
&& self.input_byte.is_ready(rx) self.input_byte.input_delay = self.input_byte.input_delay.saturating_sub(1);
&& ime) }
{ if (self.control.transfer_in_progress
self.output_byte = self.output_byte << 1 | self.byte >> 7; && self.control.clock_source == ClockSource::Internal)
self.byte = (self.byte << 1) | self.input_byte.advance(rx); || (self.control.clock_source == ClockSource::External
let (remainder, finished) = self.bits_remaining.overflowing_sub(1); && self.input_byte.is_ready(rx)
self.bits_remaining = if finished { && ime)
self.control.transfer_in_progress = false; {
will_interrupt = true; self.output_byte = self.output_byte << 1 | self.byte >> 7;
match &self.target { self.byte = (self.byte << 1) | self.input_byte.advance(rx);
SerialTarget::Stdout => { let (remainder, finished) = self.bits_remaining.overflowing_sub(1);
print!("{}", self.output_byte as char); self.bits_remaining = if finished {
stdout().flush().unwrap(); self.control.transfer_in_progress = false;
} will_interrupt = true;
SerialTarget::Custom { rx: _, tx } => { match &self.target {
if let Some(tx) = tx { SerialTarget::Stdout => {
tx.send(self.output_byte).unwrap(); print!("{}", self.output_byte as char);
} stdout().flush().unwrap();
}
SerialTarget::None => {}
} }
7 SerialTarget::Custom { rx: _, tx } => {
} else { if let Some(tx) = tx {
remainder tx.send(self.output_byte).unwrap();
}
}
SerialTarget::None => {}
} }
7
} else {
remainder
} }
} }
} }