/*
 * _irq_state — данные IM2-модуля.  Только данные.
 *
 * Кадровый обработчик теперь ЦЕПОЧКА (_irq_chain[]) вместо одного слота
 * (см. docs/im2_isr_design.md «Цепочка кадровых обработчиков»).
 *
 * Всё, к чему трамплин обращается ВО ВРЕМЯ прерывания, обязано жить в
 * W2 (0x8000-0xBFFF) — единственное окно, которое DSS не перемапливает
 * (там стек).  В tiny/big/huge вся BSS садится в W2 (code-loc W2 либо
 * data-loc 0x8000); в small для маленьких программ BSS может оказаться
 * в W1 — тогда _irq_table_ref вернёт EINVAL (safe).  Полное снятие
 * этого ограничения (резерв area _IM2) — отдельный follow-up.
 */

#include "_irq.h"

uint8_t _irq_vec_buf[_IRQ_VEC_BUF_SIZE];

/* Цепочка кадровых обработчиков.  Пустой слот = NULL.  Порядок вызова =
 * порядок индексов; после remove/add взаимный порядок НЕ гарантирован
 * (переиспользуется первая дыра) — хендлеры обязаны быть независимы. */
isr_t   _irq_chain[IRQ_CHAIN_MAX];
uint8_t _irq_chain_n;            /* число занятых слотов (быстрый выход) */

isr_t   _irq_ctc_user;           /* CTC-handler; NULL = нет */
isr_t   _irq_cbl_hook;           /* хук CBL-насоса; NULL = нет */
uint8_t _irq_old_i;              /* I до захвата таблицы */
uint8_t _irq_refs;               /* счётчик пользователей таблицы */

/* --- W1-remap для all-modes (см. трамплин) ---------------------------
 * В small/huge базовый код приложения в W1 (статическая страница).
 * Трамплин (в W2) вокруг вызова хендлеров восстанавливает эту страницу
 * в W1, чтобы хендлер, лежащий где угодно в плоском 0x4000-0xBFFF, был
 * адресуем; на выходе возвращает прочитанное на входе (что было —
 * возможно DSS-страница, если прервали сисколл). */
uint8_t _irq_app_w1_page;        /* базовая W1-страница (IN 0xA2 при install) */
uint8_t _irq_saved_w1;           /* W1 на входе в прерывание (для restore) */

/* W2-копия трамплина: в small/huge сам _irq_tramp лежит в W1-коде и в
 * момент прерывания может быть перемаплен — _irq_table_ref копирует его
 * байты сюда (BSS=W2) и направляет вектор на копию.  В tiny/big копия не
 * нужна (трамплин уже в W2), буфер не используется. */
uint8_t _irq_tramp_w2buf[_IRQ_TRAMP_BUF_SIZE];
