libbgi: блочные AND/OR/XOR акселератора (блит строками и колонками)
Акселератор умеет не только копировать блок, но и совмещать его с приёмником: опкод `and/or/xor (hl)` между триггерами чтения и записи переводит внутренний автомат из «буфер := память» в «буфер <op>= память». Операция ортогональна направлению (гориз. LD L,L / верт. LD A,A), значит одинаково работает и для row-major картинок, и для column-major спрайтов персонажей с бесплатным флипом. Полный набор, по образцу существующего копирующего: - ядра bgi256/_bgi_blit_rows_op_raw.c и _bgi_blit_cols_op_raw.c; - строками: gfx_blit_op / gfx_blit_part_op (через _gfx_blit_full_op); - колонками: gfx_blit_cols_op / gfx_blit_cols_part_wx_op (skip/rows/ skipw/maxw и flip — как у копирующего близнеца); - putimage(XOR/OR/AND_PUT) переведён на accel, попиксельным остался только NOT_PUT — закрыт пункт 2d-1 docs/TODO.md. Одна функция на три операции: опкод патчится SMC, как размер блока и страйд, — ветвления в цикле нет. Колоночный путь дороже строкового на один OUT Port_Y: вертикальный op-burst шагает Port_Y, и перед записью его надо вернуть на верх колонки (STOP обязателен — иначе fetch операнда OUT перезапустит burst, memory/accel_operand_fetch_retrigger). Две оговорки (в шапках модулей): - операция ЧИТАЕТ ОЗУ-копию экрана, а не видео-ОЗУ, поэтому при банках 0x54/0x5C совмещается с чистым фоном, а не с нарисованным поверх; - аппаратная прозрачность #FF совместима с AND (нейтраль) и OR (#FF|bg = #FF, запись подавляется), но НЕ с XOR: там источник обязан хранить прозрачный пиксель как 0x00. Проверка: tests/accop (новый) — 8/8 PASS в MAME, побайтно, источник с разными значениями по строкам И колонкам + рамка вокруг; tests/bgi_img получил две байтовые самопроверки (COPY==источник, XOR дважды == фон), обе PASS. make size-check: роста нет (эталон принят заново — kbdpoll +63 Б приехал из прошлой сессии, воспроизводится и без этих правок). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,15 @@ void _bgi_blit_rows_raw(const uint8_t *src, uint8_t *dst,
|
||||
uint8_t w, uint8_t h,
|
||||
int sstride, uint8_t y0);
|
||||
|
||||
/* То же с ЛОГИЧЕСКОЙ ОПЕРАЦИЕЙ (приёмник = приёмник <op> источник): между
|
||||
* чтением источника и записью вставлен третий burst — чтение приёмника в
|
||||
* режиме операции. Всё горизонтально, поэтому три burst'а идут одной
|
||||
* цепочкой без сброса Port_Y. op — ОПКОД `and/or/xor (hl)` (GFX_OP_* из
|
||||
* <gfx.h>), патчится SMC. bgi256/_bgi_blit_rows_op_raw.c. */
|
||||
void _bgi_blit_rows_op_raw(const uint8_t *src, uint8_t *dst,
|
||||
uint8_t w, uint8_t h,
|
||||
int sstride, uint8_t y0, uint8_t op);
|
||||
|
||||
/* КОЛОНОЧНАЯ специализация (column-major src -> экран): каждая колонка —
|
||||
* вертикальный accel-burst (LD A,A, Port_Y авто-шаг); dst +1/колонку, src
|
||||
* +sstride/колонку. Даёт бесплатный горизонтальный флип (sstride<0 + src
|
||||
@@ -96,6 +105,15 @@ void _bgi_blit_cols_raw(const uint8_t *src, uint8_t *dst,
|
||||
uint8_t w, uint8_t h,
|
||||
int sstride, uint8_t y0);
|
||||
|
||||
/* То же с ЛОГИЧЕСКОЙ ОПЕРАЦИЕЙ (приёмник = приёмник <op> источник): между
|
||||
* чтением источника и записью вставлен третий burst — чтение приёмника в
|
||||
* режиме операции. op — ОПКОД `and/or/xor (hl)` (GFX_OP_* из <gfx.h>),
|
||||
* патчится SMC. bgi256/_bgi_blit_cols_op_raw.c (там же — прозрачность и
|
||||
* почему op-burst читает ОЗУ-копию). */
|
||||
void _bgi_blit_cols_op_raw(const uint8_t *src, uint8_t *dst,
|
||||
uint8_t w, uint8_t h,
|
||||
int sstride, uint8_t y0, uint8_t op);
|
||||
|
||||
/* Специализация для heal: src == dst == адрес экрана, оба страйда 0
|
||||
* (строку выбирает Port_Y) — адресной арифметики в цикле нет, строка
|
||||
* 77Т + burst'ы. y0 — стартовый Port_Y; w,h: 0 = 256. Без скобки и
|
||||
@@ -148,6 +166,13 @@ void _gfx_blit_full(int x, int y, const void *img,
|
||||
int sx, int sy, int w, int h);
|
||||
void _gfx_heal_full(int x, int y, int w, int h);
|
||||
|
||||
/* То же с ЛОГИЧЕСКОЙ ОПЕРАЦИЕЙ (приёмник = приёмник <op> источник) —
|
||||
* близнец _gfx_blit_full поверх _bgi_blit_rows_op_raw. op — опкод
|
||||
* GFX_OP_* из <gfx.h>. common/_gfx_blit_full_op.c (там же — прозрачность
|
||||
* и почему op-burst читает ОЗУ-копию). */
|
||||
void _gfx_blit_full_op(int x, int y, const void *img,
|
||||
int sx, int sy, int w, int h, uint8_t op);
|
||||
|
||||
/* Лин-ядра для СПРАЙТОВ (кадр ≤ 64×64, sprite.h): как *_full, но без
|
||||
* split'а >256 и с 8-битными w/h (движок/putsprite — горячий путь;
|
||||
* программа только со спрайтами не тянет общие *_full со split'ом).
|
||||
|
||||
Reference in New Issue
Block a user