Files
VGMPLAY.WMF/doc/01_WC_Plugin_Overview.md
T

21 KiB
Raw Blame History

Wild Commander — Обзор Системы Плагинов

Версия документа: 2.0 — дополнена по результатам анализа исходников
Источники: inc/wc_api.h, asm/wc_api.s, asm/crt0.s, DiskRef/Help.txt, DiskRef/WC_History.txt

Введение

Wild Commander (WC) — файловый менеджер с системой плагинов для платформы TS-Configuration (ZX Spectrum Evo). Выполняет роль основной оболочки и загрузчика для работы с FAT32-дисками, SD-картами и IDE.

WC запускается из BootROM / vDOS и предоставляет:

  • Двухпанельный интерфейс (80 × 25/30/36 TXT-режим)
  • FAT32 (длинные и короткие имена до 255 символов)
  • Систему плагинов (.WMF) с горячей загрузкой/выгрузкой
  • Поддержку устройств: SD (Z-Controller), IDE NEMO, IDE SMUC, NeoGS SD
  • Встроенный просмотрщик (F3): TXT, HEX, TGA, SCR, Gigascreen, MGS — до 1 МБ
  • Мультиязычность (ENG / RUS, переключение CTRL+SHIFT)

Версии

Компонент Версия Примечание
WC 1.10 (03.08.2025) Последняя из WC_History.txt
Plugin System #10 Формат заголовка .WMF
Идентификатор WildCommanderMDL 16 байт, offset +16 в заголовке

Общая концепция

Плагины WC (.WMF файлы) — модульные расширения, выполняемые в адресном пространстве Z80. Поддерживают до 64 страниц (1 МБ) кода/данных.

Типичные области применения:

  • Просмотр файлов различных форматов (BMP, GIF, ILBM, SCR)
  • Воспроизведение музыки и видео (VGM, MOD, WAV, MP3/GS)
  • Редактирование файлов (TXT Editor с подсветкой синтаксиса)
  • Работа с ROM/Flash (ROM_PROG)
  • Монтирование образов дисков (MOUNTER: TRD, TAP, FDI)
  • Утилиты (часы, скринсейвер, компилятор, дамп памяти)

Типы запуска плагинов

При запуске плагина, в регистр A передается тип вызова:

Код Константа (C) Описание
#00 WC_PCOND_EXT_ONLY По расширению файла (ENTER / F3)
#01 WC_PCOND_ON_LOAD При первой загрузке плагина (ENTER)
#02 WC_PCOND_TIMER По таймеру скринсейвера + меню F10
#03 WC_PCOND_F10 Из меню запуска плагинов (F10)
#04 WC_PCOND_VIEWER Из меню вьювера (SHIFT+F3 / SHIFT+ENTER)
#05 WC_PCOND_F10_VIEW F10 + SHIFT+F3
#11 WC_PCOND_F10_F2 F10 + F2
#12 WC_PCOND_F2 По нажатию F2
#13 WC_PCOND_F10_F4 F10 + F4
#14 WC_PCOND_F4 По нажатию F4
#15 WC_PCOND_F10_V_F4 F10 + SHIFT+F3 + F4

Примечание: Все плагины также вызываются по расширению, если расширения указаны в блоке расширений заголовка (offset +64). ENTER и F3 разделены начиная с WC v1.00 — флаг +63 определяет, какой из них запускает плагин.

Входные параметры при запуске

WC делает CALL #8000. В crt0.s (SDCC) входные регистры сохраняются в глобальные переменные автоматически.

; Входные параметры:
A       - тип вызова (см. таблицу выше)
[DE,HL] - длина файла в байтах (DE=hi16, HL=lo16)
BC      - адрес строки с именем файла (для типов #00, #04, #14)
          формат: name(1-255), 0   (длинное FAT имя)
IX      - адрес структуры активной панели

; Альтернативные регистры (только для #00,#04,#12,#14):
A'      - номер расширения (0-31) для типа #00
DE'     - количество файлов/каталогов в панели (включая "..")
HL'     - номер объекта из панели (от 1)

В SDCC-плагине (crt0.s автоматически):

extern uint8_t   wc_file_ext;   // ← A' (номер расширения)
extern char *    wc_file_name;  // ← BC (указатель на имя)
extern uint32_t  wc_file_size;  // ← [DE,HL] (32-бит размер)

Коды возврата из плагина

При выходе из плагина регистр A определяет действие WC:

A Константа (C) Действие
0 WC_EXIT_ESC Просто выход (ESC)
1 WC_EXIT_UNRECOGNIZED Файл не опознан → передать другому плагину (тип #00)
2 WC_EXIT_NEXT Перейти на следующий файл (тип #00)
3 WC_EXIT_RELOAD_DIR Перечитать каталог
4 WC_EXIT_PREV Перейти на предыдущий файл (тип #00)

В SDCC-плагине: wc_exit_code = 0; return 0; — crt0.s считывает wc_exit_code в A перед RET обратно в WC.

Код 2/4 (NEXT/PREV): WC вызывает тот же плагин повторно с другим файлом. crt0.s заново обнуляет BSS (_DATA) и копирует инициализаторы (_INITIALIZER → _INITIALIZED), поэтому все static переменные сбросятся.

Системные адреса

Источник: src_sdcc/inc/wc_api.h, раздел «СИСТЕМНЫЕ ПЕРЕМЕННЫЕ WC»

Адрес Константа Размер Описание
#6000 WC_SYS_PG0 1 Текущая страница в окне #0000
#6001 WC_SYS_PG4 1 Текущая страница в окне #4000
#6002 WC_SYS_PG8 1 Текущая страница в окне #8000
#6003 WC_SYS_PGC 1 Текущая страница в окне #C000
#6004 WC_SYS_ABT 1 1 = был нажат ESC
#6005 WC_SYS_ENT 1 1 = был нажат ENTER
#6006 WC_SYS_FUN 3 Точка входа WC API (JP к диспетчеру)
#6009 WC_SYS_TMN 2 Таймер INT (uint16_t, ++/кадр ≈50 Гц)
#600B WC_SYS_FEP 1 Страница FAT-движка в окне 0
#600C WC_SYS_XPP 1 Сохранённая страница
#600D WC_SYS_CNFV 1 ЦАП: 0=PWM, 1=3bit, 2=4bit, 3=5bit, 7=VDAC2/FT812
#600E WC_SYS_HEI 1 Высота TXT-экрана: 25 / 30 / 36
#600F WC_SYS_TXTMD 1 Текущий видеорежим WC (0=TXT)
#6010 WC_SYS_INIFLG 1 Флаг загрузки INI-конфигурации
#6011 WC_SYS_RSQBC 2 RSQ буфер-счётчик
#6013 WC_SYS_RSQB2 2 RSQ буфер 2
#6015 WC_SYS_SDBSF 1 Состояние SD1 драйвера
#6016 WC_SYS_SDBSF2 1 Состояние SD2 драйвера
#6017 WC_SYS_F3ENTFL 1 Флаг F3/ENTER для файловых операций
#6018 WC_SYS_FEP2 2 FAT engine page extra
#6020 WC_SYS_PLRESAD 8 Резидент перехода: A=страница, HL=адрес → JP(HL)
#6028 WC_SYS_PLRESCALL 8 Резидент вызова: A=страница, HL=адрес → CALL(HL)
#8000 — — Точка входа плагина (WC делает CALL #8000)

Чтение из C:

#define WC_SYS_ABT  (*(volatile uint8_t*)0x6004)
#define WC_SYS_TMN  (*(volatile uint16_t*)0x6009)
#define WC_SYS_HEI  (*(volatile uint8_t*)0x600E)

// Или через макросы wc_api.h:
uint8_t  h = wc_get_height();   // 25/30/36
uint16_t t = wc_get_timer();    // кадровый счётчик
uint8_t  esc = wc_get_abt();    // 1 = ESC нажат

Вызов API функций

Все функции WC вызываются через точку доступа #6006:

WLD     EQU #6006

; Пример вызова функции PRWOW (вывод окна)
PRWOW   LD A,1
        JP WLD

; Пример вызова ESC (проверка нажатия ESC)
ESC     LD A,#17
        JP WLD

Регистровые соглашения WC API:

  • Вход: A = номер функции, остальные параметры в регистрах (см. справочник)
  • Некоторые функции используют A' (альтернативный A через EX AF,AF')
  • Портит: AF, BC, DE, HL, IX
  • Сохраняет: IY, AF', BC', DE', HL', SP

⚠️ IX сохраняется диспетчером P8000, но AF, BC, DE, HL портятся при каждом вызове CALL #6006.


Карта памяти (физические страницы)

Источник: wc_api.h — полная таблица WC_PAGE_*

Страницы Константа Назначение
#00 WC_PAGE_MTXPG Основной текстовый экран (TXT)
#01 WC_PAGE_FONT0 Шрифт основного TXT + Hrust/MegaLZ
#02 WC_PAGE_CODE Код WC (ядро)
#05 WC_PAGE_FAT_ENGINE FAT движок + стек + данные
#08 WC_PAGE_BUFPG 2-й текстовый экран / буфер
#09 WC_PAGE_FONT1 Шрифт для 2-го TXT
#0B–#13 WC_PAGE_CAT_LEFT Каталог левой панели (9 стр.)
#14–#1C WC_PAGE_CAT_RIGHT Каталог правой панели (9 стр.)
#1D WC_PAGE_RESB Буфер сохранения окон (RESB)
#1E WC_PAGE_CPPG1 Позиции левой панели
#1F WC_PAGE_CPPG2 Позиции правой панели
#20–#5F WC_PAGE_TVBPG Мегабуфер (64 стр. = 1 МБ), он же видео:
#20–#2F WC_PAGE_GV1 — видеобуфер 1 (16 стр.)
#30–#3F WC_PAGE_GV2 — видеобуфер 2
#40–#4F WC_PAGE_GV3 — видеобуфер 3
#50–#5F WC_PAGE_GV4 — видеобуфер 4
#60 WC_PAGE_PLHPG Заголовки плагинов
#61–#A0 WC_PAGE_PLGPG Код/данные плагинов (до 64 стр.)
#A1–#BF WC_PAGE_TAP_START TAP-область (31 стр. = 496 КБ)
#C0–#E7 WC_PAGE_VDOS_RAM vDOS RAM-диск (40 стр. = 640 КБ)
#E8–#EF WC_PAGE_VDOS_FREE Свободные страницы
#F0 WC_PAGE_PNLPG Поток левой панели
#F1 WC_PAGE_PNL_RIGHT Поток правой панели
#F2 WC_PAGE_INIPG INI-поток (плагин #00)
#F3 WC_PAGE_STRPG Поток плагина #01
#F4–#F7 — SPG loader, boot pages (5,2), panel paths
#F8–#FB WC_PAGE_VROM_START Виртуальный ROM (4 стр.)
#FC–#FF — vDOS: таблицы, драйверы, трапы

Плагин видит: свои заказанные страницы (0..N) через wc_mngc_pl() / wc_mng0_pl() / wc_mng8_pl(). Физическая нумерация скрыта — WC маппит логическую страницу N плагина в WC_PAGE_PLGPG + N.


Поддерживаемые устройства хранения

Код Константа Устройство
0 WC_DEV_SD_ZC SD-карта (Z-Controller)
1 WC_DEV_IDE_NEMO_M IDE Nemo — Master
2 WC_DEV_IDE_NEMO_S IDE Nemo — Slave
3 WC_DEV_SD_NGS SD-карта (NeoGS)
4 WC_DEV_IDE_SMUC_M IDE SMUC — Master
5 WC_DEV_IDE_SMUC_S IDE SMUC — Slave
6 WC_DEV_SD2_ZC Вторая SD (Z-Controller SD2)

Работа со страницами памяти

Логическая нумерация

Плагин запрашивает N страниц в заголовке (offset +34). WC выделяет их из пула #61–#A0. Плагин обращается по логическому номеру 0..N−1.

Окна CPU и функции маппинга

Окно Адреса Функция ASM Функция C Примечание
Win 0 #0000–#3FFF MNG0_PL (#4E) wc_mng0_pl(page) ⚠ Данные для WC API нельзя класть сюда
Win 2 #8000–#BFFF MNG8_PL (#4F) wc_mng8_pl(page) Код плагина — обычно стартовая страница
Win 3 #C000–#FFFF MNGC_PL (#00) wc_mngc_pl(page) ⚠ Сбрасывается после КАЖДОГО вызова WC API

Специальные значения для MNGC_PL:

  • #FF — шрифтовая страница (нельзя писать в #E000–#FFFF!)
  • #FE — первый текстовый экран (с панелями WC)

Резидент перехода (#6020)

Переключает страницу плагина и делает безвозвратный JP:

// C: никогда не вернётся в вызывающий код
void wc_resident_jump(uint8_t page, uint16_t addr);
; ASM: A = страница (0..N-1), HL = адрес (#8000–#BFFF)
        LD A,1
        LD HL,#8000
        CALL #6020      ; → WC переключает Win2 на стр.1, JP (HL)

Резидент вызова (#6028)

Вызывает код в другой странице плагина с возвратом:

void wc_resident_call(uint8_t page, uint16_t addr);
; ASM: A = страница, HL = адрес. Сохраняет всё кроме A,HL.
        LD A,2
        LD HL,#A000
        CALL #6028      ; → WC переключает, CALL (HL), возвращает стр. назад

Добавлено в WC v1.09 (31.07.2024). До этого многостраничные плагины требовали прямой OUT в порт Page2 (#12AF).


Важные замечания

  1. При входе в плагин может быть любой экран! Обязательно вызывайте GEDPL (#0F) / wc_gedpl() для переключения на текстовый режим.

  2. Вызывать GEDPL лучше после анализа файла, когда убедились что файл подходит для плагина (и вернули wc_exit_code = 1 если нет).

  3. Обязательно сохраняйте IX при входе в плагин, если планируете использовать файловые функции.

  4. ⚠ Win3 (#C000) сбрасывается после каждого вызова WC API!
    Внутри CALL #6006 WC переключает окно #C000 на текстовую страницу и не восстанавливает его. Если плагин работал через mngcvpl() / mngc_pl(), он обязан повторить маппинг после любого UI-вызова (gedpl, prwow, txtpr, rresb, load512 и т.д.).

  5. GEDPL затирает #1000–#1447 в окне 0 — нельзя хранить данные в этой области.

  6. Буферы и строки для файловых функций (load512, fentry, findnext, и т.д.) обязаны быть в #8000–#FFFF. WC ремапит #0000–#7FFF под FAT-движок внутри каждого файлового вызова.

  7. FindNext портит #0000–#1FFF на странице драйвера — не хранить данные там при итерации по каталогу.

  8. WC API портит регистры: AF, BC, DE, HL, IX. Сохраняет: IY, AF', BC', DE', HL', SP. Это верно для всех функций через CALL #6006.

  9. Стек не настраивается — плагин использует стек WC (в Win 1, #4000–#7FFF). Стек WC достаточно глубокий для обычных плагинов, но рекурсия требует осторожности.


Горячие клавиши WC (для пользователя)

Источник: DiskRef/Help.txt

Клавиша Действие
ENTER Войти в каталог / запустить .WMF / просмотреть файл
F3 Встроенный просмотрщик (TXT/HEX/TGA/SCR/MGS, до 1 МБ)
SHIFT+F3/SHIFT+ENTER Меню выбора вьювера (плагин с WC_PCOND_VIEWER)
F2 Пользовательское меню (из wc.mnu)
F4 Редактирование / выбор текстового редактора
F5 Копирование отмеченных файлов в другую панель
F6 Переименование файла/каталога
F7 Создание каталога
F8 / DEL Удаление отмеченных файлов
F9 Настройки INI (авто-создаёт каталог WC на загрузочном устройстве)
F10 Меню запуска/удаления плагинов
TAB Переключение между панелями
SPACE / INSERT Отметить файл/каталог
* Инвертировать выделение
ALT+F1/F2 Выбор диска для левой/правой панели
CTRL+F3 Сортировка по имени
CTRL+F4 Сортировка по расширению
CTRL+F6 Сортировка по размеру
CTRL+R Обновить каталог
CTRL+A Выделить все объекты
CTRL+SHIFT Переключение ENG/RUS

Примеры плагинов

В каталоге DiskRef/WC/ находятся скомпилированные плагины WC:

Файл Назначение
GSPLAYER.WMF Плеер для GS (MP3, MOD, WAV)
WPLAYER.WMF Музыкальный плеер с плейлистами
VGMPLAY.WMF VGM плеер (OPL3/AY/SAA) — этот проект
TXTEDIT.WMF Текстовый редактор с подсветкой синтаксиса
BMPV.WMF Просмотрщик BMP
GIFVIEW.WMF Просмотрщик GIF
ILBMVIEW.WMF Просмотрщик IFF/ILBM
FTVIEW.WMF Просмотрщик FT-шрифтов
MOUNTER.WMF Монтирование TRD/TAP/FDI образов
ROM_PROG.WMF Программатор ROM/Flash
SCRSAVER.WMF Скринсейвер (тип вызова WC_PCOND_TIMER)
CLOCK.WMF Часы
SETIME.WMF Установка времени
COMPILER.WMF Компилятор
RE.WMF Ассемблер/отладчик

Ссылки на другие разделы документации