Files

532 lines
36 KiB
C
Raw Permalink 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.
/**
* @file tsconf.h
* @brief Полный справочник регистров TSConfig (TSL FPGA-ускоритель ZX Spectrum)
* @version 2.0
*
* Самодостаточная библиотека: зависит только от types.h.
* Подходит для любого TSConfig-проекта на SDCC Z80.
*
* ═══════════════════════════════════════════════════════════════════
* АРХИТЕКТУРА ПОРТОВ
* ═══════════════════════════════════════════════════════════════════
*
* Все порты TSConfig адресуются по схеме: (REG_NUM << 8) | 0xAF
* Запись: OUT (C),A где BC = порт.
*
* На ASM:
* LD BC, TSCONF_PORT_SYSCONFIG ; BC = 0x20AF
* LD A, TSCONF_CPU_14MHZ
* OUT (C), A
*
* На C:
* tsconf_out(TSCONF_PORT_SYSCONFIG, TSCONF_CPU_14MHZ);
*
* Макросы-обёртки (конец файла) упрощают типичные операции:
* tsconf_set_cpu(TSCONF_CPU_14MHZ);
* tsconf_set_border(1);
* tsconf_set_frame_int(100, 0);
*
* ═══════════════════════════════════════════════════════════════════
* ТАЙМИНГИ TV-РЕЖИМА (Pentagon-128)
* ═══════════════════════════════════════════════════════════════════
*
* Строк в кадре: 320 (0–319)
* Строки 0–31: вертикальное гашение
* Строки 32–319: видимая область (бордер + пиксели)
*
* Пикселей в строке: 448 (7 МГц), = 224 T-states при 3.5 МГц
* Пиксели 0–87: горизонтальное гашение
* Пиксели 88–447: видимая область
*
* T-states в кадре: 320 × 224 = 71680 T
*
* ══════════════════════════════════════════════════════════════════════
* ПРЕРЫВАНИЯ (IM2)
* ══════════════════════════════════════════════════════════════════════
*
* Три источника, каждый выставляет свой вектор на шину данных:
* FRAME (#FF, приоритет 0) — совпадение растровых счётчиков
* с регистрами HSINT/VSINT
* LINE (#FD, приоритет 1) — каждая строка при HCNT = 0
* DMA (#FB, приоритет 2) — конец DMA-транзакции
*
* HSINT = HCNT[8:1]: горизонтальная позиция (0–223). >223 = выкл.
* VSINTL/VSINTH = VCNT[8:0]: вертикальная строка (0–319). >319 = выкл.
*
* VINT_INC[3:0] в VSINTH: автоинкремент VCNT после каждого FRAME-INT
* (позволяет менять строку прерывания без записи в порты).
*
* ═══════════════════════════════════════════════════════════════════
* ВИДЕО
* ═══════════════════════════════════════════════════════════════════
*
* VM[1:0]: 00=ZX (256x192, атрибуты), 01=16c, 10=256c, 11=txt
* RRES[1:0]: 00=256x192, 01=320x200, 10=320x240, 11=360x288
*
* ═══════════════════════════════════════════════════════════════════
* DMA
* ═══════════════════════════════════════════════════════════════════
*
* Адрес = 22-бит: [X(8)][H(6)][L(7)][0] — младший бит всегда 0.
*
* ═══════════════════════════════════════════════════════════════════
* ПРИМЕР (минимальный)
* ═══════════════════════════════════════════════════════════════════
*
* #include "tsconf.h"
*
* void demo(void) {
* tsconf_set_cpu(TSCONF_CPU_14MHZ); // 14 МГц
* tsconf_set_border(2); // красный бордюр
* tsconf_set_vconfig(TSCONF_VM_ZX // ZX-режим
* | TSCONF_RRES_256x192); // 256x192
* tsconf_set_frame_int(100, 0); // INT на строке 100
* tsconf_set_intmask(TSCONF_INT_FRAME); // только FRAME
* tsconf_set_cpu(TSCONF_CPU_3_5MHZ); // вернуть 3.5
* }
*/
#ifndef TSCONF_H
#define TSCONF_H
#include "types.h"
/* ══════════════════════════════════════════════════════════════════════
* Макрос формирования адреса порта
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT(reg) (((uint16_t)(reg) << 8) | 0xAF)
/* ══════════════════════════════════════════════════════════════════════
* ВИДЕО — VConfig (#00AF)
* W: RRES[1:0] | - | NOGFX | NOTSU | GFXOVR* | FT_EN** | VM[1:0]
* R: - | PWR_UP | - | FDRVER | VDVER[2:0]
* * только VDAC, ** только VDAC2. Сброс: 0x00
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_VCONFIG TSCONF_PORT(0x00)
/* VM[1:0] — видеорежим */
#define TSCONF_VM_ZX 0x00 /* ZX-Spectrum, 256×192, атрибуты */
#define TSCONF_VM_16C 0x01 /* 16 цветов, 4 бита/пиксель */
#define TSCONF_VM_256C 0x02 /* 256 цветов, 8 бит/пиксель */
#define TSCONF_VM_TXT 0x03 /* Текстовый режим */
#define TSCONF_VM_MASK 0x03
/* FT_EN, GFXOVR, NOTSU, NOGFX */
#define TSCONF_VC_FT_EN 0x04 /* FT812 enable (VDAC2) */
#define TSCONF_VC_GFXOVR 0x08 /* GFX поверх TSU (VDAC) */
#define TSCONF_VC_NOTSU 0x10 /* Отключить TSU-графику */
#define TSCONF_VC_NOGFX 0x20 /* Отключить основную графику */
/* RRES[1:0] — разрешение экрана */
#define TSCONF_RRES_256x192 (0x00 << 6)
#define TSCONF_RRES_320x200 (0x01 << 6)
#define TSCONF_RRES_320x240 (0x02 << 6)
#define TSCONF_RRES_360x288 (0x03 << 6)
#define TSCONF_RRES_MASK (0x03 << 6)
/* R: Status (то же адрес #00AF, чтение) */
#define TSCONF_STATUS_VDVER_MASK 0x07
#define TSCONF_STATUS_FDRVER 0x10
#define TSCONF_STATUS_PWR_UP 0x40
#define TSCONF_VDVER_2BIT_PWM 0x00
#define TSCONF_VDVER_3BIT 0x01
#define TSCONF_VDVER_4BIT 0x02
#define TSCONF_VDVER_5BIT 0x03
#define TSCONF_VDVER_VDAC2 0x07
/* ── VPage (#01AF): адрес видеостраницы RA[21:14] ─────────────────── */
#define TSCONF_PORT_VPAGE TSCONF_PORT(0x01)
/* ── GXOffsL (#02AF), GXOffsH (#03AF): X-смещение графики ─────────── */
#define TSCONF_PORT_GXOFFSL TSCONF_PORT(0x02) /* XO[7:0] */
#define TSCONF_PORT_GXOFFSH TSCONF_PORT(0x03) /* бит 0 = XO[8] */
/* ── GYOffsL (#04AF), GYOffsH (#05AF): Y-смещение графики ─────────── */
#define TSCONF_PORT_GYOFFSL TSCONF_PORT(0x04) /* YO[7:0] */
#define TSCONF_PORT_GYOFFSH TSCONF_PORT(0x05) /* бит 0 = YO[8] */
/* ── TSConfig (#06AF): включение tile/sprite движка ────────────────── */
#define TSCONF_PORT_TSCONFIG TSCONF_PORT(0x06)
#define TSCONF_TS_EXT 0x01 /* TSU 360×288 (не ZX-Evo) */
#define TSCONF_T0Z_EN 0x04 /* Тайл [0] виден (плоск. 0) */
#define TSCONF_T1Z_EN 0x08 /* Тайл [0] виден (плоск. 1) */
#define TSCONF_T0_EN 0x20 /* Tile-layer 0 enable */
#define TSCONF_T1_EN 0x40 /* Tile-layer 1 enable */
#define TSCONF_S_EN 0x80 /* Sprite layers enable */
/* ── PalSel (#07AF): выбор палитр ──────────────────────────────────── */
/* GPAL[7:4] | T0PAL[7:6] | T1PAL[7:6]. Сброс = 0x0F */
#define TSCONF_PORT_PALSEL TSCONF_PORT(0x07)
/* ── Border (#0FAF): цвет бордюра ──────────────────────────────────── */
#define TSCONF_PORT_BORDER TSCONF_PORT(0x0F)
/* ══════════════════════════════════════════════════════════════════════
* УПРАВЛЕНИЕ ПАМЯТЬЮ
* ══════════════════════════════════════════════════════════════════════
* RA[21:14] — номер 16KB-страницы DRAM
* Page0 = W (write-only), Page1 = W, Page2 = RW, Page3 = RW
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_PAGE0 TSCONF_PORT(0x10) /* окно #0000, W */
#define TSCONF_PORT_PAGE1 TSCONF_PORT(0x11) /* окно #4000, W */
#define TSCONF_PORT_PAGE2 TSCONF_PORT(0x12) /* окно #8000, RW */
#define TSCONF_PORT_PAGE3 TSCONF_PORT(0x13) /* окно #C000, RW */
/* ── FMAddr (#14AF): адрес Font Maps ───────────────────────────────── */
#define TSCONF_PORT_FMADDR TSCONF_PORT(0x14)
#define TSCONF_FMADDR_EN 0x10 /* бит 4 = FM_EN. Биты 3:0 = A[15:12] */
/* ── TMPage (#15AF): страница TileMap ──────────────────────────────── */
#define TSCONF_PORT_TMPAGE TSCONF_PORT(0x15) /* RA[21:14] */
/* ── T0GPage (#16AF): страница графики тайлов плоскости 0 ──────────── */
#define TSCONF_PORT_T0GPAGE TSCONF_PORT(0x16) /* RA[21:17] */
/* ── T1GPage (#17AF): страница графики тайлов плоскости 1 ──────────── */
#define TSCONF_PORT_T1GPAGE TSCONF_PORT(0x17) /* RA[21:17] */
/* ── SGPage (#18AF): страница графики спрайтов ─────────────────────── */
#define TSCONF_PORT_SGPAGE TSCONF_PORT(0x18) /* RA[21:17] */
/* ══════════════════════════════════════════════════════════════════════
* DMA — адреса источника и назначения
* Адрес = 22-бит: [X(8)][H(6)][L(7)][0]
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_DMASADDRL TSCONF_PORT(0x19) /* Source RA[7:1] */
#define TSCONF_PORT_DMASADDRH TSCONF_PORT(0x1A) /* Source RA[13:8] */
#define TSCONF_PORT_DMASADDRX TSCONF_PORT(0x1B) /* Source RA[21:14] */
#define TSCONF_PORT_DMADADDRL TSCONF_PORT(0x1C) /* Dest RA[7:1] */
#define TSCONF_PORT_DMADADDRH TSCONF_PORT(0x1D) /* Dest RA[13:8] */
#define TSCONF_PORT_DMADADDRX TSCONF_PORT(0x1E) /* Dest RA[21:14] */
#define TSCONF_PORT_DMAWPDEV TSCONF_PORT(0x25) /* DMA Wait Port Dev */
#define TSCONF_PORT_DMALEN TSCONF_PORT(0x26) /* Burst Length [7:0] */
#define TSCONF_PORT_DMACTRL TSCONF_PORT(0x27) /* Ctrl W / Status R */
#define TSCONF_PORT_DMANUM TSCONF_PORT(0x28) /* Bursts Num [7:0] */
#define TSCONF_PORT_DMANUMH TSCONF_PORT(0x2C) /* Bursts Num [9:8] */
#define TSCONF_PORT_DMAWPADDR TSCONF_PORT(0x2D) /* Wait Port Addr */
/* DMACtrl W — DDEV[3:0]: режим DMA */
#define TSCONF_DMA_RAM_RAM 0x09 /* RAM→RAM copy */
#define TSCONF_DMA_BLT1_RAM 0x89 /* RAM→RAM, пропуск нулей (OPT=1) */
#define TSCONF_DMA_FILL 0x21 /* Fill: src → dest*N */
#define TSCONF_DMA_RAM_CRAM 0xA1 /* RAM→CRAM (палитра) */
#define TSCONF_DMA_SPI_RAM 0x11 /* SPI→RAM */
#define TSCONF_DMA_RAM_SPI 0x91 /* RAM→SPI */
#define TSCONF_DMA_IDE_RAM 0x19 /* IDE→RAM */
#define TSCONF_DMA_RAM_IDE 0x99 /* RAM→IDE */
#define TSCONF_DMA_FDD_RAM 0x29 /* FDD→RAM */
#define TSCONF_DMA_RAM_WTP 0xB9 /* RAM→Wait Port */
#define TSCONF_DMA_WTP_RAM 0x39 /* Wait Port→RAM */
#define TSCONF_DMA_BLT2_RAM 0x31 /* Блиттер с аддером */
/* DMACtrl — флаги */
#define TSCONF_DMA_ASZ_256 0x00 /* Выравнивание 256 байт */
#define TSCONF_DMA_ASZ_512 0x04 /* Выравнивание 512 байт */
#define TSCONF_DMA_D_ALGN 0x08 /* Выравнивание назначения */
#define TSCONF_DMA_S_ALGN 0x10 /* Выравнивание источника */
/* R: DMAStatus */
#define TSCONF_DMA_ACT 0x80 /* DMA активна */
/* DMAWPDev */
#define TSCONF_DMAWP_GLUCLOCK 0x00
#define TSCONF_DMAWP_COMPORT 0x01
/* ══════════════════════════════════════════════════════════════════════
* СИСТЕМНАЯ КОНФИГУРАЦИЯ
* ══════════════════════════════════════════════════════════════════════ */
/* ── SysConfig (#20AF): частота CPU и кэш ──────────────────────────── */
#define TSCONF_PORT_SYSCONFIG TSCONF_PORT(0x20)
#define TSCONF_CPU_3_5MHZ 0x00
#define TSCONF_CPU_7MHZ 0x01
#define TSCONF_CPU_14MHZ 0x02
#define TSCONF_CPU_MASK 0x03
#define TSCONF_CACHE_EN 0x04 /* Включить кэш (все 4 окна) */
/* ── MemConfig (#21AF) ────────────────────────────────────────────────
* ROM128: бит 0 = то же что бит 4 в #7FFD (BootROM/Basic)
* W0_WE: разрешить запись в окно #0000
* !W0_MAP: 0=маппинг через Page0, 1=стандартная страница 0
* W0_RAM: 0=ROM, 1=RAM в #0000
* LCK128: режим блокировки 128K-совместимости
* ──────────────────────────────────────────────────────────────────── */
#define TSCONF_PORT_MEMCONFIG TSCONF_PORT(0x21)
#define TSCONF_MEM_ROM128 0x01
#define TSCONF_MEM_W0_WE 0x02
#define TSCONF_MEM_W0_MAP_DIS 0x04
#define TSCONF_MEM_W0_RAM 0x08
#define TSCONF_MEM_LCK128_512K 0x00 /* 512K, биты 7:6 #7FFD=Page3[4:3] */
#define TSCONF_MEM_LCK128_128K 0x40 /* 128K, биты 7:6 #7FFD=00 */
#define TSCONF_MEM_LCK128_AUTO 0x80 /* Auto (!a[13]) */
#define TSCONF_MEM_LCK128_1M 0xC0 /* 1024K */
/* ══════════════════════════════════════════════════════════════════════
* ПРЕРЫВАНИЯ — позиция FRAME-INT
* ══════════════════════════════════════════════════════════════════════ */
/* ── HSINT (#22AF): горизонтальная позиция ─────────────────────────── */
/* HCNT[8:1] в диапазоне 0–223; >223 = выключить INT в этой строке */
#define TSCONF_PORT_HSINT TSCONF_PORT(0x22)
#define TSCONF_HSINT_OFF 0xFF
/* ── VSINTL (#23AF): вертикальная позиция [7:0] ────────────────────── */
/* VCNT[7:0]; строки 0–319; >319 = FRAME-INT выключен */
#define TSCONF_PORT_VSINTL TSCONF_PORT(0x23)
/* ── VSINTH (#24AF): вертикальная позиция [8] + автоинкремент ──────── */
/* Бит 0 = VCNT[8]; биты [7:4] = VINT_INC[3:0] */
/* VINT_INC: после каждого FRAME-INT → VCNT += VINT_INC (0 = нет) */
#define TSCONF_PORT_VSINTH TSCONF_PORT(0x24)
#define TSCONF_VSINTH_VCNT8 0x01
#define TSCONF_VSINTH_INC_MASK 0xF0
#define TSCONF_VSINTH_INC(n) (((n) & 0x0F) << 4)
/* ── INTMask (#2AAF): маска прерываний ─────────────────────────────── */
/* Сброс: 0x01 (только FRAME включён) */
#define TSCONF_PORT_INTMASK TSCONF_PORT(0x2A)
#define TSCONF_INT_FRAME 0x01
#define TSCONF_INT_LINE 0x02
#define TSCONF_INT_DMA 0x04
#define TSCONF_INT_WTP 0x08
/* Векторы IM2 (значение на шине данных при прерывании) */
#define TSCONF_IVEC_FRAME 0xFF
#define TSCONF_IVEC_LINE 0xFD
#define TSCONF_IVEC_DMA 0xFB
/* ══════════════════════════════════════════════════════════════════════
* КЭШ — CacheConfig (#2BAF)
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_CACHECONFIG TSCONF_PORT(0x2B)
#define TSCONF_CACHE_EN_0000 0x01
#define TSCONF_CACHE_EN_4000 0x02
#define TSCONF_CACHE_EN_8000 0x04
#define TSCONF_CACHE_EN_C000 0x08
#define TSCONF_CACHE_ALL 0x0F
#define TSCONF_CACHE_NONE 0x00
/* ══════════════════════════════════════════════════════════════════════
* FDD VIRTUAL DRIVE — FDDVirt (#29AF)
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_FDDVIRT TSCONF_PORT(0x29)
#define TSCONF_FDD_A 0x01
#define TSCONF_FDD_B 0x02
#define TSCONF_FDD_C 0x04
#define TSCONF_FDD_D 0x08
#define TSCONF_FDD_VG_OPEN 0x80
/* ══════════════════════════════════════════════════════════════════════
* ТАЙЛОВЫЕ ПЛОСКОСТИ — смещения
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_T0XOFFSL TSCONF_PORT(0x40)
#define TSCONF_PORT_T0XOFFSH TSCONF_PORT(0x41)
#define TSCONF_PORT_T0YOFFSL TSCONF_PORT(0x42)
#define TSCONF_PORT_T0YOFFSH TSCONF_PORT(0x43)
#define TSCONF_PORT_T1XOFFSL TSCONF_PORT(0x44)
#define TSCONF_PORT_T1XOFFSH TSCONF_PORT(0x45)
#define TSCONF_PORT_T1YOFFSL TSCONF_PORT(0x46)
#define TSCONF_PORT_T1YOFFSH TSCONF_PORT(0x47)
/* ══════════════════════════════════════════════════════════════════════
* HUS — Hurricane Sound Engine (#80AF–#87AF)
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_HUSCTRL TSCONF_PORT(0x80) /* W: управление */
#define TSCONF_PORT_HUSSAMPRATE TSCONF_PORT(0x81) /* W: SR[7:0] (1750k/(SR+1)) */
#define TSCONF_PORT_HUSTICKRATEL TSCONF_PORT(0x82) /* W: TR[7:0] */
#define TSCONF_PORT_HUSTICKRATEH TSCONF_PORT(0x83) /* W: TR[9:8] */
#define TSCONF_PORT_HUSRLD0 TSCONF_PORT(0x84) /* Reload ch 0–7 */
#define TSCONF_PORT_HUSRLD1 TSCONF_PORT(0x85) /* Reload ch 8–15 */
#define TSCONF_PORT_HUSRLD2 TSCONF_PORT(0x86)
#define TSCONF_PORT_HUSRLD3 TSCONF_PORT(0x87)
/* R: HUSStatus (#80AF) */
#define TSCONF_HUS_ACT 0x01
#define TSCONF_HUS_TICK 0x02 /* сбрасывается при чтении */
#define TSCONF_HUS_HALF 0x40 /* буфер наполовину пуст */
#define TSCONF_HUS_EMPTY 0x80
/* W: HUSControl */
#define TSCONF_HUS_PAUSE 0x02
#define TSCONF_HUS_RESET 0x80
/* ══════════════════════════════════════════════════════════════════════
* OPL3 (YMF262) — порты на шине TSConfig
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_OPL3_ADDR0 0x00C4
#define TSCONF_PORT_OPL3_DATA0 0x00C5
#define TSCONF_PORT_OPL3_ADDR1 0x00C6
#define TSCONF_PORT_OPL3_DATA1 0x00C7
/* ══════════════════════════════════════════════════════════════════════
* AY-3-8910 / YM2149 — стандартные порты ZX Spectrum 128
* ══════════════════════════════════════════════════════════════════════
* #FFFD — выбор регистра (W) / чтение данных (R)
* #BFFD — запись данных (W)
*
* TurboSound (два AY): запись в #FFFD значения #FF/#FE выбирает чип:
* #FF → чип 0 (первый AY); #FE → чип 1 (второй AY).
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_AY_ADDR 0xFFFD /* register select / read */
#define TSCONF_PORT_AY_DATA 0xBFFD /* data write */
#define TSCONF_AY_TS_CHIP0 0xFF /* TurboSound: select chip 0 */
#define TSCONF_AY_TS_CHIP1 0xFE /* TurboSound: select chip 1 */
/* ══════════════════════════════════════════════════════════════════════
* SAA1099 — порты SAM Coupé / ZX-совместимые
* ══════════════════════════════════════════════════════════════════════
* #01FF — выбор регистра (address write)
* #00FF — запись данных (data write)
* Второй SAA1099 (если есть):
* #01FE — выбор регистра
* #00FE — запись данных
* ══════════════════════════════════════════════════════════════════════ */
#define TSCONF_PORT_SAA_ADDR 0x01FF /* SAA1099 #1 address */
#define TSCONF_PORT_SAA_DATA 0x00FF /* SAA1099 #1 data */
#define TSCONF_PORT_SAA2_ADDR 0x01FE /* SAA1099 #2 address */
#define TSCONF_PORT_SAA2_DATA 0x00FE /* SAA1099 #2 data */
/* ══════════════════════════════════════════════════════════════════════
* WC СИСТЕМНЫЕ ПЕРЕМЕННЫЕ — адреса в ROM-области ядра WC
* ══════════════════════════════════════════════════════════════════════ */
#define WC_ADDR_PAGES 0x6000 /* [3 байта] страницы #0000,#4000,#8000 */
#define WC_ADDR_ABT 0x6004 /* флаг ESC */
#define WC_ADDR_ENT 0x6005 /* флаг ENTER */
#define WC_ADDR_TMN 0x6009 /* таймер (инкр. по INT), uint16 */
#define WC_ADDR_CNFV 0x600D /* версия конфигурации */
#define WC_ADDR_HEI 0x600E /* высота экрана (25/30/36 строк) */
#define WC_CNFV_PWM 0x00
#define WC_CNFV_3BIT 0x01
#define WC_CNFV_4BIT 0x02
#define WC_CNFV_5BIT 0x03
#define WC_CNFV_VDAC2 0x07
/* ══════════════════════════════════════════════════════════════════════
* SFR — прямой доступ к портам из SDCC-C
* ══════════════════════════════════════════════════════════════════════
*
* __sfr __at 0xNN — 8-bit port: out (N), a / in a, (N)
* __sfr __banked __at 0xNNNN — 16-bit port: ld bc,#NNNN; out (c),a
*
* Не создают переменных/символов — чисто compile-time mapping.
* Присваивание sfr_xxx = val; генерирует inline OUT.
* Чтение val = sfr_xxx; генерирует inline IN.
* ══════════════════════════════════════════════════════════════════════ */
/* --- Стандартный ZX Spectrum: 8-bit порт ----------------------------- */
__sfr __at 0xFE sfr_zx_fe; /* border / keyboard */
/* --- TSConfig регистры (addr = reg<<8 | 0xAF) ----------------------- */
__sfr __banked __at 0x00AF sfr_vconfig; /* VConfig */
__sfr __banked __at 0x01AF sfr_vpage; /* VPage */
__sfr __banked __at 0x02AF sfr_gxoffsl; /* GXOffsL */
__sfr __banked __at 0x03AF sfr_gxoffsh; /* GXOffsH */
__sfr __banked __at 0x04AF sfr_gyoffsl; /* GYOffsL */
__sfr __banked __at 0x05AF sfr_gyoffsh; /* GYOffsH */
__sfr __banked __at 0x06AF sfr_tsconfig; /* TSConfig */
__sfr __banked __at 0x07AF sfr_palsel; /* PalSel */
__sfr __banked __at 0x0FAF sfr_border; /* Border Color */
__sfr __banked __at 0x10AF sfr_page0; /* Page0 (#0000) */
__sfr __banked __at 0x11AF sfr_page1; /* Page1 (#4000) */
__sfr __banked __at 0x12AF sfr_page2; /* Page2 (#8000) */
__sfr __banked __at 0x13AF sfr_page3; /* Page3 (#C000) */
__sfr __banked __at 0x14AF sfr_fmaddr; /* FMAddr */
__sfr __banked __at 0x15AF sfr_tmpage; /* TMPage */
__sfr __banked __at 0x16AF sfr_t0gpage; /* T0GPage */
__sfr __banked __at 0x17AF sfr_t1gpage; /* T1GPage */
__sfr __banked __at 0x18AF sfr_sgpage; /* SGPage */
__sfr __banked __at 0x20AF sfr_sysconfig; /* SysConfig (CPU) */
__sfr __banked __at 0x21AF sfr_memconfig; /* MemConfig */
__sfr __banked __at 0x22AF sfr_hsint; /* HSINT */
__sfr __banked __at 0x23AF sfr_vsintl; /* VSINTL */
__sfr __banked __at 0x24AF sfr_vsinth; /* VSINTH */
__sfr __banked __at 0x2AAF sfr_intmask; /* INTMask */
__sfr __banked __at 0x2BAF sfr_cacheconfig; /* CacheConfig */
__sfr __banked __at 0x29AF sfr_fddvirt; /* FDDVirt */
/* --- DMA --- */
__sfr __banked __at 0x1AAF sfr_dmasaddrh; /* DMA Src Addr H */
__sfr __banked __at 0x1BAF sfr_dmasaddrx; /* DMA Src Addr X */
__sfr __banked __at 0x19AF sfr_dmasaddrl; /* DMA Src Addr L */
__sfr __banked __at 0x1CAF sfr_dmadaddrl; /* DMA Dst Addr L */
__sfr __banked __at 0x1DAF sfr_dmadaddrh; /* DMA Dst Addr H */
__sfr __banked __at 0x1EAF sfr_dmadaddrx; /* DMA Dst Addr X */
__sfr __banked __at 0x26AF sfr_dmalen; /* DMA Burst Length */
__sfr __banked __at 0x27AF sfr_dmactrl; /* DMA Ctrl / Status */
__sfr __banked __at 0x28AF sfr_dmanum; /* DMA Bursts Num L */
__sfr __banked __at 0x2CAF sfr_dmanumh; /* DMA Bursts Num H */
/* --- OPL3 (YMF262) --- */
__sfr __banked __at 0x00C4 sfr_opl3_addr0; /* Bank0 address */
__sfr __banked __at 0x00C5 sfr_opl3_data0; /* Bank0 data */
__sfr __banked __at 0x00C6 sfr_opl3_addr1; /* Bank1 address */
__sfr __banked __at 0x00C7 sfr_opl3_data1; /* Bank1 data */
/* --- AY-3-8910 / YM2149 --- */
__sfr __banked __at 0xFFFD sfr_ay_addr; /* reg select / read */
__sfr __banked __at 0xBFFD sfr_ay_data; /* data write */
/* --- SAA1099 --- */
__sfr __banked __at 0x01FF sfr_saa_addr; /* SAA1099 #1 address */
__sfr __banked __at 0x00FF sfr_saa_data; /* SAA1099 #1 data */
__sfr __banked __at 0x01FE sfr_saa2_addr; /* SAA1099 #2 address */
__sfr __banked __at 0x00FE sfr_saa2_data; /* SAA1099 #2 data */
/* ══════════════════════════════════════════════════════════════════════
* ФУНКЦИИ — обёртки
* ══════════════════════════════════════════════════════════════════════ */
/** Запись значения в произвольный TSConfig-порт (asm, для динамических адресов)
* @param port TSCONF_PORT(reg)
* @param val значение */
extern void tsconf_out(uint16_t port, uint8_t val);
/* ── Удобные макросы (через __sfr — inline, без call) ────────────────── */
/** Установить скорость CPU (TSCONF_CPU_3_5MHZ / 7MHZ / 14MHZ) */
#define tsconf_set_cpu(speed) \
(sfr_sysconfig = (uint8_t)((speed) & TSCONF_CPU_MASK))
/** Установить скорость CPU с управлением кэшем */
#define tsconf_set_cpu_cache(speed, cache_en) \
(sfr_sysconfig = (uint8_t)(((speed) & TSCONF_CPU_MASK) | ((cache_en) ? TSCONF_CACHE_EN : 0)))
/** Установить маску прерываний (OR нужных TSCONF_INT_*) */
#define tsconf_set_intmask(mask) \
(sfr_intmask = (uint8_t)(mask))
/** Настроить позицию FRAME-INT: line=0–319, hpos=0–223 */
#define tsconf_set_frame_int(line, hpos) do { \
sfr_vsinth = (uint8_t)(((line) >> 8) & 0x01); \
sfr_vsintl = (uint8_t)((line) & 0xFF); \
sfr_hsint = (uint8_t)(hpos); \
} while(0)
/** Выключить FRAME-INT полностью */
#define tsconf_disable_frame_int() \
(sfr_hsint = TSCONF_HSINT_OFF)
/** Настроить кэш по окнам: маска из TSCONF_CACHE_EN_* */
#define tsconf_set_cache(mask) \
(sfr_cacheconfig = (uint8_t)(mask))
/** Установить цвет бордюра (TSConfig-регистр) */
#define tsconf_set_border(color) \
(sfr_border = (uint8_t)(color))
/** Подключить видеостраницу (номер 0–63) на адрес #C000 */
#define tsconf_set_vpage(page) \
(sfr_vpage = (uint8_t)(page))
/** Установить видеорежим (OR из TSCONF_VM_*, TSCONF_RRES_*, TSCONF_VC_*) */
#define tsconf_set_vconfig(cfg) \
(sfr_vconfig = (uint8_t)(cfg))
/** Подключить RAM-страницу page на окно #C000 (Page3) */
#define tsconf_set_page3(page) \
(sfr_page3 = (uint8_t)(page))
/** Подключить RAM-страницу page на окно #8000 (Page2) */
#define tsconf_set_page2(page) \
(sfr_page2 = (uint8_t)(page))
#endif /* TSCONF_H */