feat(serial): retain disconnected external-clock requests

This commit is contained in:
0xrsydn 2026-10-07 03:58:04 +07:00
commit d329c76dc3
9 changed files with 299 additions and 22 deletions

View file

@ -1,5 +1,5 @@
//! GBA I/O subset: DMA, timers, interrupts, WAITCNT, display, keypad input,
//! Direct Sound, and disconnected serial initialization.
//! Direct Sound, and disconnected serial state with external-clock waiting.
//! Timers share a free-running prescaler phase. Hardware startup/write delays
//! and interrupt delivery delays are not modeled.

View file

@ -1,4 +1,4 @@
//! Disconnected serial initialization state. Active transfers remain diagnostic.
//! Disconnected serial state, including external-clock requests that cannot progress.
use super::replace_byte;
@ -32,7 +32,9 @@ impl Inactive {
/// supplies the complete selection, independent of the previous low byte.
pub(super) fn unsupported(address: u32, value: u8) -> Option<&'static str> {
match address {
SIOCNT if value & 0x80 != 0 => Some("serial transfer start"),
// Clock source and start share the low byte. With no external
// clock edges, an external-clock request only latches start/busy.
SIOCNT if value & 0x81 == 0x81 => Some("internally clocked serial transfer"),
0x0400_0129 if value & 0x20 != 0 => Some("multiplayer/UART serial mode"),
0x0400_0135 if value & 0xc0 == 0xc0 => Some("Joybus serial mode"),
0x0400_0135 if value & 0x81 == 0x81 => Some("GPIO serial interrupt enable"),
@ -82,7 +84,7 @@ impl Inactive {
}
match address & !1 {
SIOCNT => {
self.serial_control = replace_byte(self.serial_control, address, value) & 0x500b
self.serial_control = replace_byte(self.serial_control, address, value) & 0x508b
}
SIODATA8 if address & 1 == 0 => self.serial_send = value,
RCNT => self.rcnt = replace_byte(self.rcnt, address, value) & 0xc1ff,