libc/kbd: kbd_raw_poll + замер потери нажатий при зажатом Shift (KBD-1)
Симптом: при удерживаемом Shift часть нажатий стрелок не отрабатывает
(~15 % по наблюдению пользователя), без Shift потерь нет.
Переведено в числа: нажимается Home — тоже расширенная клавиша (тот же
E0-префикс и тот же «fake shift»), но игрой игнорируется, поэтому рельеф
комнаты на результат не влияет. Счётчики — брейкпоинты MAME с действием
{ b@ADDR = b@ADDR+1 ; g } на входе клавиатурной ветки трамплина, на чтении
порта 0x18 и на установке make-бита.
Что измерено (10 нажатий Shift+Home, дошло make):
игра идёт, опрос ВКЛ 9/10 игра идёт, опрос ВЫКЛ 9/10
игра ЗАМОРОЖЕНА (блитов нет вообще, длинных DI нет) 8/10
Обе исходные гипотезы отпали:
- длина наших DI-окон ни при чём (в замороженном кадре потерь больше);
- снятие di в accel-ядрах libbgi УРОНИЛО машину — режим «акселератор при
EI» из docs/new/06-accel.md §6.6 в этой прошивке недоступен.
Байт теряется НИЖЕ нашего кода: на 49 прочитанных байт пришлось только 28
входов в клавиатурную ветку, то есть ~44 % импульсов запроса прерывания не
обслуживается и трёхбайтовый FIFO SIO переполняется.
Потолок приёма измерен отдельной программой tests/kbdpoll (ничего, кроме
kbd_raw_poll в цикле): 25 нажатий -> 25 make, 250 байт из 250, ноль потерь.
Значит опрос лечит полностью, вопрос только в плотности: нужно раз в
~0.5 мс, а шесть вызовов за 60-мс кадр давали раз в 10 мс.
Поэтому вызовы из roomtest.c УБРАНЫ (они стояли там, где прерывания и так
разрешены, и дублировали трамплин — 9/10 с ними и без). Сама функция
kbd_raw_poll оставлена в libc: она корректна и нужна как основа плотного
опроса. В заголовке и в libc-reference — честная оговорка, чтобы её не
ставили в игровой цикл «на всякий случай» без замера.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,23 @@ const uint8_t n_banks = 4;
|
||||
/* Режим читов (pop_cheat.h): на время разработки включаем в main. */
|
||||
uint8_t pop_cheats;
|
||||
|
||||
/* ПОТЕРЯ НАЖАТИЙ ПРИ ЗАЖАТОМ Shift — НЕ ЧИНИТСЯ ИЗ ЭТОГО ЦИКЛА.
|
||||
*
|
||||
* Здесь стояли шесть вызовов kbd_raw_poll() (вычерпать FIFO клавиатуры
|
||||
* после каждой тяжёлой фазы кадра). Убраны: замерено, что они не меняют
|
||||
* НИЧЕГО — 9 дошедших make-байт из 10 нажатий и с ними, и без них. Они
|
||||
* стояли ровно там, где прерывания и так разрешены, то есть добавляли то,
|
||||
* что трамплин делает сам.
|
||||
*
|
||||
* Настоящая причина лежит НИЖЕ нашего кода: при зажатом Shift PS/2 шлёт на
|
||||
* расширенную клавишу вдвое больше байт («fake shift»), а импульс запроса
|
||||
* прерывания пропускается примерно в 44 % случаев — байты копятся в
|
||||
* трёхбайтовом FIFO SIO и один из полусотни теряется ДО чтения порта.
|
||||
* Длина наших DI-окон ни при чём: в замороженном кадре, где блитов нет
|
||||
* вообще, потерь БОЛЬШЕ, а не меньше.
|
||||
*
|
||||
* Полный протокол замеров и куда копать дальше — TASKS.md, KBD-1. */
|
||||
|
||||
/* seq_2_stand (types.h seqids) — Kid стоит, ждёт ввода. */
|
||||
#define SEQ_STAND 2
|
||||
#define ROOM_1 1
|
||||
|
||||
Reference in New Issue
Block a user