Add a dependency-free keypad state machine in gba-core, map KEYCNT, latch IF bit 12, and wake HALT through the existing interrupt gates. Sample complete CPU/DMA control writes once so transient byte values cannot create false requests. Document the mGBA-style polling policy and its unverified hardware retrigger limits. Cover every button-state/selection pair, register masks, repeated requests, byte/word writes, failed-store isolation, DMA priority, ARM/Thumb IRQ return, BIOS IntrWait, and retained BIOS reset state. Follow the restructured workspace and modular documentation. Validated on Darwin arm64: workspace and core/demo tests pass in debug and release, with Clippy, rustdoc, ten native window smoke tests, and terminal demos passing.
45 lines
948 B
Rust
45 lines
948 B
Rust
//! Platform-independent GBA button state. Bits are pressed-high here;
|
|
//! the KEYINPUT register exposes their active-low hardware representation.
|
|
|
|
mod keypad;
|
|
pub(crate) use keypad::Keypad;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
#[repr(u16)]
|
|
pub enum Button {
|
|
A = 1 << 0,
|
|
B = 1 << 1,
|
|
Select = 1 << 2,
|
|
Start = 1 << 3,
|
|
Right = 1 << 4,
|
|
Left = 1 << 5,
|
|
Up = 1 << 6,
|
|
Down = 1 << 7,
|
|
R = 1 << 8,
|
|
L = 1 << 9,
|
|
}
|
|
|
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
|
pub struct Buttons(u16);
|
|
|
|
impl Buttons {
|
|
pub fn from_bits(bits: u16) -> Self {
|
|
Self(bits & 0x03ff)
|
|
}
|
|
|
|
pub fn bits(self) -> u16 {
|
|
self.0
|
|
}
|
|
|
|
pub fn with(self, button: Button, pressed: bool) -> Self {
|
|
Self(if pressed {
|
|
self.0 | button as u16
|
|
} else {
|
|
self.0 & !(button as u16)
|
|
})
|
|
}
|
|
|
|
pub(crate) fn keyinput(self) -> u16 {
|
|
!self.0 & 0x03ff
|
|
}
|
|
}
|