Files
Sprinter-SDCC/libc/include/irq.h
T
snark13 8a952b99eb irq: Phase 2a — CTC-таймер на отдельном векторе 0x06 (Z84C015)
- irq_ctc_install(handler, div2, div3) / irq_ctc_remove: канал 2 CTC
  делит видеотакт 875 кГц (1 тик = 1 знакоместо), канал 3 считает от
  него и прерывает; f = 875000/(div2*div3), div 0 = 256. Пресет
  IRQ_CTC_VSYNC_DIV2/3 = 112*160 — точное начало кадра ~48.8 Гц БЕЗ
  примеси клавиатуры (вектор 0x06 отделён от общего 0xFF)
- CTC-трамплин: полный сейв -> handler -> EI/RETI; RETI обязателен
  (daisy chain Z84C015 снимает IUS только по опкоду RETI); к DSS не
  чейнится — личное прерывание
- общая IM2-таблица под счётчиком ссылок (_irq_table.c): кадровый и
  CTC-хендлеры независимы, последний unref возвращает I/IM 1;
  atexit-уборка глушит CTC обязательно (иначе кГц-прерывания душат
  шелл после выхода)
- порты/слова по docs/samples: CH0=0x10/CH2=0x12/CH3=0x13,
  0x57/0xD7/вектор в CH0, стоп 0x03
- irqtest: CTC-vsync параллельно с кадровым + произвольная частота;
  MAME: frame 48 Гц, ctc(vsync) 49 Гц (parallel frame жив),
  ctc(50x50) 350 Гц точно по формуле, remove/выход чистые

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

64 lines
3.7 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. Штатно DSS работает в
* IM 1 (обработчик 0x0038). irq_install() переключает CPU в IM 2 со
* своей таблицей и зовёт handler ТОЛЬКО на кадровых прерываниях;
* после него (и на всех прочих источниках) управление всегда
* передаётся штатному обработчику DSS на 0x0038 — клавиатура,
* SYSTIME и курсор мыши продолжают работать. irq_remove()
* возвращает IM 1/I как было (и вызывается автоматически из 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
#include <stdint.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);
/* ---- CTC-таймер (Z84C015, вектор 0x06 — отдельный от кадрового) ---
*
* Канал 2 тактируется 875 кГц (1 тик = 1 знакоместо видеотракта) и
* делит; канал 3 считает от канала 2 и прерывает. Частота handler'а:
* f = 875000 / (div2 * div3), div 0 = 256
* (диапазон ~13 Гц .. десятки кГц; на частотах выше пары кГц handler
* должен быть ОЧЕНЬ коротким). Ставится независимо от irq_install —
* можно иметь оба. Ограничения для handler'а те же, что выше.
* Обработчик завершается RETI (в трамплине) — daisy chain Z84C015. */
int irq_ctc_install(isr_t handler, uint8_t div2, uint8_t div3);
void irq_ctc_remove(void); /* глушит CTC; тоже вызывается из exit() */
/* Пресет точного кадра: 112 тактов (2 пикс. линии) * 160 = 320 линий,
* ~48.8 Гц, начало кадра — «vsync без примеси клавиатуры». */
#define IRQ_CTC_VSYNC_DIV2 112
#define IRQ_CTC_VSYNC_DIV3 160
/* Скобки для доступа main-кода к данным, разделяемым с ISR. */
#define IRQ_DISABLE() __asm__("di")
#define IRQ_ENABLE() __asm__("ei")
#endif