Files
Sprinter-SDCC/libbgi/common/putimage.c
T
snark13 860468f3c5 libbgi: NOT_PUT тоже через акселератор + изыскания по виду Тени
NOT.  У акселератора нет режима «инвертировать буфер»: буфер меняется
только на ЧТЕНИИ и только опкодами AND/OR/XOR (HL) (драйвер MAME,
update_accel_buffer), а `CPL` автомат вообще не распознаёт — инвертируется
регистр CPU, не буфер.  Зато ~src = src XOR #FF, поэтому NOT собирается из
уже имеющегося: буфер := src, XOR-burst по константному блоку единиц
(common/_bgi_ones256.c), запись.  Ядра _bgi_blit_{rows,cols}_not_raw.c;
между burst'ами меняется HL, поэтому каждая смена — под СТОПом (иначе fetch
операнда перезапустит burst).  В колоночном варианте второй OUT Port_Y не
нужен: op-burst идёт по блоку единиц горизонтально, а Port_Y шагает только
вертикальный.

Наружу — тем же op-параметром (GFX_OP_NOT), диспетчер один раз на вызов, в
цикл по полосам/колонкам не заходит.  putimage лишился попиксельного пути
ЦЕЛИКОМ: все пять операций BGI идут через акселератор и клиппируются
одинаково.  tests/accop дополнен T9/T10 (NOT строками и колонками) —
10/10 PASS в MAME; tests/bgi_img P1/P2 по-прежнему PASS.

tests/convbench (новый) — замер побайтной конвертации атласа
«прозрачный #FF -> 0x00» (источник для XOR-блита): 145.3 такта/байт, то
есть 2.5× от 59 номинальных T-states цикла.  0.11 с на страницу 16 КБ,
3.2 с на все 28 страниц, 1.3 с по фактическому объёму данных (186 КБ).

applications/PoP/docs/shadow_render.md — вид Тени (два блиттера OR+XOR)
ОТЛОЖЕН по решению пользователя: пока рисуем обычной копией атласами Кида.
В документе собрано, почему в лоб не выходит (XOR несовместим с
прозрачностью #FF; операция читает ОЗУ-копию, поэтому два прохода
оригинала вырождаются в один XOR — нужен однопроходный композит
s | bg ^ s(сдвиг)), замер стоимости источника и четыре варианта.  Ключ к
выбору — список кадров, которыми тень реально пользуется; снимать по факту,
когда пойдут уровни 5/6/12.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 15:41:06 +03:00

49 lines
2.4 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.
/*
* putimage — вывести образ bitmap левым-верхним углом в (left,top)
* операцией op. Заголовок буфера: uint16 width, uint16 height.
*
* COPY_PUT — через accel-ядро gfx_blit_part (block-copy строками, до
* 256 байт за burst; Фаза A спрайтового дизайна) — С КЛИППИНГОМ по
* экрану (superset поведения Turbo C, где выход за экран — UB) и
* с учётом текущего банка (gfx_set_bank: 0x58 даёт аппаратную
* прозрачность 0xFF, 0x54/0x5C — временный вывод).
*
* XOR/OR/AND/NOT_PUT — тоже через акселератор (gfx_blit_part_op,
* 2026-08-11; закрыт пункт 2d-1 docs/TODO.md): у железа есть блочные
* AND/OR/XOR между буфером акселератора и памятью приёмника, а NOT
* выражается через XOR по блоку единиц. Попиксельного пути в putimage
* больше НЕТ ВООБЩЕ, и клиппинг у всех пяти операций теперь одинаковый
* (раньше на непрямом пути его не было вовсе).
*
* Оговорки — в шапке common/_gfx_blit_full_op.c: операция читает
* ОЗУ-копию экрана (при банках 0x54/0x5C это чистый фон, а не то, что
* нарисовано поверх), а прозрачность #FF совместима с AND/OR, но не с XOR.
*
* Буфер bitmap обязан лежать вне W3 (< 0xC000) — на время операции W3
* замаплен на видеобанк.
*/
#include "../_bgi.h"
void putimage(int left, int top, const void *bitmap, int op)
{
const uint8_t *p = (const uint8_t *)bitmap;
int w, h;
uint8_t gop;
w = p[0] | (p[1] << 8);
h = p[2] | (p[3] << 8);
if (w <= 0 || h <= 0) return;
switch (op) {
case XOR_PUT: gop = GFX_OP_XOR; break;
case OR_PUT: gop = GFX_OP_OR; break;
case AND_PUT: gop = GFX_OP_AND; break;
case NOT_PUT: gop = GFX_OP_NOT; break;
case COPY_PUT:
default:
gfx_blit_part(left, top, bitmap, 0, 0, w, h);
return;
}
gfx_blit_part_op(left, top, bitmap, 0, 0, w, h, gop);
}