libc+libbgi: raw-клавиатура (held-state) + column-major блит спрайтов
libc/kbd: kbd_raw_open/close/down — сырой PS/2-канал клавиатуры с held-state (битовая карта _kbdraw_down[512], EXT-клавиши +256). Пока raw открыт, кадровый IRQ-трамплин перехватывает байт SIO у DSS и декодирует make/break (0xF0/0xE0-префиксы) сам. FIFO вычерпывается В ЦИКЛЕ (приёмный буфер SIO 3 байта; пачка break-кодов при одновременном отпускании иначе теряется → залипание клавиши). Буфер W2-трамплина поднят 224→288 Б под выросший обработчик. libc/conio: kbd_mod_state() — live-состояние модификаторов (ESTEX CTRLKEY $33h), Shift/Ctrl/Alt/Lock прямо сейчас, KBD_MOD_* маска. libbgi: gfx_blit_cols(x,y,img,flip) + _bgi_blit_cols_raw — блит column-major спрайта вертикальным accel-проходом, бесплатный горизонтальный флип (sstride<0), клип по экрану. Для персонажей. libbgi/atlas_load: восстанавливать W3 ДО записи a->count (atlas_t в --bank памяти резолвится через W3; count оставался мусором). tests/kbdraw — тест raw-клавиатуры; size-baseline +kbdraw. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* _bgi_blit_cols_raw — accel block-copy КОЛОНКАМИ (буфер column-major ->
|
||||
* экран). Парный к _bgi_blit_rows_raw, но вертикальный проход: каждая
|
||||
* КОЛОНКА копируется одним accel-burst'ом вниз (Port_Y авто-шагает),
|
||||
* опкод LD A,A (0x7F — «копирование блока для вертикального прохода»,
|
||||
* см. docs/reference/accel_r.txt). dst двигается на +1 (следующий x) на
|
||||
* колонку; Port_Y сбрасывается в y0 перед каждой колонкой (accel шагает
|
||||
* его внутри burst'а); src двигается на sstride на колонку.
|
||||
*
|
||||
* ЗАЧЕМ: бесплатный ГОРИЗОНТАЛЬНЫЙ флип персонажей — вызывающий подаёт
|
||||
* src с конца (src+(w-1)*h) и sstride=-h, тогда правая колонка источника
|
||||
* ложится в левый x экрана (зеркало). Реверс без CPU и без удвоения
|
||||
* памяти. Спрайты персонажей хранятся column-major.
|
||||
*
|
||||
* ВХОД (__sdcccall(1)): src→HL, dst→DE; стек: w 4(ix), h 5(ix),
|
||||
* sstride 6/7(ix), y0 8(ix). w — число КОЛОНОК (1..256, 0=256); h —
|
||||
* высота колонки = размер accel-блока (1..256, 0=256); sstride — шаг
|
||||
* адреса src между колонками (±); y0 — стартовый Port_Y. Callee-pop 5 Б.
|
||||
*
|
||||
* Raw: без клиппинга (вызывающий); W3 замаплен (_bgi_begin/end снаружи);
|
||||
* банк выставлен вызывающим (0x5C прозрачный / 0x50 обычный). src ВНЕ W3.
|
||||
* ОДИН DI на весь блит. Колонки > 256 строк режет вызывающий (h ≤ 256).
|
||||
* Клоббер: AF/BC/DE/HL; IX сохраняется.
|
||||
*/
|
||||
|
||||
#include "../_bgi.h"
|
||||
|
||||
void _bgi_blit_cols_raw(const uint8_t *src, uint8_t *dst,
|
||||
uint8_t w, uint8_t h,
|
||||
int sstride, uint8_t y0) __naked
|
||||
{
|
||||
(void)src; (void)dst; (void)w; (void)h; (void)sstride; (void)y0;
|
||||
__asm
|
||||
push ix
|
||||
ld ix, #0
|
||||
add ix, sp
|
||||
;; SMC: размер accel-блока <- h (высота колонки)
|
||||
ld a, 5 (ix)
|
||||
ld (bc_len_imm), a
|
||||
;; SMC: src-страйд между колонками (8-бит adc-цепочка, ± на вызов)
|
||||
ld a, 6 (ix)
|
||||
ld (bc_slo_imm), a
|
||||
ld a, 7 (ix)
|
||||
ld (bc_shi_imm), a
|
||||
ld b, 4 (ix) ; B = число колонок (0 => 256: djnz)
|
||||
ld c, 8 (ix) ; C = y0 (Port_Y, константа)
|
||||
di ; один DI на весь блит
|
||||
ld d, d ; 0x52 — режим размера блока
|
||||
ld a, #0
|
||||
bc_len_imm = . - 1
|
||||
ld b, b ; 0x40 — стоп (B=счётчик не тронут)
|
||||
bc_col:
|
||||
ld a, c
|
||||
out (#0x89), a ; Port_Y = y0 (сброс на верх колонки)
|
||||
;; ЧТЕНИЕ — ГОРИЗОНТАЛЬНОЙ копией (LD L,L): src-колонка лежит в ОЗУ
|
||||
;; СМЕЖНО, адрес шагает (не port_y). ЗАПИСЬ — ВЕРТИКАЛЬНОЙ (LD A,A):
|
||||
;; port_y шагает вниз по видео-колонке. Режим меняется между read и
|
||||
;; write (do_accel_block применяет один режим на весь блок).
|
||||
ld l, l ; 0x6D — гориз. копия (для ЧТЕНИЯ смежных)
|
||||
ld a, (hl) ; read-блок: h смежных байт src -> буфер accel
|
||||
ld a, a ; 0x7F — верт. копия (для ЗАПИСИ колонки)
|
||||
ld (de), a ; write-блок: буфер -> видео-колонка (port_y++)
|
||||
ld b, b ; 0x40 — стоп
|
||||
;; src += sstride (следующая колонка источника)
|
||||
ld a, l
|
||||
add a, #0
|
||||
bc_slo_imm = . - 1
|
||||
ld l, a
|
||||
ld a, h
|
||||
adc a, #0
|
||||
bc_shi_imm = . - 1
|
||||
ld h, a
|
||||
inc de ; dst += 1 (следующий x)
|
||||
djnz bc_col
|
||||
ei ; закрыть DI-окно
|
||||
pop ix
|
||||
;; callee-pop 5 байт (w,h,sstride:2,y0)
|
||||
pop hl ; ret-адрес
|
||||
pop af
|
||||
pop af
|
||||
inc sp
|
||||
jp (hl)
|
||||
__endasm;
|
||||
}
|
||||
Reference in New Issue
Block a user