/* * _bgi_clear_raw — залить всё поле 320×256 цветом color, mode 0x81. * * Chunked-схема (v2, 2026-07-10): 20 DI-скобок по 16 колонок (256 строк * каждая) — армирование размера один раз на скобку, на колонку только * ре-арм LD E,E + выстрел (см. _gfx_rectfill256.c и * memory/accel_multitrigger_fill; проверено в MAME tests/accfill). * Окно DI на чанк ≈ 0.6 мс (16×256 байт) — CBL/IM2 живут. * Вертикальный Fill двигает Port_Y — re-OUT 0 перед каждой колонкой. * * Register-only asm, без глобального скретча. W3-naive: вызывающий * обрамляет _bgi_begin/_bgi_end. color → A (__sdcccall(1)). */ #include "../_bgi.h" void _bgi_clear_raw(uint8_t color) __naked { __asm .globl __gfx_addr_base ld c, a ; C = цвет ld hl, (__gfx_addr_base) ; HL = база draw-страницы ld d, #0 ; y0 = 0 ld e, #20 ; 20 чанков × 16 колонок = 320 clr_chunk: di ;; Армирование размера НЕ выносить из цикла (экономия ~0.1%): ;; в окне EI между чанками CBL-ISR сам армирует акселератор ;; своим размером блока — каждый чанк обязан армировать заново. ld d, d ; 0x52 — режим размера блока (no-op для D) ld a, #0 ; размер 256 (конвенция акселератора) ld b, b ; выключить — размер сохранён ld b, #16 ; колонок в чанке clr_col: ld a, d out (#0x89), a ; Port_Y = 0 (vertical Fill его сдвинул) ld e, e ; 0x5B — вертикальный Fill (no-op для E) ld a, c ld (hl), a ; выстрел: колонка 256 строк ld b, b ; выключить (перед djnz — fetch смещения!) inc hl ; следующая колонка djnz clr_col ei ; окно для прерываний между чанками dec e jr NZ, clr_chunk ret __endasm; } #if 0 /* ================================================================ * Старый вариант (до 2026-07-10): полный брекет (DI+арм размера+ * режим+выстрел+выкл+EI) на КАЖДУЮ из 320 колонок. Оставлен * закомментированным для отката/сравнения. * ================================================================ */ void _bgi_clear_raw(uint8_t color) __naked { __asm ld c, a ; color -> c xor a, a out (#0x89), a ; Port_Y = 0 ld hl, (__gfx_addr_base) ; HL = база draw-страницы (0xC000/0xC140) ld de, #0x0000 _clear_cyc0: ld a, e ; if DE >= 320 - return sub a, #0x40 ld a, d sbc a, #0x01 ret NC ;; --- ПОСЛЕДОВАТЕЛЬНОСТЬ АКСЕЛЕРАТОРА --- di ld d, d ; 0x52 — режим размера блока ld a, #0 ; 0x3E 0 — размер (256 точек по высоте) ld e, e ; 0x5B — вертикальный Fill ld a, c ; 0x79 — A = цвет (НЕ ещё один ld a,#n) ld (hl), a ; выстрел; заливает _gfx_acc_len байт ld b, b ; 0x40 — выключить ei inc hl inc de jr _clear_cyc0 __endasm; } #endif