Skip to main content

gb/
timer.rs

1//! The timer and the free-running divider.
2//!
3//! [`divider`] is free-running and cannot be configured; the timer counts at a
4//! rate a program picks and raises an interrupt when it overflows. See
5//! <https://gbdev.io/pandocs/Timer_and_Divider_Registers.html>.
6//!
7//! [`Timer::start`] hands back the proof that ticks are being counted.
8//! Timestamps come from it and cannot outlive it.
9//!
10//! ```ignore
11//! let timer = unsafe { Timer::start(rate::Hz256) }.unwrap();
12//! let began = timer.now();
13//! // ...
14//! if began.elapsed() >= Duration::from_ms(5000) {
15//!     expire();
16//! }
17//! ```
18//!
19//! Carrying the rate in the type is what settles the arithmetic behind
20//! [`Duration`] at compile time, and it keeps a span from one rate from being
21//! compared against a span from another.
22//!
23//! [`Duration`] is not [`core::time::Duration`], which holds a `u64` of seconds
24//! beside a `u32` of nanoseconds and does its arithmetic to match; a span here
25//! is a `u32` of ticks.
26//!
27//! # A handler of one's own
28//!
29//! A program that wants work at the tick, a sound driver most often, writes
30//! `#[gb::rt::interrupt(Timer)]` and takes that vector. Nothing reports it, and
31//! the count then moves only where the handler calls [`timer_tick`].
32//!
33//! The rate is still [`Timer::start`]'s to set. The eleven in [`rate`] are
34//! powers of two; a tempo that falls between them means implementing [`Rate`]
35//! for a type of one's own.
36
37use core::marker::PhantomData;
38use core::ops::{Add, Sub};
39
40use crate::mmio::{DIV, Interrupts, TAC, TIMA, TMA, TimerClock, TimerCtrl};
41
42// Little-endian, and incremented a byte at a time so that a tick costs one
43// `ldh` pair in the common case.
44crate::hram! {
45    static TICKS: HramArea<4>;
46}
47
48/// Advance the tick count.
49///
50/// Needed only by a timer handler that replaced the one this module installs.
51/// The rate is still [`Timer::start`]'s to set, so the two do not drift apart.
52#[inline]
53pub fn timer_tick() {
54    unsafe {
55        core::arch::asm!(
56            "ldh a, ({t} + 0)", "inc a", "ldh ({t} + 0), a", "jr nz, 2f",
57            "ldh a, ({t} + 1)", "inc a", "ldh ({t} + 1), a", "jr nz, 2f",
58            "ldh a, ({t} + 2)", "inc a", "ldh ({t} + 2), a", "jr nz, 2f",
59            "ldh a, ({t} + 3)", "inc a", "ldh ({t} + 3), a",
60            "2:",
61            t = sym TICKS,
62            out("a") _,
63            options(nostack),
64        );
65    }
66}
67
68// Weak, so a handler in the program replaces it. Not `pub`: the symbol is what
69// the vector needs, and calling this as a function would return through `reti`.
70#[linkage = "weak"]
71#[unsafe(no_mangle)]
72extern "z80-interrupt" fn on_timer() {
73    timer_tick();
74}
75
76/// Read the four bytes, retrying until the top three agree across the low one.
77///
78/// The handler may land in the middle, and `di` is not an option here: it would
79/// end a critical section the caller was inside. Reading the high bytes on both
80/// sides of the low one catches a carry that crossed the read.
81fn count_ticks() -> u32 {
82    let (b0, b1, b2, b3): (u8, u8, u8, u8);
83    unsafe {
84        core::arch::asm!(
85            "2:",
86            "ldh a, ({t} + 3)", "ld d, a",
87            "ldh a, ({t} + 2)", "ld e, a",
88            "ldh a, ({t} + 1)", "ld b, a",
89            "ldh a, ({t} + 0)", "ld c, a",
90            "ldh a, ({t} + 1)", "cp b", "jr nz, 2b",
91            "ldh a, ({t} + 2)", "cp e", "jr nz, 2b",
92            "ldh a, ({t} + 3)", "cp d", "jr nz, 2b",
93            t = sym TICKS,
94            out("a") _,
95            out("b") b1,
96            out("c") b0,
97            out("d") b3,
98            out("e") b2,
99            options(nostack, readonly),
100        );
101    }
102    u32::from_le_bytes([b0, b1, b2, b3])
103}
104
105/// The divider, which counts at 16384 Hz whatever the timer is doing.
106///
107/// Programs read it for a value that is hard to predict, a random seed most
108/// often.
109#[inline]
110pub fn divider() -> u8 {
111    DIV.read()
112}
113
114/// Reset the divider to zero.
115///
116/// The timer shares the divider's counter, so this can advance it once. The APU
117/// counts its envelopes and length timers off the same place; those step early
118/// as well.
119#[inline]
120pub fn reset_divider() {
121    DIV.write(0);
122}
123
124/// How often the timer overflows, as a type.
125///
126/// An implementation names an input clock and what to divide it by, which is
127/// what the hardware takes; everything else follows. [`rate`] has the eleven a
128/// program can usually afford, and an implementation of one's own is how to
129/// reach a rate between them: a music driver wanting a particular tempo would
130/// write it out rather than round to a power of two.
131///
132/// ```ignore
133/// #[derive(Clone, Copy)]
134/// struct Tempo;
135///
136/// impl Rate for Tempo {
137///     const CLOCK: TimerClock = TimerClock::Hz65536;
138///     const DIVISOR: u16 = 66;      // 992.96 Hz, the closest to a millisecond
139/// }
140/// ```
141pub trait Rate: Copy {
142    /// The input clock the hardware counts at.
143    const CLOCK: TimerClock;
144
145    /// What that clock is divided by, `1..=256`.
146    const DIVISOR: u16;
147
148    /// Overflows per second, rounded down.
149    ///
150    /// The clock over the divisor is the exact answer; this one loses the
151    /// fraction, so 992.96 Hz reads as 992.
152    const HZ: u32 = clock_hz(Self::CLOCK) / Self::DIVISOR as u32;
153
154    /// What the hardware reloads the counter with.
155    const MODULO: u8 = {
156        assert!(Self::DIVISOR >= 1 && Self::DIVISOR <= 256, "a divisor is one of 1..=256");
157        (256 - Self::DIVISOR) as u8
158    };
159
160    /// What ticks are multiplied by to reach milliseconds, before
161    /// [`MS_SHIFT`](Self::MS_SHIFT).
162    ///
163    /// A tick is `1000 * divisor / clock` ms. 1000 is `8 * 125` and the clock is
164    /// a power of two, so the division comes out as a shift; the twos the
165    /// divisor brings are cancelled here rather than left to make this larger
166    /// than it need be.
167    const MS_NUM: u32 = reduce(125 * Self::DIVISOR as u32, clock_hz(Self::CLOCK).trailing_zeros() - 3).0;
168
169    /// What the product is shifted by to reach milliseconds.
170    const MS_SHIFT: u32 = reduce(125 * Self::DIVISOR as u32, clock_hz(Self::CLOCK).trailing_zeros() - 3).1;
171}
172
173/// What a clock counts at.
174///
175/// The names are the nominal ones; the timer is among the things CGB double
176/// speed mode runs twice as fast, so a machine built for it counts double.
177const fn clock_hz(clock: TimerClock) -> u32 {
178    let nominal = match clock {
179        TimerClock::Hz4096 => 4096,
180        TimerClock::Hz16384 => 16384,
181        TimerClock::Hz65536 => 65536,
182        TimerClock::Hz262144 => 262_144,
183    };
184    nominal << crate::rt::DOUBLE_SPEED as u32
185}
186
187/// Cancel the twos shared by the multiplier and the shift, so [`Duration::ms`]
188/// does not saturate sooner than it has to.
189const fn reduce(mut num: u32, mut shift: u32) -> (u32, u32) {
190    while shift > 0 && num % 2 == 0 {
191        num /= 2;
192        shift -= 1;
193    }
194    (num, shift)
195}
196
197/// The rates the timer can be run at.
198///
199/// Each names what it counts. The hardware divides one of four clocks by a
200/// power of two, and these are the ones a program can afford: every overflow
201/// runs the handler.
202///
203/// | Hz | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 |
204/// |---|---|---|---|---|---|---|---|---|---|---|---|
205/// | CPU | 0.05% | 0.1% | 0.2% | 0.4% | 0.7% | 1.5% | 2.9% | 5.9% | 12% | 23% | 47% |
206///
207/// The figures are for an original Game Boy. CGB double speed mode halves each
208/// of them, since the handler costs the same and the processor issues twice as
209/// much in a second.
210///
211/// The hardware counts faster than 16384 Hz, but the handler would take more of
212/// the processor than the program has left to give.
213///
214/// Each rate is paired with the fastest clock that reaches it, which leaves
215/// [`Timer::count`] dividing the period as finely as it can.
216pub mod rate {
217    use crate::mmio::TimerClock;
218
219    macro_rules! rates {
220        ($($name:ident = $hz:literal, $clock:ident / $div:literal;)*) => {$(
221            #[doc = concat!($hz, " Hz.")]
222            #[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
223            pub struct $name;
224
225            impl super::Rate for $name {
226                const CLOCK: TimerClock = TimerClock::$clock;
227                const DIVISOR: u16 = $div;
228            }
229
230            // The name is the derived rate, not a second source of truth.
231            const _: () = assert!(<$name as super::Rate>::HZ == $hz);
232        )*};
233    }
234
235    // The clock names are nominal, so CGB double speed mode needs a different
236    // divisor for the same rate.
237    #[cfg(not(feature = "cgb-double-speed"))]
238    rates! {
239        Hz16 = 16, Hz4096 / 256;
240        Hz32 = 32, Hz4096 / 128;
241        Hz64 = 64, Hz16384 / 256;
242        Hz128 = 128, Hz16384 / 128;
243        Hz256 = 256, Hz65536 / 256;
244        Hz512 = 512, Hz65536 / 128;
245        Hz1024 = 1024, Hz262144 / 256;
246        Hz2048 = 2048, Hz262144 / 128;
247        Hz4096 = 4096, Hz262144 / 64;
248        Hz8192 = 8192, Hz262144 / 32;
249        Hz16384 = 16384, Hz262144 / 16;
250    }
251
252    #[cfg(feature = "cgb-double-speed")]
253    rates! {
254        Hz32 = 32, Hz4096 / 256;
255        Hz64 = 64, Hz4096 / 128;
256        Hz128 = 128, Hz16384 / 256;
257        Hz256 = 256, Hz16384 / 128;
258        Hz512 = 512, Hz65536 / 256;
259        Hz1024 = 1024, Hz65536 / 128;
260        Hz2048 = 2048, Hz262144 / 256;
261        Hz4096 = 4096, Hz262144 / 128;
262        Hz8192 = 8192, Hz262144 / 64;
263        Hz16384 = 16384, Hz262144 / 32;
264    }
265}
266
267/// A running timer, and the scope its timestamps belong to.
268///
269/// [`stop`](Self::stop) takes it by value, so a timestamp taken from it keeps
270/// the count running for as long as it is held.
271pub struct Timer<R: Rate>(PhantomData<R>);
272
273// A proof about the hardware's current state belongs to the context that made it.
274impl<R: Rate> !Send for Timer<R> {}
275impl<R: Rate> !Sync for Timer<R> {}
276
277impl<R: Rate> Timer<R> {
278    /// Start counting at `R`, or `None` if the timer is already running.
279    ///
280    /// Writing the control register can advance the timer once, so the first
281    /// interrupt may come early.
282    ///
283    /// # Safety
284    ///
285    /// Lets the timer interrupt through and turns interrupts on. That is
286    /// preemption, which the surrounding code may have been written to rule
287    /// out, and it happens whether or not a timer is handed back.
288    #[inline]
289    pub unsafe fn start(_rate: R) -> Option<Self> {
290        // `IE` is read and written back, and another module may have turned
291        // interrupts on already, so the pair is kept off the air.
292        crate::interrupt::disable();
293        let free = !TAC.read().enable();
294        if free {
295            TMA.write(R::MODULO);
296            TAC.write(TimerCtrl::new().with_clock(R::CLOCK).with_enable(true));
297            unsafe {
298                crate::interrupt::set_enabled(crate::interrupt::enabled() | Interrupts::TIMER);
299            }
300        }
301        unsafe { crate::interrupt::enable() };
302        free.then(|| Timer(PhantomData))
303    }
304
305    /// The tick count now.
306    #[inline]
307    pub fn now(&self) -> Instant<'_, R> {
308        Instant(count_ticks(), PhantomData)
309    }
310
311    /// Sleep until `span` has passed.
312    ///
313    /// The CPU sleeps while waiting, so this does not return if `IE` lacks
314    /// `TIMER` or interrupts are off: the count only moves when the handler
315    /// runs.
316    pub fn wait(&self, span: Duration<R>) {
317        let from = count_ticks();
318        while count_ticks().wrapping_sub(from) < span.0 {
319            crate::interrupt::halt();
320        }
321    }
322
323    /// How far the timer has counted towards its next overflow.
324    ///
325    /// This is the hardware register, so it moves at the input clock rather than
326    /// the overflow rate and costs no interrupt at all.
327    #[inline]
328    pub fn count(&self) -> u8 {
329        TIMA.read()
330    }
331
332    /// Stop counting.
333    #[inline]
334    pub fn stop(self) {
335        TAC.write(TAC.read().with_enable(false));
336    }
337}
338
339/// A point in the tick count.
340///
341/// Comparable and subtractable, and bounded to the [`Timer`] it came from: a
342/// count that stopped and started again would leave it meaning nothing.
343pub struct Instant<'a, R: Rate>(u32, PhantomData<&'a Timer<R>>);
344
345impl<R: Rate> Clone for Instant<'_, R> {
346    fn clone(&self) -> Self {
347        *self
348    }
349}
350impl<R: Rate> Copy for Instant<'_, R> {}
351impl<R: Rate> PartialEq for Instant<'_, R> {
352    fn eq(&self, other: &Self) -> bool {
353        self.0 == other.0
354    }
355}
356impl<R: Rate> Eq for Instant<'_, R> {}
357impl<R: Rate> PartialOrd for Instant<'_, R> {
358    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
359        Some(self.cmp(other))
360    }
361}
362impl<R: Rate> Ord for Instant<'_, R> {
363    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
364        self.0.cmp(&other.0)
365    }
366}
367
368impl<R: Rate> Instant<'_, R> {
369    /// How long since this was taken.
370    #[inline]
371    pub fn elapsed(self) -> Duration<R> {
372        Duration(count_ticks().wrapping_sub(self.0), PhantomData)
373    }
374
375    /// How long from `earlier` to this.
376    ///
377    /// Zero if `earlier` is the later of the two.
378    #[inline]
379    pub fn saturating_duration_since(self, earlier: Self) -> Duration<R> {
380        Duration(self.0.saturating_sub(earlier.0), PhantomData)
381    }
382
383    /// How long from `earlier` to this, or `None` if `earlier` is the later.
384    #[inline]
385    pub fn checked_duration_since(self, earlier: Self) -> Option<Duration<R>> {
386        self.0.checked_sub(earlier.0).map(|d| Duration(d, PhantomData))
387    }
388}
389
390impl<R: Rate> Sub for Instant<'_, R> {
391    type Output = Duration<R>;
392
393    /// How long from `earlier` to this, wrapping if they are the wrong way round.
394    #[inline]
395    fn sub(self, earlier: Self) -> Duration<R> {
396        Duration(self.0.wrapping_sub(earlier.0), PhantomData)
397    }
398}
399
400impl<'a, R: Rate> Add<Duration<R>> for Instant<'a, R> {
401    type Output = Instant<'a, R>;
402
403    #[inline]
404    fn add(self, span: Duration<R>) -> Self {
405        Instant(self.0.wrapping_add(span.0), PhantomData)
406    }
407}
408
409impl<'a, R: Rate> Sub<Duration<R>> for Instant<'a, R> {
410    type Output = Instant<'a, R>;
411
412    #[inline]
413    fn sub(self, span: Duration<R>) -> Self {
414        Instant(self.0.wrapping_sub(span.0), PhantomData)
415    }
416}
417
418/// A span of ticks at rate `R`.
419///
420/// The count wraps after 2^32 ticks, which is twelve days at 4096 Hz and months
421/// below that. Nothing here allows for that: a span measured across the wrap
422/// comes back wrong rather than saturated, so a machine left running that long
423/// after [`Timer::start`] reads the wrong time.
424pub struct Duration<R: Rate>(u32, PhantomData<R>);
425
426impl<R: Rate> Clone for Duration<R> {
427    fn clone(&self) -> Self {
428        *self
429    }
430}
431impl<R: Rate> Copy for Duration<R> {}
432impl<R: Rate> PartialEq for Duration<R> {
433    fn eq(&self, other: &Self) -> bool {
434        self.0 == other.0
435    }
436}
437impl<R: Rate> Eq for Duration<R> {}
438impl<R: Rate> PartialOrd for Duration<R> {
439    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
440        Some(self.cmp(other))
441    }
442}
443impl<R: Rate> Ord for Duration<R> {
444    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
445        self.0.cmp(&other.0)
446    }
447}
448
449impl<R: Rate> Add for Duration<R> {
450    type Output = Self;
451
452    /// The two spans one after the other, saturating rather than wrapping.
453    #[inline]
454    fn add(self, other: Self) -> Self {
455        Duration(self.0.saturating_add(other.0), PhantomData)
456    }
457}
458
459impl<R: Rate> Sub for Duration<R> {
460    type Output = Self;
461
462    /// What is left of this span after `other`, or nothing if `other` is the
463    /// longer of the two.
464    #[inline]
465    fn sub(self, other: Self) -> Self {
466        Duration(self.0.saturating_sub(other.0), PhantomData)
467    }
468}
469
470impl<R: Rate> Duration<R> {
471    /// A span of `ticks`.
472    pub const fn from_ticks(ticks: u32) -> Self {
473        Duration(ticks, PhantomData)
474    }
475
476    /// The shortest span of at least `ms` milliseconds.
477    ///
478    /// Rounded up to a whole tick, so comparing against this is the answer to
479    /// "has `ms` passed". At 16 Hz a tick is 63 ms, and nothing shorter can be
480    /// told apart.
481    pub const fn from_ms(ms: u32) -> Self {
482        // The shift overruns 32 bits before the divide brings it back,
483        // so the whole and the remainder are taken apart: each is a part of the
484        // answer, so each fits wherever the answer does.
485        let whole = ms / R::MS_NUM;
486        if whole > u32::MAX >> R::MS_SHIFT {
487            return Duration(u32::MAX, PhantomData);
488        }
489        let rest = ((ms % R::MS_NUM) << R::MS_SHIFT) + R::MS_NUM - 1;
490        Duration(
491            (whole << R::MS_SHIFT).saturating_add(rest / R::MS_NUM),
492            PhantomData,
493        )
494    }
495
496    /// The span in ticks.
497    pub const fn ticks(self) -> u32 {
498        self.0
499    }
500
501    /// The span in milliseconds, rounded down.
502    ///
503    /// Do not compare against this. It multiplies, and that is not cheap enough
504    /// to run each time a program asks whether a span has passed.
505    /// [`from_ms`](Self::from_ms) converts at compile time instead, leaving a
506    /// plain comparison on ticks:
507    ///
508    /// ```ignore
509    /// if elapsed >= Duration::from_ms(5000) { .. }   // one comparison
510    /// if elapsed.ms() >= 5000 { .. }                 // a multiply first
511    /// ```
512    ///
513    /// This is for a number to show or to log.
514    pub fn ms(self) -> u32 {
515        // The product overruns 32 bits and is taken in halves. Each half is a
516        // part of the answer, so each fits wherever the answer does,
517        // and the answer is a `u32` of milliseconds: seven weeks.
518        let hi = (self.0 >> 16) * R::MS_NUM;
519        let lo = (self.0 & 0xFFFF) * R::MS_NUM;
520        (hi << (16 - R::MS_SHIFT)).wrapping_add(lo >> R::MS_SHIFT)
521    }
522}