libc/irq: цепочка кадровых обработчиков + all-modes W1-remap
_irq_user → _irq_chain[4]+_irq_chain_n (W2-BSS); трамплин tr_frame проходит слоты (один тяжёлый сейв на всю цепь, пустой слот пропуск). API irq_chain_add (0/-1+ENOMEM) / irq_chain_remove(h); irq_install → обёртка chain_add (EBUSY исчез), irq_remove() рвёт всю цепь; refcount таблицы на первом/последнем слоте, мутации под IRQ_DISABLE. Лимит 4 кадровых + 1 CTC. All-modes: трамплин copy-safe (только jr/djnz + литерал jp 0x0038), _irq_table_ref копирует его в _irq_tramp_w2buf (W2) когда оригинал в W1 (small/huge), вектор → на копию; вокруг вызова хендлеров восстанавливает базовую W1-страницу (_irq_app_w1_page = IN 0xA2). Хендлер может лежать где угодно в плоском 0x4000-0xBFFF. Проверено в MAME (tests/irqtest, 2 хендлера): tiny/big/huge — chain h1=h2 → remove h2 → h1 жив/h2=0; huge = код в W1, remap работает. Follow-up: CTC в small/huge = EINVAL (нужна W2-копия _irq_ctc_tramp); small для мелких программ (BSS в W1) = irq_install EINVAL, safe. Доки: im2_isr_design (цепочка), sprite-api §9е (делитель поверх цепи), fast_ram §8. rpgprof: gfx_sprite_ysort в профиль (+230 Б baseline). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+26
-18
@@ -5,26 +5,34 @@
|
||||
|
||||
## Ближайшее
|
||||
|
||||
- [ ] **FPS-делитель (frame pacing)** — gfx_set_fps_div(n): логический
|
||||
Порядок реализации связки: **сначала цепочка irq, потом FPS-делитель
|
||||
поверх неё** (делитель — просто один слот цепи; так снимается EBUSY
|
||||
на сосуществование со своим тиком приложения).
|
||||
|
||||
- [x] **(1) irq: цепочка кадровых обработчиков** — СДЕЛАНО 2026-07-15.
|
||||
Массив `isr_t _irq_chain[4]` + `_irq_chain_n` в W2-data (заменили
|
||||
`_irq_user`); трамплин `tr_frame` проходит слоты (один тяжёлый сейв
|
||||
на всю цепь, пустой слот пропускается); API `irq_chain_add`
|
||||
(0/-1+ENOMEM), `irq_chain_remove(h)`; `irq_install` → обёртка
|
||||
chain_add (EBUSY исчез), `irq_remove()` рвёт всю цепь; refcount
|
||||
таблицы на первом/последнем слоте; мутации под IRQ_DISABLE.
|
||||
All-modes W1-remap: трамплин копируется в W2 (`_irq_tramp_w2buf`,
|
||||
copy-safe — только jr/djnz + литерал jp 0x0038), вокруг вызова
|
||||
восстанавливает базовую W1-страницу (`_irq_app_w1_page` = IN 0xA2
|
||||
при install). ПРОВЕРЕНО в MAME (tests/irqtest, 2 хендлера):
|
||||
tiny/big/huge — chain 97=97 → remove h2 → 48/0; **huge = код в W1,
|
||||
remap работает** (цепочка тикает синхронно). Дизайн:
|
||||
docs/im2_isr_design.md.
|
||||
FOLLOW-UP: (а) CTC-трамплин пока требует код в W2 → в small/huge
|
||||
`irq_ctc_install` = EINVAL (нужна такая же W2-копия _irq_ctc_tramp);
|
||||
(б) small для мелких программ (BSS в W1) → irq_install EINVAL
|
||||
(safe; снять резервом area _IM2 в верхней W2).
|
||||
- [ ] **(2) FPS-делитель (frame pacing)** — gfx_set_fps_div(n): логический
|
||||
кадр = ровно n кадровых интервалов (50/25/16.7 fps), при
|
||||
переполнении слота — выравнивание на ближайший фронт; счётчик
|
||||
кадров через irq_install (только tiny/big в первой версии).
|
||||
ПОЛНЫЙ ПЛАН: docs/sprite-api-design.md §9е (обсуждён 2026-07-14).
|
||||
- [ ] **irq: цепочка обработчиков** (дизайн 2026-07-14, реализация по
|
||||
потребности — понадобится, когда в программе сойдутся fps-делитель
|
||||
+ свой тик/звук). Вместо одного слота (EBUSY) — фиксированный
|
||||
массив `isr_t _irq_chain[IRQ_CHAIN_MAX /* 4 */]` в W2-data:
|
||||
- трамплин вместо SMC-вызова одного handler'а обходит слоты
|
||||
(load/or a/skip-NULL/call — пустой слот ~40Т, копейки на кадре);
|
||||
- API: `irq_chain_add(h)` (0 / -1+ENOMEM когда слоты кончились),
|
||||
`irq_chain_remove(h)` (по указателю; слот → NULL);
|
||||
- совместимость: `irq_install(h)` становится обёрткой chain_add
|
||||
(EBUSY исчезает), `irq_remove()` БЕЗ аргумента снимает ВСЮ цепь
|
||||
и возвращает IM 1 — семантика exit/atexit сохранена;
|
||||
- порядок вызова = порядок слотов; взаимный порядок хендлеров НЕ
|
||||
гарантируется после remove/add (первая дыра) — хендлеры обязаны
|
||||
быть независимы; дисциплина ISR прежняя (irq.h);
|
||||
- CTC-цепочка (irq_ctc_*) — тем же паттерном, если понадобится.
|
||||
кадров через irq_chain_add(_gfx_frame_isr) (только tiny/big в
|
||||
первой версии). ПОЛНЫЙ ПЛАН: docs/sprite-api-design.md §9е
|
||||
(обсуждён 2026-07-14; ограничение EBUSY снято цепочкой).
|
||||
- [ ] **П6/железо**: MAME-смоук всех тестов после libc-сплита (conio,
|
||||
ptime, stattest, mouse, gfx_demo/gfx_d16/gfx_text/gfx_mous —
|
||||
трогался asm акселератора); затем прогон на реальном Sprinter
|
||||
|
||||
Reference in New Issue
Block a user