/* * kbdpoll — измерение ПОТОЛКА «плотного опроса» клавиатуры. * * Вопрос, на который отвечает тест (applications/PoP/roomtest/TASKS.md, * KBD-1): при зажатом Shift часть нажатий расширенных клавиш теряется — * байт не доезжает до порта 0x18, потому что импульс запроса прерывания * пропускается примерно в 44 % случаев и трёхбайтовый FIFO SIO * переполняется. Редкий опрос (несколько раз за кадр) не помог вовсе. * Здесь опрос идёт МАКСИМАЛЬНО плотно — вся программа только этим и * занята, — то есть измеряется ЛУЧШЕЕ, чего опрос в принципе может * достичь. Если и здесь байты теряются, приём не спасёт и в игре, и * искать надо в эмуляции/железе, а не у нас. * * Как мерить (MAME, счётчики брейкпоинтами, машина не останавливается): * 1. Найти в .map адреса `_kbd_raw_poll` и хвоста карты `__kbdraw_down`. * 2. bpset <адрес чтения порта 0x18 внутри kbd_raw_poll>,1,{ b@СЧ1 = b@СЧ1+1 ; g } * bpset <адрес установки make-бита>,E==0x6C && (b@_kbdraw_pending & 1)==0, * { b@СЧ2 = b@СЧ2+1 ; g } * 3. Держать Left Shift, нажать Home ровно N раз * (`:kbd:ms_naturl:P1.7` 0x0002 — Shift, `:kbd:ms_naturl:P2.5` 0x0001 — Home). * Home выбран потому, что он расширенный (тот же «fake shift», что у * стрелок), но в этой программе ничего не делает. * 4. Ожидание: байт ровно 10*N (нажатие E0 F0 12 + E0 6C, отпускание * E0 F0 6C + E0 12), make'ов ровно N. * * Итог теста на экран не выводится СПЕЦИАЛЬНО: любой вывод — это работа, * которая разрежает опрос и портит замер. Числа снимаются из памяти. * * Выход — ESC. Чтобы отличить «программа жива» от «повисла», крутится * бордюр: цвет меняется раз в 4096 опросов (медленное мерцание = работаем). */ #include #include __sfr __at (0xFE) io_border; int main(void) { uint16_t spin = 0; if (kbd_raw_open() != 0) return 1; /* Ничего, кроме опроса. Ни vsync, ни графики, ни ввода-вывода — * иначе замеряли бы не потолок приёма, а свою же нагрузку. */ while (!kbd_raw_down(KBD_ESC)) { kbd_raw_poll(); if (++spin == 0) io_border ^= 4; /* признак жизни: бит 2 (зелёный) */ } kbd_raw_close(); return 0; }