/* * kbd_raw.h — эксклюзивный raw-канал клавиатуры: держит битовую карту * «клавиша N зажата ПРЯМО СЕЙЧАС», обновляемую напрямую из * прерывания (декодирует PS/2 Scan Code Set 2 — make/break, тот же * протокол, что и в docs/samples/sprinterKeybLib.asm). * * Прецедент и мотивация — applications/PoP/docs/PORT_PLAN.md §2: * ESTEX kbhit/getch/getkey/CTRLKEY — событийные (нажатие, без * release), обычные клавиши (не модификаторы) вообще не имеют * live-state в ESTEX; трамплин кадрового прерывания * (libc/irq/_irq_tramp.c) в штатном режиме отдаёт клавиатурные байты * ПРЯМО в DSS, не читая порт данных — байт из аппаратного приёмного * регистра можно прочитать только ОДИН раз, поэтому «подсмотреть, не * мешая DSS» невозможно технически. * * ЖИЗНЕННЫЙ ЦИКЛ И ГЛАВНОЕ СЛЕДСТВИЕ: пока kbd_raw_open() активен, ВЕСЬ * поток клавиатурных байт достаётся ЭТОМУ модулю — DSS их не видит. * kbhit/getch/getkey/CTRLKEY (в т.ч. kbd_mod_state) НЕ получают новых * событий, пока raw-канал открыт. Приложение обязано проверять «выход» * (например ESC — KBD_ESC) через kbd_raw_down() само. Перед экранами, * которым нужен обычный ESTEX-ввод (диалоги/меню на консольном I/O), * закрыть канал kbd_raw_close(). Паттерн один в один как у * cbl_open()/cbl_close() () — тот же приватный IM2-хук, не * чейнящийся к DSS. * * КОДЫ КЛАВИШ: значения ниже — общеизвестный стандарт AT/PS-2 Scan * Code Set 2 (не специфика Sprinter). TODO до использования в PoC: * подтвердить в MAME, что реальный поток байт с SIO-A клавиатуры * Sprinter именно этот набор кодов (см. defer_unexplained_quirks). */ #ifndef KBD_RAW_H #define KBD_RAW_H #include /* Включить raw-канал: 0 / -1+errno (EBUSY — уже открыт; прочие коды — * см. errno.h, как у irq_install/cbl_open — общий IM2-механизм). */ int kbd_raw_open(void); /* Выключить raw-канал, вернуть клавиатуру DSS. Идемпотентно; висит * на atexit (страховка, как у cbl_close). */ void kbd_raw_close(void); /* Зажата ли клавиша code ПРЯМО СЕЙЧАС (0/1). code вне 0..511 — 0 * (защитно). Для расширенных клавиш (стрелки и т.п., префикс 0xE0 * на проводе) прибавить KBD_EXT к базовому коду. */ uint8_t kbd_raw_down(uint16_t code); /* Восстановление после Rx-overrun SIO: звать РАЗ В КАДР (до чтения * kbd_raw_down). Аппаратный FIFO SIO 3 байта; при длинных DI-окнах пачка * скан-кодов (напр. shift+стрелка release) переполняет его → потерян break * → залипшая клавиша. Трамплин ловит overrun и взводит флаг; kbd_raw_sync * по флагу сбрасывает ВСЁ held-состояние (реально зажатые перечитаются). */ void kbd_raw_sync(void); #define KBD_EXT 0x0100 /* база кода была расширенной (0xE0-префикс) */ /* Позиционные коды PS/2 Set 2 — то, что реально нужно платформеру. * TODO: подтвердить в MAME перед PoC (см. предупреждение выше). */ #define KBD_UP (KBD_EXT | 0x75) #define KBD_DOWN (KBD_EXT | 0x72) #define KBD_LEFT (KBD_EXT | 0x6B) #define KBD_RIGHT (KBD_EXT | 0x74) #define KBD_SPACE 0x29 #define KBD_ENTER 0x5A #define KBD_ESC 0x76 #define KBD_LSHIFT 0x12 #define KBD_RSHIFT 0x59 #endif