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}