# TSConfig Platform Reference > Источники: `inc/tsconf.h` (532 стр.), `inc/wc_api.h` (системные константы), > [TSConfig Wiki](https://github.com/tslabs/zx-evo) ## Обзор платформы TS-Configuration (TSConfig) — расширенная конфигурация на базе **ZX Evolution** (Большой Спектрум / ZX Evo), реализованная в FPGA (Altera/Xilinx). | Параметр | Значение | |-----------|----------| | CPU | Z80 @ 3.5 / 7 / 14 / 28 МГц | | RAM | до 4096 КБ (256 страниц × 16 КБ) | | ROM | до 512 КБ (32 страницы) | | Видео | до 360×288, 256 цветов, TXT 80/90 столбцов | | Спрайты | До 85 на строку, 8×8–64×64, 3 плоскости | | Тайлы | 2 плоскости, 8×8 | | DMA | Аппаратный контроллер (RAM↔RAM, RAM↔SPI/IDE, FILL, CRAM, SFILE) | | Кэш | 512 байт, по-оконно | | Звук | AY-3-8910 (TurboSound: 2 чипа), OPL3 (YMF262), SAA1099 ×2, HUS | | Хранилище | SD (Z-Controller, NeoGS), IDE (NEMO, SMUC), FAT32 | | Совместимость | Pentagon-128/512/1024, порт #7FFD | ## Память ### Страничная адресация Процессор Z80 адресует 64 КБ памяти, разделенные на 4 окна по 16 КБ: | Окно | Адреса CPU | Регистр страницы | R/W | Reset | |------|------------|------------------|-----|-------| | 0 | #0000..#3FFF | Page0 | W | #00 | | 1 | #4000..#7FFF | Page1 | W | #05 | | 2 | #8000..#BFFF | Page2 | R/W | #02 | | 3 | #C000..#FFFF | Page3 | R/W | #00 | **Доступно:** - RAM: до 4096 КБ (256 страниц по 16 КБ) - ROM: до 512 КБ (32 страницы по 16 КБ) ### Регистры управления памятью Доступ к регистрам через порты **#nnAF**, где nn - номер регистра. #### MemConfig (регистр #07) ``` Биты: 7:6 - LCK128[1:0] - режим порта #7FFD 5:4 - резерв 3 - W0_RAM - выбор ROM/RAM в окне 0 2 - !W0_MAP - режим маппинга окна 0 1 - W0_WE - разрешение записи в окно 0 0 - ROM128 - выбор страниц маппинга ``` #### Page0..3 (регистры #10-#13) 8-битные регистры, содержащие номер страницы для соответствующего окна. ## Порты ввода-вывода ### Схема адресации портов TSConfig использует порты с адресом **#nnAF**, где: - Младшие 8 бит (A0-A7) = #AF - Старшие 8 бит (A8-A15) = номер регистра (nn) ### Базовые регистры TSConfig > Источник: `src_sdcc/inc/tsconf.h` — `#define TSCONF_PORT(reg) (((uint16_t)(reg) << 8) | 0xAF)` | Порт | Константа | R/W | Описание | |---------|----------------------------|-----|-------------------------------------| | `#00AF` | `TSCONF_PORT_VCONFIG` | RW | VConfig: видеорежим (VM, RRES) | | `#01AF` | `TSCONF_PORT_VPAGE` | W | VPage: страница видеобуфера | | `#02AF` | `TSCONF_PORT_GXOFFSL` | W | GFX X offset (low) | | `#03AF` | `TSCONF_PORT_GXOFFSH` | W | GFX X offset (high) | | `#04AF` | `TSCONF_PORT_GYOFFSL` | W | GFX Y offset (low) | | `#05AF` | `TSCONF_PORT_GYOFFSH` | W | GFX Y offset (high) | | `#06AF` | `TSCONF_PORT_TSCONFIG` | W | TSConfig: tile/sprite engine | | `#07AF` | `TSCONF_PORT_PALSEL` | W | PalSel: выбор палитры | | `#0FAF` | `TSCONF_PORT_BORDER` | W | Border: цвет бордюра (биты 2:0) | | `#10AF` | `TSCONF_PORT_PAGE0` | **W** | **Page0: страница окна #0000** | | `#11AF` | `TSCONF_PORT_PAGE1` | **W** | **Page1: страница окна #4000** | | `#12AF` | `TSCONF_PORT_PAGE2` | **RW** | **Page2: страница окна #8000** | | `#13AF` | `TSCONF_PORT_PAGE3` | **RW** | **Page3: страница окна #C000** | | `#14AF` | `TSCONF_PORT_FMADDR` | W | Font Maps | | `#15AF` | `TSCONF_PORT_TMPAGE` | W | TileMap page | | `#16AF` | `TSCONF_PORT_T0GPAGE` | W | Tile plane 0 gfx page | | `#17AF` | `TSCONF_PORT_T1GPAGE` | W | Tile plane 1 gfx page | | `#18AF` | `TSCONF_PORT_SGPAGE` | W | Sprite gfx page | | `#20AF` | `TSCONF_PORT_SYSCONFIG` | W | **SysConfig: CPU freq + кэш** | | `#21AF` | `TSCONF_PORT_MEMCONFIG` | W | MemConfig: режим памяти | | `#22AF` | `TSCONF_PORT_HSINT` | W | FRAME-INT: горизонт. позиция | | `#23AF` | `TSCONF_PORT_VSINTL` | W | FRAME-INT: вертик. позиция (low) | | `#24AF` | `TSCONF_PORT_VSINTH` | W | FRAME-INT: вертик. позиция (high) + auto-inc | | `#29AF` | `TSCONF_PORT_FDDVIRT` | W | FDD виртуализация | | `#2AAF` | `TSCONF_PORT_INTMASK` | W | **INTMask: маска прерываний** | | `#2BAF` | `TSCONF_PORT_CACHECONFIG` | W | **CacheConfig: кэш по окнам** | #### Порты тайловых смещений | Порт | Описание | |------|----------| | `#40AF`/`#41AF` | Tile plane 0: X offset (lo/hi) | | `#42AF`/`#43AF` | Tile plane 0: Y offset (lo/hi) | | `#44AF`/`#45AF` | Tile plane 1: X offset (lo/hi) | | `#46AF`/`#47AF` | Tile plane 1: Y offset (lo/hi) | #### Порты DMA | Порт | Константа | Описание | |------|-----------|----------| | `#19AF` | `TSCONF_PORT_DMASADDRL` | Source addr low | | `#1AAF` | `TSCONF_PORT_DMASADDRH` | Source addr high | | `#1BAF` | `TSCONF_PORT_DMASADDRX` | Source page (extended) | | `#1CAF` | `TSCONF_PORT_DMADADDRL` | Dest addr low | | `#1DAF` | `TSCONF_PORT_DMADADDRH` | Dest addr high | | `#1EAF` | `TSCONF_PORT_DMADADDRX` | Dest page (extended) | | `#25AF` | `TSCONF_PORT_DMAWPDEV` | Wait Port device | | `#26AF` | `TSCONF_PORT_DMALEN` | Burst length | | `#27AF` | `TSCONF_PORT_DMACTRL` | Control (W) / Status (R) | | `#28AF` | `TSCONF_PORT_DMANUM` | Bursts num (low) | | `#2CAF` | `TSCONF_PORT_DMANUMH` | Bursts num (high) | | `#2DAF` | `TSCONF_PORT_DMAWPADDR` | Wait Port addr | > ⚠️ **Частая ошибка:** Page0–Page3 = `#10AF`–`#13AF`, SysConfig = `#20AF`. > Не путать с VConfig (`#00AF`) или VPage (`#01AF`)! ### Порты OPL3 — YMF262 **OPL3 чип располагается по портам #C4–#C7:** | Порт | Константа | Назначение | |-------|-----------|------------| | `#C4` | `TSCONF_PORT_OPL3_ADDR0` | Bank 0: регистр адреса | | `#C5` | `TSCONF_PORT_OPL3_DATA0` | Bank 0: данные | | `#C6` | `TSCONF_PORT_OPL3_ADDR1` | Bank 1: регистр адреса | | `#C7` | `TSCONF_PORT_OPL3_DATA1` | Bank 1: данные | **Регистр NEW (Bank 1, reg 0x05):** - `NEW=1` (0x01) → OPL3 mode: биты L/R в регистрах `C0–C8` управляют маршрутизацией звука - `NEW=0` (0x00) → OPL2-compat: L+R всегда активны (обязательно для файлов OPL2/OPL1!) ```c // inc/opl3.h void opl3_write_b0(uint8_t reg, uint8_t data); // Bank 0 (#C4/#C5) void opl3_write_b1(uint8_t reg, uint8_t data); // Bank 1 (#C6/#C7) void opl3_init(void); // сброс + NEW=1 // Для OPL2/OPL1 VGM: после opl3_init() нужно: opl3_write_b1(0x05, 0x00); // NEW=0 — иначе тишина! ``` ### Порты AY-3-8910 / YM2149 | Порт | Константа | Назначение | |---------|-----------|------------| | `#FFFD` | `TSCONF_PORT_AY_ADDR` | Регистр адреса / чтение (`OUT/IN`) | | `#BFFD` | `TSCONF_PORT_AY_DATA` | Запись данных | **TurboSound (два AY):** второй чип выбирается через порт `#FFFD`: - `OUT (#FFFD), #FF` (= `TSCONF_AY_TS_CHIP0`) → чип 0 (основной) - `OUT (#FFFD), #FE` (= `TSCONF_AY_TS_CHIP1`) → чип 1 **Частоты AY** (управление через `wc_turbopl(WC_TURBO_AY, param)`): | param | Частота | Примечание | |-------|---------|------------| | 0 | 1,750,000 Гц | Стандарт TSConfig / Pentagon | | 1 | 1,773,400 Гц | NTSC-кварц (315/88 МГц ÷ 2) | | 2 | 3,500,000 Гц | Удвоенная | | 3 | 3,546,800 Гц | Удвоенная NTSC | ### Порты SAA1099 — MultiSound card | Чип | Данные | Адрес | Константы | |------|--------|-------|-----------| | SAA1 | `#00FF` | `#01FF` | `TSCONF_PORT_SAA_DATA/ADDR` | | SAA2 | `#00FE` | `#01FE` | `TSCONF_PORT_SAA2_DATA/ADDR` | > Некоторые источники указывают SAA2 по портам `#02FF`/`#03FF` — это > зависит от реализации MultiSound платы. В `tsconf.h` используются > `#00FE`/`#01FE`. **Пример записи в регистр OPL3:** ```asm ; Запись в регистр банка 0 LD BC,#C4 ; Порт адреса LD A,reg ; Номер регистра OUT (C),A LD B,#C5 ; Порт данных LD A,value ; Значение OUT (C),A ; Запись в регистр банка 1 LD BC,#C6 ; Порт адреса банка 1 LD A,reg ; Номер регистра OUT (C),A LD B,#C7 ; Порт данных банка 1 LD A,value ; Значение OUT (C),A ``` ## Процессор ### Частоты CPU | Режим | Частота | SysConfig [1:0] | Константа | |--------|---------|-----------------|----------| | 00 | 3.5 МГц | `00` | `TSCONF_CPU_3_5MHZ` | | 01 | 7.0 МГц | `01` | `TSCONF_CPU_7MHZ` | | 10 | 14.0 МГц | `10` | `TSCONF_CPU_14MHZ` | | 11 | 28.0 МГц | `11` | (non-standard, не все FPGA) | > В WC API `wc_turbopl(WC_TURBO_CPU, param)` поддерживает > param 0–3 (3.5/7/14/28 МГц). Управление через регистр **SysConfig #20AF** (биты 1:0): ```c // tsconf.h #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 // бит 2 — глобальный кэш // Convenience macros: tsconf_set_cpu(TSCONF_CPU_14MHZ); // только CPU tsconf_set_cpu_cache(TSCONF_CPU_14MHZ, TSCONF_CACHE_EN); // CPU + кэш ``` ### Кэш 512 байт кэш-памяти для ускорения работы на 14/28 МГц. **Глобально:** бит 2 регистра **SysConfig** (`TSCONF_CACHE_EN`). **По-оконно:** регистр **CacheConfig #2BAF**: | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_CACHE_EN_0000` | 0x01 | Кэш для #0000–#3FFF | | `TSCONF_CACHE_EN_4000` | 0x02 | Кэш для #4000–#7FFF | | `TSCONF_CACHE_EN_8000` | 0x04 | Кэш для #8000–#BFFF | | `TSCONF_CACHE_EN_C000` | 0x08 | Кэш для #C000–#FFFF | | `TSCONF_CACHE_ALL` | 0x0F | Все окна | | `TSCONF_CACHE_NONE` | 0x00 | Кэш выключен | ```c tsconf_set_cache(TSCONF_CACHE_EN_8000 | TSCONF_CACHE_EN_C000); ``` **Важно:** После DMA операций необходима **инвалидация кэша**: ```asm ; Инвалидация: 512 байт LDIR на себя LD HL,#FE00 LD DE,#FE00 LD BC,#0200 LDIR ``` ## Прерывания ### Источники прерываний TSConfig поддерживает несколько источников INT: | Источник | Бит | IM2 вектор | Константа | |----------|-----|------------|-----------| | FRAME | 0 | `#FF` (`TSCONF_IVEC_FRAME`) | `TSCONF_INT_FRAME` | | LINE | 1 | `#FD` (`TSCONF_IVEC_LINE`) | `TSCONF_INT_LINE` | | DMA | 2 | `#FB` (`TSCONF_IVEC_DMA`) | `TSCONF_INT_DMA` | | WTP | 3 | — | `TSCONF_INT_WTP` | ### Регистр маски прерываний (INTMask #2AAF) ``` Биты: 3 - WTP (Wait Port) interrupt enable 2 - DMA interrupt enable 1 - LINE interrupt enable 0 - FRAME interrupt enable Reset: #01 (только FRAME включен) ``` ```c tsconf_set_intmask(TSCONF_INT_FRAME | TSCONF_INT_LINE); ``` ### Позиционирование FRAME-INT ```c // Задать вертикальную строку и горизонтальную позицию tsconf_set_frame_int(vline, hpos); // Отключить tsconf_disable_frame_int(); // Авто-инкремент VCNT (для множественных INT в кадре): // VSINTH[7:4] = auto-increment value #define TSCONF_VSINTH_INC(n) ((n) << 4) ``` --- ## MemConfig (#21AF) — Конфигурация памяти | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_MEM_ROM128` | 0x01 | Выбор банка ROM (= бит 4 порта #7FFD) | | `TSCONF_MEM_W0_WE` | 0x02 | Разрешить запись в окно #0000 | | `TSCONF_MEM_W0_MAP_DIS` | 0x04 | Отключить маппинг через Page0 | | `TSCONF_MEM_W0_RAM` | 0x08 | RAM вместо ROM в окне #0000 | | `TSCONF_MEM_LCK128_512K` | 0x00 | Pentagon-512 режим | | `TSCONF_MEM_LCK128_128K` | 0x40 | Pentagon-128 режим | | `TSCONF_MEM_LCK128_AUTO` | 0x80 | Авто-определение | | `TSCONF_MEM_LCK128_1M` | 0xC0 | Расширенный 1 МБ | --- ## TSU — Tile/Sprite Engine (#06AF) | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_TS_EXT` | 0x01 | TSU 360×288 (extended) | | `TSCONF_T0Z_EN` | 0x04 | Tile[0] visible (plane 0) | | `TSCONF_T1Z_EN` | 0x08 | Tile[0] visible (plane 1) | | `TSCONF_T0_EN` | 0x20 | Tile layer 0 enable | | `TSCONF_T1_EN` | 0x40 | Tile layer 1 enable | | `TSCONF_S_EN` | 0x80 | Sprite layers enable | --- ## HUS — Hurricane Sound Engine > Порты `#80AF`–`#87AF` (есть не на всех FPGA-прошивках) HUS — аппаратный звуковой движок TSConfig для воспроизведения PCM-сэмплов из RAM с DMA. | Порт | Константа | Описание | |------|-----------|----------| | `#80AF` | `TSCONF_PORT_HUSCTRL` | Control (W) / Status (R) | | `#81AF` | `TSCONF_PORT_HUSSAMPRATE` | Sample Rate: 1,750,000 / (SR+1) | | `#82AF` | `TSCONF_PORT_HUSTICKRATEL` | Tick Rate (low) | | `#83AF` | `TSCONF_PORT_HUSTICKRATEH` | Tick Rate (high) | | `#84AF`–`#87AF` | `TSCONF_PORT_HUSRLD0`–`3` | Reload ch 0–31 | **Биты статуса (чтение #80AF):** | Константа | Бит | Описание | |-----------|-----|----------| | `TSCONF_HUS_ACT` | 0 | 1 = HUS активен | | `TSCONF_HUS_TICK` | 1 | 1 = tick event | | `TSCONF_HUS_HALF` | 6 | 1 = полбуфера | | `TSCONF_HUS_EMPTY` | 7 | 1 = буфер пуст | **Управление (запись #80AF):** | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_HUS_PAUSE` | 0x02 | Пауза воспроизведения | | `TSCONF_HUS_RESET` | 0x80 | Сброс HUS | ### ISR плагина — собственный таймер Плагин может зарегистрировать собственный ISR через `wc_int_pl(WC_INT_PLUGIN)` + `wc_int_pl_handler(addr)`. В VGM-плеере ISR настраивается через **перехват** вектора IM2 (FRAME INT, вектор `#5BFF`) с высокой частотой вызова. POS_TABLE задаёт позиции INT-триггеров в кадре: | Вариант | ISR_FREQ | T-states/тик | Тиков/кадр | VGM_SAMPLE_SHIFT | Семплов/тик | |---------|----------|-------------|------------|------------------|---------| | Quarter | **683 Гц** | 5120 T | 14 | 6 (44100/64) | 64 | | Half | 1367 Гц | 2560 T | 28 | 5 (44100/32) | 32 | | Full | 2734 Гц | 1280 T | 56 | 4 (44100/16) | 16 | Конфигурация варианта хранится в `inc/variant_cfg.h`: ```c // variant_cfg.h (текущий вариант) #define ISR_FREQ 683 #define ISR_TICKS_PER_FRAME 14 // 683/50≈14 #define VGM_SAMPLE_SHIFT 6 // 44100 >> 6 = 689 ≈ 683 #define VGM_SAMPLE_MASK 0x3Fu #define VGM_FILL_CMD_BUDGET 32 // команд за один yield #define VARIANT_POS_ENTRIES 14 // записей в pos_table #define VARIANT_POS_STEP 5120 // T-states между INT ``` ### Механизм pos_table `pos_table` — кольцевой буфер позиций INT в кадре. Каждая запись: 5 байт `[VSINTH, VSINTL, HSINT, next_ptr_lo, next_ptr_hi]`. ISR выводит 3 байта через OUTI (порты VSINTH/VSINTL/HSINT), затем переходит по next_ptr к следующей записи. Генерируется скриптом `scripts/gen_pos_table.js`. ### Частота прерываний TSConfig (FRAME) - FRAME: зависит от видео режима - 50 Гц (312 строк PAL) - 60 Гц (262 строки NTSC) - ~48.8 Гц (320 строк Pentagon) ## DMA Контроллер TSConfig имеет аппаратный DMA для быстрого копирования/заполнения данных. ### Режимы DMA (регистр DMACTRL #27AF) | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_DMA_RAM_RAM` | 0x09 | RAM → RAM копирование | | `TSCONF_DMA_BLT1_RAM` | 0x89 | RAM → RAM с пропуском нулей (transparency) | | `TSCONF_DMA_BLT2_RAM` | 0x31 | Blitter с aдером | | `TSCONF_DMA_FILL` | 0x21 | Заполнение RAM | | `TSCONF_DMA_RAM_CRAM` | 0xA1 | RAM → CRAM (палитра, RGB555) | | `TSCONF_DMA_RAM_SFILE` | — | RAM → Sprite File | | `TSCONF_DMA_SPI_RAM` | 0x11 | SPI → RAM (чтение SD) | | `TSCONF_DMA_RAM_SPI` | 0x91 | RAM → SPI (запись SD) | | `TSCONF_DMA_IDE_RAM` | 0x19 | IDE → RAM | | `TSCONF_DMA_RAM_IDE` | 0x99 | RAM → IDE | | `TSCONF_DMA_FDD_RAM` | 0x29 | FDD → RAM | | `TSCONF_DMA_RAM_WTP` | 0xB9 | RAM → Wait Port | | `TSCONF_DMA_WTP_RAM` | 0x39 | Wait Port → RAM | ### Флаги DMA | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_DMA_ASZ_256` | 0x00 | Выравнивание 256 байт | | `TSCONF_DMA_ASZ_512` | 0x04 | Выравнивание 512 байт | | `TSCONF_DMA_D_ALGN` | 0x08 | Выравнивание приёмника | | `TSCONF_DMA_S_ALGN` | 0x10 | Выравнивание источника | | `TSCONF_DMA_ACT` | 0x80 | DMA active (бит статуса при чтении) | ### Wait Port Device (#25AF) | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_DMAWP_GLUCLOCK` | 0x00 | GluClock | | `TSCONF_DMAWP_COMPORT` | 0x01 | COM-порт | ### Основные регистры DMA > Порты DMA описаны выше в таблице портов. Основные: | Регистр | Порт | Описание | |---------|------|----------| | DMA_SAL/H/X | `#19AF`/`#1AAF`/`#1BAF` | Адрес + страница источника | | DMA_DAL/H/X | `#1CAF`/`#1DAF`/`#1EAF` | Адрес + страница приёмника | | DMA_LEN | `#26AF` | Размер бёрста (N) | | DMA_NUM/H | `#28AF`/`#2CAF` | Количество бёрстов (T) | | DMA_CTRL | `#27AF` | Режим + запуск (W) / статус (R) | ### Пример DMA через WC API (C) ```c // Копирование 4 КБ из стр. 0 плагина (#8000) в стр. 1 (#8000) wc_dmapl(WC_DMA_INIT_SD); // потребует B,C,HL,DE в регистрах wc_dmapl(WC_DMA_SET_TN); // B=бёрсты, C=размер бёрста wc_dmapl(WC_DMA_RUN_RAM); // запуск RAM→RAM с ожиданием ``` --- ## Использование портов из SDCC `tsconf.h` объявляет все порты как `__sfr __banked` переменные для прямого ввода/вывода без `__asm`: ```c // Примеры: sfr_page2 = 5; // OUT (#12AF), 5 sfr_sysconfig = TSCONF_CPU_14MHZ; // OUT (#20AF), 2 sfr_border = 2; // OUT (#0FAF), 2 sfr_opl3_addr0 = 0x20; // OUT (#00C4), 0x20 sfr_opl3_data0 = 0xFF; // OUT (#00C5), 0xFF // Чтение: uint8_t page = sfr_page2; // IN A,(#12AF) ``` Полный список: `sfr_vconfig`, `sfr_vpage`, `sfr_gxoffsl/h`, `sfr_gyoffsl/h`, `sfr_tsconfig`, `sfr_palsel`, `sfr_border`, `sfr_page0`–`sfr_page3`, `sfr_sysconfig`, `sfr_memconfig`, `sfr_intmask`, `sfr_cacheconfig`, `sfr_dmasaddrh/l/x`, `sfr_dmadaddrh/l/x`, `sfr_dmalen`, `sfr_dmactrl`, `sfr_dmanum/h`, `sfr_opl3_addr0/data0/addr1/data1`, `sfr_ay_addr/data`, `sfr_saa_addr/data`, `sfr_saa2_addr/data`. ## Видео система ### Видео режимы (VConfig #00AF) | Режим | Константа | Разрешения | Цвета | |-------|-----------|------------|-------| | ZX | `TSCONF_VM_ZX` (0x00) | 256×192 | 16 (атрибуты) | | 16c | `TSCONF_VM_16C` (0x01) | 256..360 | 16 (4 bpp) | | 256c | `TSCONF_VM_256C` (0x02) | 256..360 | 256 (8 bpp) | | TXT | `TSCONF_VM_TXT` (0x03) | 80×25, 80×30, 90×36 | 256 | **Разрешения:** | Константа | Значение | Пиксели | |-----------|----------|---------| | `TSCONF_RRES_256x192` | 0x00 | 256×192 | | `TSCONF_RRES_320x200` | 0x40 | 320×200 | | `TSCONF_RRES_320x240` | 0x80 | 320×240 | | `TSCONF_RRES_360x288` | 0xC0 | 360×288 | **Прочие биты VConfig:** | Константа | Бит | Описание | |-----------|-----|----------| | `TSCONF_VC_FT_EN` | 2 | FT812 enable (VDAC2) | | `TSCONF_VC_GFXOVR` | 3 | GFX over TSU | | `TSCONF_VC_NOTSU` | 4 | Отключить TSU graphics | | `TSCONF_VC_NOGFX` | 5 | Отключить main graphics | **Чтение VConfig (статус):** | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_VDVER_2BIT_PWM` | 0x00 | 2-бит ЦАП (ШИМ) | | `TSCONF_VDVER_3BIT` | 0x01 | 3-бит | | `TSCONF_VDVER_4BIT` | 0x02 | 4-бит | | `TSCONF_VDVER_5BIT` | 0x03 | 5-бит | | `TSCONF_VDVER_VDAC2` | 0x07 | VDAC2 / FT812 | | `TSCONF_STATUS_PWR_UP` | 0x40 | Після включення | ### Палитра 256 ячеек палитры, формат RGB555 (15 бит цвета). ### Спрайты - До 85 спрайтов на строку - Размеры: 8x8 до 64x64 пикселей - До 3 плоскостей спрайтов - До 16 палитр на строку ## Совместимость с Pentagon-128 ### Порт #7FFD ``` Биты: 7:6 - дополнительные биты страницы (512K/1024K) 5 - LOCK (блокировка переключения) 4 - ROM128 (выбор ROM) 3 - SCR (экран 5 или 7) 2:0 - номер страницы для #C000 ``` ### Режимы совместимости (MemConfig [7:6]) | LCK128 | Режим | Описание | |--------|-------|----------| | 00 | Pentagon-512 | `TSCONF_MEM_LCK128_512K` | | 01 | Pentagon-128 | `TSCONF_MEM_LCK128_128K` | | 10 | Авто | `TSCONF_MEM_LCK128_AUTO` | | 11 | 1024 КБ | `TSCONF_MEM_LCK128_1M` | --- ## FDD виртуализация (#29AF) TSConfig позволяет виртуализировать FDD-приводы (для TRD/TAP): | Константа | Значение | Описание | |-----------|----------|----------| | `TSCONF_FDD_A` | 0x01 | Привод A | | `TSCONF_FDD_B` | 0x02 | Привод B | | `TSCONF_FDD_C` | 0x04 | Привод C | | `TSCONF_FDD_D` | 0x08 | Привод D | | `TSCONF_FDD_VG_OPEN` | 0x80 | Открыть VG93 | --- ## Файловая система WC работает через FAT32: - **SD-карты**: Z-Controller (основной), NeoGS SD - **IDE**: NEMO (Master/Slave), SMUC (Master/Slave) - **Длинные имена**: до 255 символов (с WC v0.73) - **Каталоги**: >4095 записей (с WC v1.05) --- ## Полезные ссылки - TSConfig спецификация: https://github.com/tslabs/zx-evo - Регистры TSConfig: [src_sdcc/inc/tsconf.h](../src_sdcc/inc/tsconf.h) - WC API: [src_sdcc/inc/wc_api.h](../src_sdcc/inc/wc_api.h) - ISR конфигурация: [src_sdcc/inc/variant_cfg.h](../src_sdcc/inc/variant_cfg.h) ## Пример инициализации для плагина ```asm ; Базовая инициализация для музыкального плагина INIT_PLUGIN: ; Сохранить текущее состояние LD A,(#6002) ; Страница в окне 2 PUSH AF LD A,(#6003) ; Страница в окне 3 PUSH AF ; Восстановить TXT режим LD A,#0F CALL WLD ; GEDPL ; Установить частоту CPU LD B,#00 ; Z80 frequency LD C,%01 ; 7 MHz LD A,#0E CALL WLD ; TURBOPL ; Настроить прерывания LD HL,INT_HANDLER EXA LD A,#FF CALL WLD ; INT_PL EXA ; Инициализация OPL3 CALL INIT_OPL3 RET ; Обработчик прерываний INT_HANDLER: PUSH AF, BC, DE, HL ; Ваш код обработки музыки CALL UPDATE_MUSIC POP HL, DE, BC, AF EI RETI ; Инициализация OPL3 INIT_OPL3: ; Сброс OPL3 LD BC,#C4 XOR A OUT (C),A LD B,#C5 OUT (C),A ; Дополнительная инициализация... RET ```