Better DUART delay calculation

This commit is contained in:
Seth Morabito 2022-09-03 16:41:59 -07:00
parent c3677ab006
commit 829a72ebbc
2 changed files with 21 additions and 21 deletions

View File

@ -1034,7 +1034,7 @@ impl Cpu {
#[allow(clippy::cognitive_complexity)]
fn dispatch(&mut self, bus: &mut Bus) -> Result<i32, CpuError> {
self.steps += 1;
self.steps = self.steps.wrapping_add(1);
// Update anything that needs updating.
bus.service();

View File

@ -1,5 +1,3 @@
#![allow(clippy::unreadable_literal)]
use crate::bus::AccessCode;
use crate::bus::Device;
use crate::err::BusError;
@ -19,17 +17,11 @@ const ADDRESS_RANGE: Range<usize> = START_ADDR..END_ADDR;
// Vertical blanks should occur at 60Hz. This value is in nanoseconds
const VERTICAL_BLANK_DELAY: u32 = 16_666_666; // 60 Hz
// Delay rates, in nanoseconds, selected when ACR[7] = 0
const DELAY_RATES_A: [u32; 13] = [
160000000, 72727272, 59259260, 40000000, 26666668, 13333334, 6666667, 7619047, 3333333,
1666666, 1111111, 833333, 208333,
];
const BAUD_RATES_A: [u32; 13] =
[50, 110, 135, 200, 300, 600, 1200, 1050, 2400, 4800, 7200, 9600, 38400];
// Delay rates, in nanoseconds, selected when ACR[7] = 1
const DELAY_RATES_B: [u32; 13] = [
106666672, 72727272, 59259260, 53333336, 26666668, 13333334, 6666667, 4000000, 3333333,
1666666, 4444444, 833333, 416666,
];
const BAUD_RATES_B: [u32; 13] =
[75, 110, 135, 150, 300, 600, 1200, 2000, 2400, 4800, 1800, 9600, 19200];
const PORT_0: usize = 0;
const PORT_1: usize = 1;
@ -148,6 +140,21 @@ impl Default for Duart {
}
}
/// Compute the delay rate to wait for the next transmit or receive
fn delay_rate(csr_bits: u8, acr_bits: u8) -> u32 {
const NS_PER_SEC: u32 = 1_100_000_000;
const BITS_PER_CHAR: u32 = 7;
let baud_bits: usize = ((csr_bits >> 4) & 0xf) as usize;
let baud_rate = if acr_bits & 0x80 == 0 {
BAUD_RATES_A[baud_bits]
} else {
BAUD_RATES_B[baud_bits]
};
NS_PER_SEC / (baud_rate / BITS_PER_CHAR)
}
impl Duart {
pub fn new() -> Duart {
Duart {
@ -476,15 +483,8 @@ impl Device for Duart {
ctx.mode_ptr = (ctx.mode_ptr + 1) % 2;
}
CSRA => {
// Set the baud rate.
let baud_bits: usize = ((val >> 4) & 0xf) as usize;
let delay = if self.acr & 0x80 == 0 {
DELAY_RATES_A[baud_bits]
} else {
DELAY_RATES_B[baud_bits]
};
let mut ctx = &mut self.ports[PORT_0];
ctx.char_delay = Duration::new(0, delay);
ctx.char_delay = Duration::new(0, delay_rate(val, self.acr));
}
CRA => {
self.handle_command(val, PORT_0);