Files
Sprinter-SDCC/libbgi/bgi256/_bgi_blit_rows_raw.c
T
snark13 ee1ca00c6f libbgi: funcptr-диспетч clip/noclip спрайтовых ядер + снятие src[0]-фикса
Диспетчеризация 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>
2026-07-13 11:37:54 +03:00

94 lines
5.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* _bgi_blit_rows_raw — специализация accel block-copy для БЛИТА
* (буфер → экран): dst ФИКСИРОВАН (адрес экрана base+x; строку выбирает
* Port_Y, dstride == 0 по определению), src двигается на sstride (ширину
* картинки) на строку. Выделен из _bgi_copy_rows_raw (2026-07-12,
* профиль examples/balls): у блита dst-цепочка (ld a,e; add; ld e,a;
* ld a,d; adc; ld d,a ≈ 24Т/строку) — мёртвый груз, т.к. dst не меняется;
* здесь её нет вообще. src-страйд SMC-патчится в 8-битную adc-цепочку
* (константа на вызов). Универсальный _bgi_copy_rows_raw остаётся для
* getimage (grab: dst двигается, src фикс — другая специализация).
*
* ВХОД (__sdcccall(1)): src→HL, dst→DE (фикс); стек: w 4(ix), h 5(ix),
* sstride 6/7(ix), y0 8(ix). w — байт/строку за burst (1..256, 0=256);
* h — строк (1..256, 0=256); sstride — шаг адреса src между строками;
* y0 — стартовый Port_Y. Callee-pop 5 байт.
*
* Raw: клиппинга НЕТ (вызывающий), W3 замаплен (_bgi_begin/_bgi_end
* снаружи), банк выставлен вызывающим (0x5C прозрачный / 0x50 обычный).
* Буфер src обязан быть ВНЕ W3 (< 0xC000). Полосы > 256 режет вызывающий.
*
* ОДИН DI на весь блит (arm + все строки): убирает per-row EI-окно, где
* CBL-ISR мог пере-армировать акселератор своим размером блока, и тесней
* loop (санкция пользователя 2026-07-12: малый спрайт под одним DI аудио
* не рвёт). ВНИМАНИЕ: h ограничен малыми спрайтами — большие блиты
* (putimage 256 строк) вызывающий обязан резать на чанки ≤16 строк.
*
* Квирк CPU-байта write-триггера СНЯТ (2026-07-13): на точной dev-MAME
* (сборка разработчиков Sprinter) ПЛМ подавляет CPU-байт LD (DE),A при
* активном burst'е — утечки в dst[0] нет (проверено по байтам VRAM:
* tests/blitw col0 @200,150 = GREEN). Старый фикс (preread src[0] +
* EX AF,AF') оставлен закомментированным ниже — восстановить, если
* реальное железо поведёт себя как старая MAME. ПЕРЕПРОВЕРИТЬ НА ЖЕЛЕЗЕ.
*
* Клоббер: AF/BC/DE/HL; IX сохраняется.
*/
#include "../_bgi.h"
void _bgi_blit_rows_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: размер блока <- w (immediate у ld a,#n требование FSM)
ld a, 4 (ix)
ld (br_len_imm), a
;; SMC: src-страйд константа на вызов (8-битная adc-цепочка)
ld a, 6 (ix)
ld (br_slo_imm), a
ld a, 7 (ix)
ld (br_shi_imm), a
ld b, 5 (ix) ; B = счётчик строк (0 => 256: djnz)
ld c, 8 (ix) ; C = y
di ; один DI на весь блит
ld d, d ; 0x52 режим размера блока
ld a, #0
br_len_imm = . - 1
ld b, b ; 0x40 стоп (B=счётчик не тронут)
br_row:
ld a, c
out (#0x89), a ; Port_Y = y
inc c
;; ld a, (hl) ; A = src[0] (accel выключен)
;; ex af, af' ; спрятать src[0]
ld l, l ; 0x6D армировать копию строки
ld a, (hl) ; burst: src -> память акселератора
;; ex af, af' ; A = src[0] CPU-байт триггера записи
ld (de), a ; burst: память акселератора -> dst (фикс)
ld b, b ; 0x40 стоп
;; src += sstride (dst НЕ двигается dstride 0)
ld a, l
add a, #0
br_slo_imm = . - 1
ld l, a
ld a, h
adc a, #0
br_shi_imm = . - 1
ld h, a
djnz br_row
ei ; закрыть DI-окно блита
pop ix
;; callee-pop 5 байт (w,h,sstride:2,y0)
pop hl ; ret-адрес
pop af
pop af
inc sp
jp (hl)
__endasm;
}