BIOS: implement get_key_timeout with INT 16h/01h polling + INT 15h/86h delay

Fixes autoboot countdown blocking forever because the default trait impl
calls blocking get_key(). Uses non-destructive key check (INT 16h AH=01h)
with EDX sentinel to detect key availability without EFLAGS access, and
INT 15h AH=86h for 10ms polling intervals.
This commit is contained in:
Red Bear OS
2026-07-12 05:02:08 +03:00
parent 2f79630b0e
commit c78c3a63c0
+48
View File
@@ -219,6 +219,54 @@ impl Os for OsBios {
}
}
fn get_key_timeout(&self, milliseconds: usize) -> OsKey {
let mut remaining = milliseconds;
loop {
let mut check = ThunkData::new();
check.eax = 0x0100;
check.edx = 0xFFFF_FFFF;
unsafe {
check.with(self.thunk16);
}
if check.edx != 0xFFFF_FFFF || check.eax != 0x0100 {
let mut data = ThunkData::new();
unsafe {
data.with(self.thunk16);
}
return match (data.eax >> 8) as u8 {
0x4B => OsKey::Left,
0x4D => OsKey::Right,
0x48 => OsKey::Up,
0x50 => OsKey::Down,
0x0E => OsKey::Backspace,
0x53 => OsKey::Delete,
0x1C => OsKey::Enter,
_ => match data.eax as u8 {
0 => OsKey::Other,
b => OsKey::Char(b as char),
},
};
}
if remaining == 0 {
return OsKey::Timeout;
}
let step = 10.min(remaining);
let mut wait = ThunkData::new();
wait.eax = 0x8600;
wait.ecx = 0;
wait.edx = (step * 1000) as u32;
unsafe {
wait.with(self.thunk15);
}
remaining -= step;
}
}
fn clear_text(&self) {
let mut vga = VGA.lock();
vga.clear();