/* * kbd_raw_sync.c — восстановление held-состояния после Rx-overrun SIO. * * Аппаратный приёмный FIFO SIO — 3 байта. Если прерывания запрещены * достаточно долго (DI-окна графики/кадрового IRQ), а в этот момент * приходит пачка скан-кодов (напр. одновременное отпускание shift+стрелка * = F0 12 E0 F0 74, 5 байт) — FIFO переполняется, байт(ы) теряются * аппаратно. Потерянный break → клавиша «залипает» в _kbdraw_down. * * Трамплин ловит overrun (RR1 бит5) и взводит _kbdraw_overrun. Приложение * зовёт kbd_raw_sync() раз в кадр: при взведённом флаге сбрасывает ВСЁ * held-состояние (какой именно break потерян — неизвестно). Реально * зажатые клавиши «перечитаются» их make-повтором/следующим нажатием. * * ВНИМАНИЕ: путь overrun-recovery НЕ проверен детерминированно (баг * интермиттентный, зависит от тайминга DI) — требует проверки на железе. */ #include #include "_kbdraw.h" void kbd_raw_sync(void) { if (_kbdraw_overrun) { _kbdraw_overrun = 0; memset(_kbdraw_down, 0, sizeof(_kbdraw_down)); } }