rx82 0.1.0

An emulator for the RX82 retro computer system.
Documentation
use core::time::Duration;
use std::{thread::sleep, time::Instant};

use crate::{bus::Bus, device::Device};

/// The system clock.
#[non_exhaustive]
pub struct Clock {
    /// Time the next tick is due.
    pub next_tick: Instant,
    /// Target duration for each tick.
    pub tick_duration: Duration,
}

impl Default for Clock {
    /// Creates a default [`Clock`] with a nominal frequency of 4MHz.
    #[inline]
    fn default() -> Self {
        Self {
            next_tick: Instant::now(),
            tick_duration: Duration::from_nanos(250), // 4MHz
        }
    }
}

impl Device for Clock {
    /// Waits until the next tick is due.
    ///
    /// If the projected next tick time overflows `usize`, or we are already past the
    /// next tick time, returns immediately.
    #[inline]
    fn tick(&mut self, _bus: &mut Bus) {
        let now = Instant::now();
        self.next_tick = self
            .next_tick
            .checked_add(self.tick_duration)
            .unwrap_or(now); // too far in the future
        let wait = self.next_tick.saturating_duration_since(now);
        if !wait.is_zero() {
            sleep(wait);
        }
    }
}