libc/kbd: held-карта клавиш в биты (512 -> 64 Б); эталон размеров принят
Разгрузка W1/W2 под будущий ИИ стражей: _kbdraw_down был БАЙТОМ на
скан-код (512 Б в _DATA при 32-килобайтной раскладке). Теперь бит на
код: код>>3 = байт, код&7 = бит, расширенные (префикс 0xE0) — смещение
+32 байта вместо +256.
Трамплин прерывания строит маску СДВИГОМ, а не таблицей: таблица
потребовала бы `ld hl,#метка` внутри трамплина, а он копируется в W2
побайтно и обязан быть без абсолютных само-ссылок (см. его шапку).
Маска строится в BC, поэтому в клавиатурной ветке добавлен push/pop bc.
Трамплин вырос 244 -> 267 Б, буфер копии поднят 320 -> 336 (запас 69 Б).
Проверено в MAME на roomtest, все три класса клавиш:
- обычные: '=' (обход комнат) и 'K' (чит-убийство стража — читал
guardhp_curr/delta: 3/0 -> 0/-3);
- расширенные (E0): стрелка вправо — Kid добежал до края комнаты;
- модификаторы: удержание Shift ставит бит 2 байта 2 карты
(скан-код 0x12), отпускание снимает.
Скорость: кадр 334 716 -> 338 508 тактов (+1.1 %) на битовой арифметике
в kbd_raw_down (~15 вызовов за кадр); при бюджете 430 000 это 0.79
периода вместо 0.78 — регрессии нет.
Итог по roomtest: данные 4422 -> 4022 Б, куча W2 996 -> 1294 Б.
Эталон размеров принят заново (make size-baseline): _CODE десяти
программ вырос на 14-23 Б — это код битовой арифметики в трамплине и
kbd_raw_down, обмен на -448 Б данных, которые size_check не считает.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+17
-10
@@ -1,5 +1,5 @@
|
|||||||
# Эталон размеров _CODE (байт); обновление: python3 toolchain/size_check.py --update
|
# Эталон размеров _CODE (байт); обновление: python3 toolchain/size_check.py --update
|
||||||
accfill 3772
|
accfill 3786
|
||||||
argv 3431
|
argv 3431
|
||||||
assrtest 3847
|
assrtest 3847
|
||||||
atlas 9193
|
atlas 9193
|
||||||
@@ -9,15 +9,15 @@ banked 1056
|
|||||||
bankedbg 1067
|
bankedbg 1067
|
||||||
banklocl 4683
|
banklocl 4683
|
||||||
banktest 3767
|
banktest 3767
|
||||||
bgi_img 7057
|
bgi_img 7200
|
||||||
bgitest 3737
|
bgitest 3751
|
||||||
bios_text 4461
|
bios_text 4461
|
||||||
blitperf 5860
|
blitperf 5860
|
||||||
blitw 4939
|
blitw 4939
|
||||||
cat 913
|
cat 913
|
||||||
cblstream 6217
|
cblstream 6431
|
||||||
cbltest 6366
|
cbltest 6580
|
||||||
cblwav 6434
|
cblwav 6648
|
||||||
conio 4605
|
conio 4605
|
||||||
conio2 3929
|
conio2 3929
|
||||||
dec_test 860
|
dec_test 860
|
||||||
@@ -27,12 +27,12 @@ fdmax 6023
|
|||||||
filetest 10547
|
filetest 10547
|
||||||
fpsdiv 4870
|
fpsdiv 4870
|
||||||
gets 509
|
gets 509
|
||||||
gfx_dbuf 5032
|
gfx_dbuf 5112
|
||||||
gfx_demo 4103
|
gfx_demo 4117
|
||||||
gfxbanks 6044
|
gfxbanks 6044
|
||||||
hello 4167
|
hello 4167
|
||||||
hello2 4244
|
hello2 4244
|
||||||
irqtest 6527
|
irqtest 6647
|
||||||
kbdraw 4911
|
kbdraw 4911
|
||||||
ls 4835
|
ls 4835
|
||||||
malloc 4461
|
malloc 4461
|
||||||
@@ -45,7 +45,8 @@ palfile 5406
|
|||||||
ptime 5744
|
ptime 5744
|
||||||
rpgprof 12082
|
rpgprof 12082
|
||||||
rpgwalk 10309
|
rpgwalk 10309
|
||||||
rt_test 4892
|
rt_test 5154
|
||||||
|
scroll 2974
|
||||||
seek 4188
|
seek 4188
|
||||||
simple 955
|
simple 955
|
||||||
solidt 11531
|
solidt 11531
|
||||||
@@ -60,4 +61,10 @@ strtest 1340
|
|||||||
text_palette 5024
|
text_palette 5024
|
||||||
timedir 5454
|
timedir 5454
|
||||||
w0page 8831
|
w0page 8831
|
||||||
|
w3bankgfx 5240
|
||||||
|
w3bgfx 5246
|
||||||
|
w3big 3673
|
||||||
|
w3huge 3700
|
||||||
|
w3probe 3556
|
||||||
|
w3tiny 3471
|
||||||
winrest 4459
|
winrest 4459
|
||||||
|
|||||||
|
+4
-4
@@ -30,10 +30,10 @@
|
|||||||
#define _IRQ_VEC_BUF_SIZE (256 + 257)
|
#define _IRQ_VEC_BUF_SIZE (256 + 257)
|
||||||
|
|
||||||
/* Буфер под W2-копию кадрового трамплина (small/huge — _irq_tramp в
|
/* Буфер под W2-копию кадрового трамплина (small/huge — _irq_tramp в
|
||||||
* W1). С запасом над реальным размером трамплина (244 Б после
|
* W1). С запасом над реальным размером трамплина (267 Б после
|
||||||
* FIFO-drain + overrun-recovery в raw-клавиатурной ветке, 2026-07-18 —
|
* упаковки held-карты клавиатуры в биты, 2026-07-30 — проверять
|
||||||
* проверять __irq_tramp_end при правках, запас держать ≥ 60 Б). */
|
* __irq_tramp_end при правках, запас держать >= 60 Б). */
|
||||||
#define _IRQ_TRAMP_BUF_SIZE 320
|
#define _IRQ_TRAMP_BUF_SIZE 336
|
||||||
|
|
||||||
extern uint8_t _irq_vec_buf[_IRQ_VEC_BUF_SIZE];
|
extern uint8_t _irq_vec_buf[_IRQ_VEC_BUF_SIZE];
|
||||||
|
|
||||||
|
|||||||
+31
-5
@@ -10,7 +10,8 @@
|
|||||||
* (порт данных 0x18 читается один раз, деструктивно — либо мы,
|
* (порт данных 0x18 читается один раз, деструктивно — либо мы,
|
||||||
* либо DSS, не оба), декодируется make/break (PS/2 Scan Code
|
* либо DSS, не оба), декодируется make/break (PS/2 Scan Code
|
||||||
* Set 2: 0xF0 — префикс отпускания, 0xE0 — префикс расширенной
|
* Set 2: 0xF0 — префикс отпускания, 0xE0 — префикс расширенной
|
||||||
* клавиши) в битовую карту `_kbdraw_down[]`, и к DSS НЕ идём
|
* клавиши) в битовую карту `_kbdraw_down[]` (бит на код, 64 Б),
|
||||||
|
* и к DSS НЕ идём
|
||||||
* (private RETI — тот же паттерн, что и у CBL ниже). Пока raw
|
* (private RETI — тот же паттерн, что и у CBL ниже). Пока raw
|
||||||
* открыт, DSS клавиатуру не видит вообще (см. <kbd_raw.h>).
|
* открыт, DSS клавиатуру не видит вообще (см. <kbd_raw.h>).
|
||||||
* - CBL (бит 7 порта 0xFE) — только при зарегистрированном хуке
|
* - CBL (бит 7 порта 0xFE) — только при зарегистрированном хуке
|
||||||
@@ -61,6 +62,7 @@ void _irq_tramp(void) __naked
|
|||||||
;; break-кода = клавиша «залипает» навсегда (найдено 2026-07-16).
|
;; break-кода = клавиша «залипает» навсегда (найдено 2026-07-16).
|
||||||
push hl
|
push hl
|
||||||
push de
|
push de
|
||||||
|
push bc ; маска бита строится в BC (см. ниже)
|
||||||
tr_kbd_drain:
|
tr_kbd_drain:
|
||||||
in a, (#_IRQ_SIO_DATA) ; читаем — тем самым дренируем байт
|
in a, (#_IRQ_SIO_DATA) ; читаем — тем самым дренируем байт
|
||||||
cp #0xF0
|
cp #0xF0
|
||||||
@@ -68,7 +70,27 @@ void _irq_tramp(void) __naked
|
|||||||
cp #0xE0
|
cp #0xE0
|
||||||
jr Z, tr_kbd_setext
|
jr Z, tr_kbd_setext
|
||||||
|
|
||||||
;; --- обычный байт кода: индекс в _kbdraw_down[код(+256 EXT)] ---
|
;; --- обычный байт кода: БИТ code&7 в байте _kbdraw_down[code>>3]
|
||||||
|
;; (карта упакована по битам: 64 Б вместо 512, см. _kbdraw.h).
|
||||||
|
;; Маску строим сдвигом, а НЕ таблицей: таблица потребовала бы
|
||||||
|
;; `ld hl,#метка` внутри трамплина, а он копируется в W2 побайтно
|
||||||
|
;; и обязан быть без абсолютных само-ссылок (см. шапку). ---
|
||||||
|
ld e, a ; E = код
|
||||||
|
and #7
|
||||||
|
ld b, a
|
||||||
|
inc b ; B = (код&7)+1 для djnz
|
||||||
|
ld a, #1
|
||||||
|
jr tr_kbd_mskdec
|
||||||
|
tr_kbd_mskloop:
|
||||||
|
add a, a
|
||||||
|
tr_kbd_mskdec:
|
||||||
|
djnz tr_kbd_mskloop ; A = 1 << (код&7)
|
||||||
|
ld c, a ; C = маска бита
|
||||||
|
ld a, e
|
||||||
|
rrca
|
||||||
|
rrca
|
||||||
|
rrca
|
||||||
|
and #0x1F ; A = код>>3 (код <= 255)
|
||||||
ld hl, #__kbdraw_down
|
ld hl, #__kbdraw_down
|
||||||
ld d, #0
|
ld d, #0
|
||||||
ld e, a
|
ld e, a
|
||||||
@@ -76,16 +98,19 @@ void _irq_tramp(void) __naked
|
|||||||
ld a, (__kbdraw_pending)
|
ld a, (__kbdraw_pending)
|
||||||
bit 1, a ; _KBDRAW_PEND_EXT?
|
bit 1, a ; _KBDRAW_PEND_EXT?
|
||||||
jr Z, tr_kbd_noext
|
jr Z, tr_kbd_noext
|
||||||
ld de, #256
|
ld de, #32 ; +256 кодов = +32 байта карты
|
||||||
add hl, de
|
add hl, de
|
||||||
tr_kbd_noext:
|
tr_kbd_noext:
|
||||||
ld a, (__kbdraw_pending)
|
ld a, (__kbdraw_pending)
|
||||||
bit 0, a ; _KBDRAW_PEND_BREAK?
|
bit 0, a ; _KBDRAW_PEND_BREAK?
|
||||||
jr Z, tr_kbd_mkdown
|
jr Z, tr_kbd_mkdown
|
||||||
xor a, a ; break → снять (0)
|
ld a, c
|
||||||
|
cpl ; break → сбросить бит
|
||||||
|
and a, (hl)
|
||||||
jr tr_kbd_wr
|
jr tr_kbd_wr
|
||||||
tr_kbd_mkdown:
|
tr_kbd_mkdown:
|
||||||
ld a, #1 ; make → взвести (1)
|
ld a, c ; make → взвести бит
|
||||||
|
or a, (hl)
|
||||||
tr_kbd_wr:
|
tr_kbd_wr:
|
||||||
ld (hl), a
|
ld (hl), a
|
||||||
xor a, a
|
xor a, a
|
||||||
@@ -120,6 +145,7 @@ void _irq_tramp(void) __naked
|
|||||||
ld a, #1
|
ld a, #1
|
||||||
ld (__kbdraw_overrun), a
|
ld (__kbdraw_overrun), a
|
||||||
tr_kbd_noovr:
|
tr_kbd_noovr:
|
||||||
|
pop bc
|
||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
pop af
|
pop af
|
||||||
|
|||||||
+7
-2
@@ -23,7 +23,12 @@ extern uint8_t _kbdraw_pending; /* FSM декодера make/break, см. в
|
|||||||
extern uint8_t _kbdraw_overrun; /* 1 = ISR поймал Rx-overrun SIO (потерян
|
extern uint8_t _kbdraw_overrun; /* 1 = ISR поймал Rx-overrun SIO (потерян
|
||||||
* байт → возможно потерян break); снимает
|
* байт → возможно потерян break); снимает
|
||||||
* kbd_raw_sync (чистит _kbdraw_down) */
|
* kbd_raw_sync (чистит _kbdraw_down) */
|
||||||
extern uint8_t _kbdraw_down[512]; /* 0/1 по коду; +256 для расширенных
|
/* Held-состояние: БИТ на скан-код, код>>3 = байт, код&7 = номер бита;
|
||||||
* (префикс 0xE0) — см. kbd_raw_down */
|
* коды 0..255 обычные, 256..511 — расширенные (префикс 0xE0), т.е.
|
||||||
|
* смещение +32 байта. Упаковка вместо байта на код: 64 Б вместо 512 —
|
||||||
|
* заметная доля _DATA на 32-килобайтной раскладке (замер PoP roomtest
|
||||||
|
* 2026-07-30). Ведёт трамплин прерывания (libc/irq/_irq_tramp.c),
|
||||||
|
* читает kbd_raw_down(). */
|
||||||
|
extern uint8_t _kbdraw_down[64];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ uint8_t _kbdraw_active;
|
|||||||
uint8_t _kbdraw_pending;
|
uint8_t _kbdraw_pending;
|
||||||
uint8_t _kbdraw_overrun; /* ISR взвёл при Rx-overrun SIO (потерян
|
uint8_t _kbdraw_overrun; /* ISR взвёл при Rx-overrun SIO (потерян
|
||||||
* break) — kbd_raw_sync снимет залипшее */
|
* break) — kbd_raw_sync снимет залипшее */
|
||||||
uint8_t _kbdraw_down[512];
|
uint8_t _kbdraw_down[64]; /* БИТ на скан-код (см. _kbdraw.h) */
|
||||||
|
|||||||
@@ -10,5 +10,5 @@
|
|||||||
uint8_t kbd_raw_down(uint16_t code)
|
uint8_t kbd_raw_down(uint16_t code)
|
||||||
{
|
{
|
||||||
if (code >= 512) return 0;
|
if (code >= 512) return 0;
|
||||||
return _kbdraw_down[code];
|
return (uint8_t)((_kbdraw_down[code >> 3] >> (code & 7)) & 1);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-3
@@ -36,7 +36,15 @@ void kbd_raw_sync(void)
|
|||||||
if (!_kbdraw_overrun) return;
|
if (!_kbdraw_overrun) return;
|
||||||
_kbdraw_overrun = 0;
|
_kbdraw_overrun = 0;
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) save[i] = _kbdraw_down[_kbd_mod_codes[i]];
|
/* Карта упакована по битам (см. _kbdraw.h): сохраняем/возвращаем
|
||||||
memset(_kbdraw_down, 0, sizeof(_kbdraw_down));
|
* именно БИТ модификатора, а не байт. */
|
||||||
for (i = 0; i < 6; i++) _kbdraw_down[_kbd_mod_codes[i]] = save[i];
|
for (i = 0; i < 6; i++) {
|
||||||
|
uint16_t c = _kbd_mod_codes[i];
|
||||||
|
save[i] = (uint8_t)((_kbdraw_down[c >> 3] >> (c & 7)) & 1);
|
||||||
|
}
|
||||||
|
memset(_kbdraw_down, 0, sizeof(_kbdraw_down));
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
uint16_t c = _kbd_mod_codes[i];
|
||||||
|
if (save[i]) _kbdraw_down[c >> 3] |= (uint8_t)(1 << (c & 7));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user