ee1ca00c6f
Диспетчеризация clip/noclip через указатели _gfx_blit_fn/_gfx_heal_fn (common/_gfx_sprite_fns.c, дефолт clip): gfx_sprite_clip() — теперь модуль, переключает указатели один раз; sprite_update/putsprite/ movesprite зовут через указатель — ветка if(clip) из горячего цикла убрана (съедала половину выигрыша noclip). Программа без вызова gfx_sprite_clip() noclip-ядра не линкует. Замер dev-MAME (16 шаров, uncapped): clip 50 → noclip 60-61 fps (+20-22%). Регресс tests/sprites (A/B PASS), size-check OK (balls −237 Б, sprites −3177 Б — отвязались лишние ядра). Фикс CPU-байта write-триггера (preread + EX AF,AF') снят: точная dev-MAME эмулирует ПЛМ, подавляющую CPU-байт при активном burst'е — подтверждено по байтам VRAM (tests/blitw col0 = GREEN через read_vram MCP-моста). Для heal фикс был избыточен всегда (банк 0x50 перезаписывает dst[0]). Строки фикса оставлены закомментированными в трёх leaf'ах на случай отличий реального железа; шапки и §9а/§9б дизайна обновлены. НА ЖЕЛЕЗЕ ПЕРЕПРОВЕРИТЬ. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76 lines
4.4 KiB
C
76 lines
4.4 KiB
C
/*
|
||
* _bgi_heal_rows_raw — специализация accel-копии для heal (src == dst ==
|
||
* адрес экрана): h строк по w байт «прочитать ОЗУ-копию → записать в
|
||
* VRAM+ОЗУ» на одном месте. Выделен из _bgi_copy_rows_raw по профилю
|
||
* examples/balls (2026-07-12): у heal ОБА страйда нулевые по
|
||
* определению (строку выбирает Port_Y, CPU-адрес не меняется), поэтому
|
||
* адресной арифметики в цикле нет вообще — строка 77Т + burst'ы против
|
||
* 204Т у универсального leaf'а до оптимизации.
|
||
*
|
||
* ВХОД (__sdcccall(1)): scr→HL (base + x), y0→DE (E — стартовый
|
||
* Port_Y); стек: w 4(ix), h 5(ix) — 1..256, 0 = 256 (конвенция
|
||
* акселератора). Callee-pops 2 байта.
|
||
*
|
||
* Raw: клиппинга нет, W3 замаплен вызывающим; банк выбирает
|
||
* вызывающий (gfx_heal форсит 0x50 — иначе heal бессмыслен).
|
||
* Полосы > 256 байт режет вызывающий.
|
||
*
|
||
* Квирк CPU-байта write-триггера: фикс (preread + EX AF,AF') СНЯТ
|
||
* (2026-07-13). Для heal он был избыточен ВСЕГДА: банк 0x50 без
|
||
* прозрачности — даже если CPU-байт утёк бы в dst[0], burst тут же
|
||
* перезаписывает его тем же значением из ОЗУ-копии. Плюс точная
|
||
* dev-MAME показала, что ПЛМ вообще подавляет CPU-байт (см.
|
||
* _bgi_blit_rows_raw). Закомментированные строки ниже — след старого
|
||
* фикса на случай отличий реального железа.
|
||
*
|
||
* Клоббер: AF/BC/DE/HL; IX сохраняется.
|
||
*/
|
||
|
||
#include "../_bgi.h"
|
||
|
||
void _bgi_heal_rows_raw(uint8_t *scr, int y0, uint8_t w, uint8_t h) __naked
|
||
{
|
||
__asm
|
||
push ix
|
||
ld ix, #0
|
||
add ix, sp
|
||
;; SMC: размер блока <- w (immediate — требование FSM)
|
||
ld a, 4 (ix)
|
||
ld (hr_len_imm), a
|
||
ld c, e ; C = y (взять ДО затирания DE)
|
||
ld b, 5 (ix) ; B = счётчик строк (0 => 256)
|
||
ld d, h
|
||
ld e, l ; DE = HL = scr (src == dst)
|
||
;; ОДИН DI на весь спрайт (arm + все строки): убирает per-row
|
||
;; EI-окно, где CBL-ISR мог пере-армировать акселератор своим
|
||
;; размером блока (латентная реентерабельность), и тесней loop.
|
||
;; Санкция пользователя 2026-07-12: 16×16 = 256 байт под одним DI
|
||
;; (как 1×256 fill) на аудио не влияет. ВНИМАНИЕ: h ограничен
|
||
;; малыми спрайтами — для больших блитов (putimage 256 строк)
|
||
;; вызывающий обязан резать на чанки ≤16 строк (иначе долгий DI).
|
||
di
|
||
ld d, d ; 0x52 — режим размера блока
|
||
ld a, #0
|
||
hr_len_imm = . - 1
|
||
ld b, b ; 0x40 — стоп (B=счётчик не тронут)
|
||
hr_row:
|
||
ld a, c
|
||
out (#0x89), a ; Port_Y = y
|
||
inc c
|
||
;; ld a, (hl) ; предчитать ОЗУ[0] (accel выключен)
|
||
;; ex af, af'
|
||
ld l, l ; 0x6D — армировать копию строки
|
||
ld a, (hl) ; burst: ОЗУ-копия -> память акселератора
|
||
;; ex af, af' ; A = ОЗУ[0] — CPU-байт триггера корректен
|
||
ld (de), a ; burst: память акселератора -> VRAM+ОЗУ
|
||
ld b, b ; 0x40 — стоп
|
||
djnz hr_row ; адреса не меняются — только Port_Y
|
||
ei ; закрыть DI-окно спрайта
|
||
pop ix
|
||
pop hl ; ret-адрес; callee-pop 2 байта (w,h)
|
||
inc sp
|
||
inc sp
|
||
jp (hl)
|
||
__endasm;
|
||
}
|