Files
Sprinter-SDCC/libc/include/irq.h
T
snark13 a6fe50e247 libc: IM2 user-ISR, Phase 1 — libc/irq (irq_install/irq_remove) + irqtest
Проще исходного плана (docs/im2_isr_design.md обновлён): отдельный
--memory im2 не понадобился.

- <irq.h>: irq_install(handler) — вызов ~50 Гц только на КАДРОВЫХ
  прерываниях (клавиатура bit0:0x19 и CBL bit7:0xFE отфильтровываются);
  штатный обработчик DSS чейнится ВСЕГДА (SMC-jp, адрес из старой
  IM2-таблицы по регистру I) — клавиатура/SYSTIME/мышь живут
- вектор-таблица: 513 Б BSS + runtime-выравнивание; Sprinter шлёт
  только вектор 0xFF, поэтому jp-заглушка лежит внутри самой таблицы
  по смещению H — без linker-областей и правок crt0
- трамплин: полный сейв обоих наборов+IX/IY вокруг user-handler'а
  (ex af,af' как .db 0x08 — апостроф ломает препроцессор SDCC)
- tiny/big: работает (код в W2); small/huge: EINVAL по проверке
  адресов; irq_remove идемпотентен и висит на atexit (выход без
  снятия = I в памяти умершего процесса = крах шелла); old_I==0 → IM1
- tests/irqtest: тики за 3 с против time() (~50 Гц), живая клавиатура
  под handler'ом, остановка после remove, чистый выход
- docs: im2_isr_design (статус+дельты), libc-reference (<irq.h>), TODO

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 21:21:16 +03:00

43 lines
2.3 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.
/*
* irq.h — пользовательский обработчик кадрового прерывания (IM 2).
*
* Sprinter шлёт вектор 0xFF от трёх источников: кадр (50 Гц),
* клавиатура (бит 0 порта 0x19), CBL/COVOX (бит 7 порта 0xFE).
* irq_install() перехватывает IM2-таблицу и зовёт handler ТОЛЬКО на
* кадровых прерываниях; после него (и на всех прочих источниках)
* управление всегда передаётся штатному обработчику DSS — клавиатура,
* SYSTIME и курсор мыши продолжают работать. irq_remove()
* восстанавливает всё как было (и вызывается атоматически из exit).
*
* ТРЕБОВАНИЕ ПАМЯТИ: код и данные программы должны быть в W2
* (0x8000-0xBFFF) — режимы tiny и big. В small/huge (CODE в W1)
* irq_install вернёт -1/EINVAL: во время прерывания W1 может быть
* перемаплен. Дизайн: docs/im2_isr_design.md.
*
* Правила для handler'а (вызывается ~50 раз/с, все регистры
* сохраняются снаружи):
* МОЖНО: volatile-глобалы, арифметика, короткая работа (<1 мс);
* НЕЛЬЗЯ: ESTEX/BIOS-вызовы (printf/malloc/файлы), gfx_* и любой
* своп W1/W3, акселератор, banked-функции, longjmp наружу.
*/
#ifndef IRQ_H
#define IRQ_H
typedef void (*isr_t)(void);
/* Установить обработчик кадрового прерывания.
* 0 — OK; -1 + errno: EBUSY (уже установлен), EINVAL (код/данные
* не в W2 — неподходящий memory mode). */
int irq_install(isr_t handler);
/* Снять обработчик и вернуть IM2-таблицу DSS. Безопасно звать
* повторно; вызывается автоматически при exit(). */
void irq_remove(void);
/* Скобки для доступа main-кода к данным, разделяемым с ISR. */
#define IRQ_DISABLE() __asm__("di")
#define IRQ_ENABLE() __asm__("ei")
#endif