Files
Sprinter-SDCC/libc/irq/_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

62 lines
3.4 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 — внутренности IM2-модуля (НЕ публичный заголовок).
*
* Механика (docs/im2_isr_design.md):
* - таблица векторов: 257 байт с выравниванием 256 внутри статического
* буфера 513 байт (_irq_state.c), заполняется байтом H = старший
* байт её же адреса; CPU по внешнему вектору 0xFF читает адрес
* (H<<8|H) — трёхбайтовый `jp _irq_tramp` лежит ВНУТРИ таблицы по
* смещению H (H < 0xC0 — с [0xFF]/[0x100] не пересекается; заливка
* H перехватывает и вектора SIO 0x10..0x1E, если их кто-то включит);
* - таблица общая для кадрового и CTC-хендлеров — жизнью управляет
* счётчик ссылок (_irq_table_ref/_irq_table_unref в _irq_table.c);
* unref последнего возвращает I и IM 1 (штатный режим DSS);
* - кадровый трамплин (_irq_tramp.c): AF-пробник порта 0x19 (SIO-A
* RR0, бит 0 = клавиатурный байт); кадр → полный save → user
* handler → restore; затем ВСЕГДА jp на обработчик DSS 0x0038
* (DSS работает в IM 1) — EI/RETI делает DSS;
* - CTC-трамплин (_irq_ctc_tramp.c): вектор 0x06 (Z84C015, каналы
* 2+3 в связке, база 875 кГц); полный save → handler → restore →
* EI/RETI — RETI ОБЯЗАТЕЛЕН (daisy chain: без него CTC не пошлёт
* следующее прерывание); к DSS НЕ чейнится (наше личное прерывание).
*/
#ifndef _IRQ_INTERNAL_H
#define _IRQ_INTERNAL_H
#include <stdint.h>
#include <irq.h>
/* Буфер под таблицу: 256 (выравнивание) + 257 (таблица). */
#define _IRQ_VEC_BUF_SIZE (256 + 257)
extern uint8_t _irq_vec_buf[_IRQ_VEC_BUF_SIZE];
extern isr_t _irq_user; /* кадровый handler; NULL = нет */
extern isr_t _irq_ctc_user; /* CTC-handler; NULL = нет */
extern uint8_t _irq_old_i; /* I до захвата таблицы */
extern uint8_t _irq_refs; /* счётчик пользователей таблицы */
/* Порты встроенной периферии Z84C015 (docs/samples/SIO_CTC_KEY.asm). */
#define _IRQ_CTC_CH0 0x10
#define _IRQ_CTC_CH2 0x12
#define _IRQ_CTC_CH3 0x13
#define _IRQ_SIO_A 0x19 /* SIO-A RR0: бит 0 = Rx available */
/* Захватить/отпустить IM2-таблицу (счётчик ссылок). ref: при первом
* захвате строит таблицу, ставит I/IM2, взводит atexit-уборку;
* 0 или -1+errno (EINVAL — код/буфер не в W2). unref: при последнем
* отпускании возвращает I и IM 1. */
int _irq_table_ref(void);
void _irq_table_unref(void);
/* Адрес выровненной таблицы (валиден при _irq_refs > 0). */
uint8_t *_irq_table(void);
/* Входы трамплинов (asm). */
void _irq_tramp(void);
void _irq_ctc_tramp(void);
/* SMC-операнд `jp` на обработчик DSS (метка в _irq_tramp.c). */
extern uint16_t _irq_dss_target;
#endif