Files
Sprinter-SDCC/libbgi/common/_gfx_w0_isr.c
T
snark13 0e935343d9 libbgi: W0-атласы спрайтов — загрузчик, движок, упаковщик (все проверки PASS)
Реализация §3.1/§9в: атлас = один .atl-файл = одна EMM-страница,
подключаемая в W0 на время блита.

- atlas_load: read() файла целиком в страницу через W3 + патч ISR-стаба
  (0x38: JP _gfx_w0_isr; 0x66: RETN); atlas_free/atlas_image/
  atlas_sprite_init; gfx_w0_map/unmap для ручных вызовов.
- _gfx_w0_isr (стаб из tests/w0page): свап на ядро DSS → честный 0x38 →
  restore спрайт-страницы; покрывает IM1 и IM2-чейн.
- sprite_t.page (0 = обычная память); sprite_update в блит-проходе
  мапит страницу по смене (один OUT на атлас), эпилог возвращает DSS
  (+52 Б на движок — цена фичи).
- toolchain/mkatlas.py: PNG (indexed) / raw → .atl; заголовок 0x100,
  каталог 0x68 (19 лент), файл-офсет == офсет страницы == W0-адрес.
- Сплит _gfx_sprite_fns → _gfx_blit_fn.c + _gfx_heal_fn.c (1 указатель
  = 1 модуль): putsprite-only программа не тянет heal-ядро (spriteclip
  ловил +292 Б; теперь −68 Б от эталона).

tests/atlas (MAME dev, PASS): загрузка (count/страница), каталог и
данные по W0-адресам (заголовок ленты через gfx_w0_map), 3 спрайта из
двух лент через движок — пиксели проверены read_vram побайтно
(0x10/0x12/0x21, прозрачный угол = фон).

docs: §9г — предложение авто-анимации (кадровая ±step без умножений,
tween-Брезенхэм порциями, тикер через funcptr) — ОБСУЖДАЕТСЯ.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:52:00 +03:00

44 lines
2.2 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.
/*
* _gfx_w0_isr — ISR-стаб для спрайт-страниц в W0 (§9в дизайна).
*
* Сюда прыгает 3-байтный JP, который atlas_load патчит в 0x38 каждой
* атлас-страницы: пока страница подключена в W0, ЛЮБОЕ прерывание
* (IM1 напрямую; IM2-трамплин libc/irq чейнит jp 0x0038) попадает в
* этот стаб вместо кода ядра DSS.
*
* Схема (проверена tests/w0page, MAME dev 2026-07-13):
* 1) W0 := страница ядра DSS (_gfx_w0_dss);
* 2) подложить адрес возврата и прыгнуть в честный 0x0038 — DSS
* делает свой save/restore и завершает EI/RETI → возврат в хвост;
* 3) хвост: W0 := _gfx_w0_cur (спрайт-страница) — restore ОБЯЗАТЕЛЕН,
* он закрывает EI-щель между out(0x82) движка и DI leaf'а.
* Вложенное прерывание в хвосте (EI уже сделан DSS) безопасно: W0 в
* этот момент = DSS, штатный путь, стаб не реентерится.
*
* Живёт в _CODE — обязан быть в W2 (режимы tiny/big; в small/huge код
* в W1, который прерывание может перемапить — не использовать W0-атласы
* с irq_install там; сам стаб зовётся только при странице в W0, т.е.
* из окна sprite_update, где W1 стоит программный — работает).
*/
#include "../_bgi.h"
void _gfx_w0_isr(void) __naked
{
__asm
push af
ld a, (__gfx_w0_dss)
out (#0x82), a ; W0 = ядро DSS
pop af
push hl
ld hl, #w0_isr_ret
ex (sp), hl ; вершина стека = возврат, HL цел
jp 0x0038 ; честный обработчик (EI/RETI)
w0_isr_ret:
push af
ld a, (__gfx_w0_cur)
out (#0x82), a ; вернуть спрайт-страницу
pop af
ret
__endasm;
}