BUG-KBD-5: зажатый Shift снимался автоповтором стрелки
Симптом: Shift работал в одиночку и НЕ работал вместе со стрелками — прыжок с зацепом не выходил (BUG-GRAB-1), а осторожный шаг срывался в бег. Декодеры делали из «fake shift» два вывода, и второй был неверен: обёртка E0 F0 12 / E0 12 есть -> Shift зажат -> взвести бит — верно; расширенный make БЕЗ обёртки -> Shift отпущен -> снять бит — НЕТ. Замер потока байт (MAME, breakpoint на выходе из in a,($18)): клавиатура pc_kbd ms_naturl обёртку не шлёт вовсе — при зажатом Shift поток на ↑ ровно `E0 75 E0 75 …`, ни одного F0/12. А typematic-повторы идут непрерывно, пока стрелка зажата, значит каждый повтор снимал реально зажатый Shift. Короткий тап это маскировал: после отпускания стрелки Shift снова становился последней клавишей, и его собственный автоповтор `12` взводил бит обратно за ~30 мс. Фикс: обратный вывод убран, расширенная клавиша о Shift не судит. Состояние Shift ведут его собственные make/break 12 / F0 12 — они приходят всегда. Прямой вывод оставлен (дёшев и верен там, где обёртка есть). Ушла ставшая ненужной _kbdraw_fakesh; трамплин короче на 36 Б (0x150→0x12C), что важно — его клавиатурный блок упирается в диапазон jr. Плата: потерянный при overrun break Shift снять нечем, модификатор может залипнуть до перенажатия (BUG-KBD-3). Размен решён как и раньше в kbd_raw_sync: лучше залипание, чем отвал — сорванный посреди игры Shift в PoP стоит жизни. Проверено в MAME чтением _kbdraw_down: Shift+↑+→ зажаты 5 с (автоповтор идёт) -> LSh остаётся 04; отпускание Shift -> 00. Зацеп в игре подтверждён пользователем. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+12
-27
@@ -82,10 +82,10 @@ void _irq_tramp(void) __naked
|
||||
jr tr_kbd_hub
|
||||
tr_kbd_nE0:
|
||||
|
||||
;; --- «fake shift»: расширенные коды 12/59 — не клавиши, а обёртка,
|
||||
;; которой клавиатура сопровождает КАЖДЫЙ расширенный код, пока
|
||||
;; реально зажат Shift (см. _kbdraw.h). Отсюда состояние Shift
|
||||
;; определяется в обе стороны и не зависит от целости потока. ---
|
||||
;; --- «fake shift»: расширенные коды 12/59 — не клавиши, а служебная
|
||||
;; обёртка, которой НЕКОТОРЫЕ клавиатуры сопровождают расширенный код
|
||||
;; при зажатом Shift (см. _kbdraw.h). Используем её ТОЛЬКО как
|
||||
;; подтверждение «Shift зажат»; обратный вывод запрещён. ---
|
||||
ld e, a ; E = код
|
||||
ld a, (__kbdraw_pending)
|
||||
bit 1, a ; EXT?
|
||||
@@ -95,22 +95,9 @@ void _irq_tramp(void) __naked
|
||||
jr Z, tr_kbd_fake
|
||||
cp #0x59
|
||||
jr Z, tr_kbd_fake
|
||||
;; расширенная КЛАВИША: make без обёртки => Shift не зажат
|
||||
ld a, (__kbdraw_pending)
|
||||
bit 0, a ; break — состояние Shift не судим
|
||||
jr NZ, tr_kbd_fkclr
|
||||
ld a, (__kbdraw_fakesh)
|
||||
or a, a
|
||||
jr NZ, tr_kbd_fkclr ; обёртка была => Shift зажат, не трогаем
|
||||
ld hl, #(__kbdraw_down + _KBDRAW_LSH_BYTE)
|
||||
res _KBDRAW_LSH_BIT, (hl)
|
||||
ld hl, #(__kbdraw_down + _KBDRAW_RSH_BYTE)
|
||||
res _KBDRAW_RSH_BIT, (hl)
|
||||
tr_kbd_fkclr:
|
||||
xor a, a
|
||||
ld (__kbdraw_fakesh), a
|
||||
ld a, e
|
||||
jr tr_kbd_code ; дальше как обычная клавиша
|
||||
;; расширенная КЛАВИША — обычный путь. О состоянии Shift по ней НЕ
|
||||
;; судим (почему — см. tr_kbd_fake). A всё ещё = код.
|
||||
jr tr_kbd_code
|
||||
|
||||
tr_kbd_hub:
|
||||
;; Ретрансляторы: клавиатурный блок длиннее 127 байт, а jp внутри
|
||||
@@ -124,13 +111,11 @@ void _irq_tramp(void) __naked
|
||||
jr tr_kbd_dss
|
||||
|
||||
tr_kbd_fake:
|
||||
;; E0 F0 12 / E0 12 — реальный Shift ЗАЖАТ. Бит взводит ОБЩИЙ
|
||||
;; писатель ниже: достаточно обнулить префиксы — тогда он положит
|
||||
;; код в PLAIN-половину карты (без +32) и именно взведёт бит (не
|
||||
;; break). В расширенную половину не пишем: это не клавиша.
|
||||
ld a, (__kbdraw_pending)
|
||||
and #1 ; 1 = break-форма (идёт ПЕРЕД обёрнутым make)
|
||||
ld (__kbdraw_fakesh), a
|
||||
;; E0 F0 12 / E0 12 — реальный Shift ЗАЖАТ (обе формы обёртки шлются
|
||||
;; только пока он зажат). Бит взводит ОБЩИЙ писатель ниже: достаточно
|
||||
;; обнулить префиксы — тогда он положит код в PLAIN-половину карты
|
||||
;; (без +32) и именно ВЗВЕДЁТ бит, а не снимет, даже у break-формы.
|
||||
;; В расширенную половину не пишем: это не клавиша.
|
||||
xor a, a
|
||||
ld (__kbdraw_pending), a
|
||||
ld a, e
|
||||
|
||||
Reference in New Issue
Block a user