Skip to main content

gb/mmio/
interrupt.rs

1//! Interrupt flags (`IF`, `IE`).
2
3use bitflags::bitflags;
4use voladdress::{Safe, Unsafe, VolAddress};
5
6bitflags! {
7    /// Interrupt sources. `IE` and `IF` share this type (same bit layout).
8    ///
9    /// | Bit | Flag | Meaning |
10    /// |-----|------|---------|
11    /// | 4 | `JOYPAD`   | A selected input line went low. |
12    /// | 3 | `SERIAL`   | Serial transfer completed. |
13    /// | 2 | `TIMER`    | TIMA overflowed. |
14    /// | 1 | `LCD_STAT` | A configured PPU mode or LYC=LY condition. |
15    /// | 0 | `VBLANK`   | The PPU entered VBlank. |
16    #[derive(Clone, Copy, PartialEq, Eq, Debug)]
17    pub struct Interrupts: u8 {
18        /// VBlank: the PPU entered VBlank.
19        const VBLANK = 1 << 0;
20        /// LCD STAT: a configured PPU mode or LYC=LY condition.
21        const LCD_STAT = 1 << 1;
22        /// Timer: TIMA overflowed.
23        const TIMER = 1 << 2;
24        /// Serial transfer completed.
25        const SERIAL = 1 << 3;
26        /// Joypad: a selected input line went low.
27        const JOYPAD = 1 << 4;
28    }
29}
30
31/// Interrupt flag: pending interrupt requests.
32///
33/// # Safety
34///
35/// Writing can request an interrupt; with no handler installed the CPU runs
36/// whatever sits at the vector.
37pub const IF: VolAddress<Interrupts, Safe, Unsafe> = unsafe { VolAddress::new(0xFF0F) };
38/// Interrupt enable: which interrupts may fire.
39///
40/// # Safety
41///
42/// Enabling an interrupt with no handler installed runs whatever sits at its
43/// vector.
44pub const IE: VolAddress<Interrupts, Safe, Unsafe> = unsafe { VolAddress::new(0xFFFF) };
45
46const _: () = {
47    assert!(Interrupts::VBLANK.bits() == 0b0000_0001);
48    assert!(Interrupts::JOYPAD.bits() == 0b0001_0000);
49};