Files
VGMPLAY.WMF/doc/03_WC_API_Reference.md
T

41 KiB
Raw Blame History

WC API — Полный справочник функций

Источники: inc/wc_api.h (1878 стр.), asm/wc_api.s (1339 стр.), DiskRef/WC_History.txt (история изменений API)

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

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

WLD EQU #6006

; В регистр A загружается номер функции
; Остальные параметры - в соответствующие регистры
LD A, функция_номер
JP WLD

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

  • Портит: AF, BC, DE, HL, IX
  • Сохраняет: IY, AF’, BC’, DE’, HL’, SP
  • Функции с параметром в A’ используют EX AF,AF' перед вызовом

⚠️ Win 3 (#C000) сбрасывается на текстовую страницу после каждого вызова CALL #6006. Плагин обязан повторить mngcvpl()/mngc_pl() после любого API-вызова.

Категории функций

  1. Управление памятью
  2. Работа с окнами
  3. Работа с клавиатурой
  4. Файловые операции
  5. Работа с графикой
  6. Системные функции
  7. DMA операции
  8. Константы и структуры
  9. Таблица кодов функций

Управление памятью

#00 - MNGC_PL

Включение страницы плагина на #C000

Вход:

  • A' - номер страницы (от 0)
    • #FF - страница с фонтом (нельзя использовать #E000-#FFFF!)
    • #FE - первый текстовый экран (с панелями)

Пример:

MNGC_PL:  EXA
          LD A,0       ; Страница 0
          CALL WLD
          EXA
          RET

#78 - MNG0_PL

Включение страницы плагина на #0000

Вход:

  • A' - номер страницы (от 0)

Важно: Все структуры для файловых функций должны лежать в #8000-#FFFF!

#79 - MNG8_PL

Включение страницы плагина на #8000

Вход:

  • A' - номер страницы (от 0)

Работа с окнами

Структура окна (SOW - Structure Of Window)

; Базовая структура (для типа 0)
SOW:
    DB 0           ; +0:  Флаги окна
    DB 0           ; +1:  Маска цвета курсора
    DB 255         ; +2:  X позиция (255=центр)
    DB 255         ; +3:  Y позиция (255=центр)
    DB 40          ; +4:  Ширина (0=весь экран)
    DB 20          ; +5:  Высота (0=весь экран)
    DB %01111111   ; +6:  Цвет (PAPER+INK)
    DB 0           ; +7:  Резерв (всегда 0)
    DW #0000       ; +8:  Адрес буфера (#0000=не выведено, #FFFF=без буфера)
    DB 0           ; +10: Линия разделитель 1
    DB 0           ; +11: Линия разделитель 2 (смещение снизу)
    DB 1           ; +12: Позиция курсора (от 1)
    DB 20          ; +13: Нижний ограничитель
    DB %01011000   ; +14: Цвет курсора
    DB %01111111   ; +15: Цвет под курсором

Флаги окна (+0):

[7]: %1 - окно с тенью
[6]: %1 - курсор во всю ширину
[5]: резерв
[4]: %1 - окно с инверсной шапкой
[3-0]: Тип окна:
  0 - стандартное окно, рамки 1-го типа
  1 - окно с заголовками и текстом (без курсора)
  2 - окно с заголовками и текстом + курсор
  3 - стандартное окно, рамки 2-го типа
  4 - окно с заголовками (рамки 2-го типа)
  5 - окно с заголовками + курсор (рамки 2-го типа)
  6 - стандартное окно, рамки 3-го типа
  7 - окно с заголовками (рамки 3-го типа)
  8 - окно с заголовками + курсор (рамки 3-го типа)

#01 - PRWOW

Вывод окна на экран

Вход:

  • IX - адрес структуры окна (SOW) в #8000-#BFFF или #0000-#3FFF

Примечание: Включает основной TXT экран в #C000 и оставляет его по выходу!

#02 - RRESB

Стирание окна (восстановление информации)

Вход:

  • IX - адрес SOW

Примечание: Включает основной TXT экран в #C000!

#03 - PRSRW

Печать строки в окне

Вход:

  • IX - адрес SOW
  • HL - адрес текста (в #8000-#BFFF или #0000-#3FFF)
  • D - Y координата
  • E - X координата
  • BC - длина строки

#04 - PRIAT

Выставление цвета (после PRSRW)

Вход:

  • A' - цвет (PAPER+INK)
  • Использует координаты и длину из PRSRW

#05 - GADRW

Получение адреса в окне

Вход:

  • IX - адрес SOW
  • D - Y координата
  • E - X координата

Выход:

  • HL - адрес в памяти

#06 - CURSOR

Печать курсора

Вход:

  • IX - адрес SOW

#07 - CURSER

Стирание курсора

Вход:

  • IX - адрес SOW

#0B - TXTPR

Вывод текста с разметкой в окне

Вход:

  • IX - адрес SOW
  • HL - адрес текста (в #8000-#BFFF или #0000-#3FFF)
  • D - Y (внутри окна)
  • E - X (внутри окна)

Выход:

  • D - Y (следующая строка)
  • E - X (без изменений)

Коды разметки текста:

#00       - конец строки и абзаца
#00,#00   - разделитель между сообщениями
#0B,XX    - сдвиг вправо на XX символов
#0C,YY    - сдвиг вниз на YY строк
#0D       - перенос строки
#0E       - центрирование строки
#09       - инверсия цвета

#01-#08   - цвет чернил (1=синий, 7=белый, 8=черный)
#01-#08,#01-#08 - папер+инк

#FE,XXXX  - ссылка на строку (XXXX - адрес)

Работа с клавиатурой

Все функции возвращают NZ если клавиша нажата, Z если нет.

Функция Код Клавиша
SPKE #10 SPACE
UPPP #11 UP Arrow
DWWW #12 DOWN Arrow
LFFF #13 LEFT Arrow
RGGG #14 RIGHT Arrow
TABK #15 TAB
ENKE #16 ENTER
ESC #17 ESCAPE
BSPC #18 BACKSPACE
PGU #19 PAGE UP
PGD #1A PAGE DOWN
HOME #1B HOME
END #1C END
F1-F10 #1D-#26 F1-F10
ALT #27 ALT
SHIFT #28 SHIFT
CTRL #29 CTRL
DEL #2B DELETE
INS #55 INSERT
CAPS #2C CAPS LOCK
ANYK #2D Любая клавиша
USPO #2E Пауза до отпускания клавиш
NUSP #2F Ожидание любой клавиши

#2A - KBSCN

Сканирование клавиатуры

Вход:

  • A' - режим обработки
    • #00 - учитывает SHIFT, CAPS, ENG/RUS (вызывать 1 раз в фрейм)
    • #01 - всегда выдает код из таблицы (можно вызывать много раз)

Выход:

  • NZ: A - код клавиши
  • Z: A - #00 (неизвестная клавиша) или #FF (буфер пуст)

Пример:

WAIT_KEY:
    EI
    HALT
    LD A,1
    CALL KBSCN
    CP 'm'           ; Ждем 'm'
    JR NZ,WAIT_KEY

Файловые операции

#30 - LOAD512

Потоковая загрузка файла

Вход:

  • HL - адрес буфера
  • B - количество блоков (по 512 байт)

Выход:

  • HL - новое значение адреса
  • A - #0F если конец файла

#31 - SAVE512

Потоковая запись файла

Вход:

  • HL - адрес буфера
  • B - количество блоков (по 512 байт)

Выход:

  • HL - новое значение адреса
  • A - #0F если конец файла

#32 - GIPAGPL

Позиционирование на начало файла

Устанавливает указатель на начало файла, переданного плагину.

#3B - FENTRY

Поиск файла/каталога

Вход:

  • HL - адрес структуры: flag(1), name(1-255), #00
    • flag: #00 = файл, #10 = каталог

Выход:

  • Z - файл не найден
  • NZ - файл найден, [DE,HL] = размер файла
    • Вызовите GFILE/GDIR для активации

Пример:

    LD HL,FILE_STRUCT
    LD A,#3B
    CALL WLD
    JR Z,NOT_FOUND
    ; Файл найден
    CALL GFILE        ; Активировать файл
    ...
FILE_STRUCT:
    DB #00            ; Файл
    DB "music.vgm",0

#3E - GFILE

Активация найденного файла

Устанавливает указатель на начало файла, найденного FENTRY.

#3F - GDIR

Активация найденного каталога

Делает каталог, найденный FENTRY, активным.

#48 - MKfile

Создание файла

Вход:

  • HL - адрес структуры: flag(1), length(4), name(1-255), #00

Выход:

  • A - код ошибки
  • Z - файл создан
  • NZ - ошибка

#39 - STREAM

Работа с потоками

Вход:

  • D - команда:

    • #FF - активировать root dir
    • #FE - клонировать поток в #00 и #01
    • #FD - активировать поток INI файла
    • #00/#01 - номер потока, требует BC
  • BC (для #00/#01):

    • B - устройство (0=SD, 1=IDE Master, 2=IDE Slave)
    • C - раздел
    • #FFFF - просто включить поток

Выход:

  • Z - поток активен
  • NZ - ошибка

Работа с графикой

#40 - MNGV_PL

Включение видео страницы

Вход:

  • A' - номер видео страницы:
    • #00 - основной экран (TXT)
    • #01 - видео буфер 1 (16 страниц)
    • #02 - видео буфер 2 (16 страниц)
    • #03 - видео буфер 3 (16 страниц)
    • #04 - видео буфер 4 (16 страниц)

#41 - MNGCVPL

Включение страницы видео буфера на #C000

Вход:

  • A' - номер страницы:
    • #00-#0F - из буфера 1
    • #10-#1F - из буфера 2
    • #20-#2F - из буфера 3
    • #30-#3F - из буфера 4

#42 - GVmod

Включение видео режима

Вход:

  • A' - видео режим:
[7-6]: Разрешение
  %00 - 256x192
  %01 - 320x200
  %10 - 320x240
  %11 - 360x288
[1-0]: Тип
  %00 - ZX
  %01 - 16c
  %10 - 256c
  %11 - txt

Системные функции

#0E - TURBOPL

Управление частотой процессора

Вход:

  • B - выбор Z80/AY:
    • #00 (WC_TURBO_CPU) - частота Z80:
      • C = %00 (3.5 МГц), %01 (7 МГц), %10 (14 МГц), %11 (28 МГц)
    • #01 (WC_TURBO_AY) - частота AY:
      • C = %00 (1.75 МГц), %01 (1.7733 МГц), %10 (3.5 МГц), %11 (3.546 МГц)
    • #FF (WC_TURBO_RESTORE) - восстановить значения из настроек WC

AY частоты 1.7733/3.546 МГц — это NTSC-кварц (315/88 МГц ÷ 2).

#0F - GEDPL

Восстановление текстового режима

Важно: Обязательно вызывать при запуске плагина!

Восстанавливает палитру, оффсеты, включает TXT режим.

Примечание: Гробит область #1000-#1447!

#56 - INT_PL

Работа с прерываниями

Вход:

  • A' - команда:
    • #00 - отключить все INT функции
    • #01 - отключить обновление времени
    • #02 - отключить опрос PS/2 клавиатуры
    • #FF - установить обработчик INT от плагина
      • HL - адрес обработчика (#8000-#BFFE)

Примечание: Все параметры восстанавливаются при выходе из плагина.

#53 - PRM_PL

Запрос параметров запуска

Вход:

  • A' - номер параметра (1-8)

Выход:

  • Z - параметр не найден
  • NZ - параметр получен
    • A - номер выбранной опции (1-10)

DMA операции

#0D - DMAPL

Работа с DMA

Инициализация:

  • A' = #00: инит S и D (BHL=Source, CDE=Destination)
  • A' = #01: инит S (BHL)
  • A' = #02: инит D (CDE)
  • A' = #05: DMA_T (B = количество бёрстов, 0=1...255=256)
  • A' = #06: DMA_N (B = размер бёрста)

Формат B/C для #00-#02:

[7]: %1 - страница из блока плагина (0-5)
     %0 - страница из видео буферов (0-63)
[6-0]: номер страницы

Запуск:

  • A' = #FC: RAM→RAM
  • A' = #FE: RAM→RAM с ожиданием
  • A' = #FF: ожидание готовности DMA

Выход:

  • Z - операция завершена
  • NZ - DMA не готов

Пример:

; Копирование 4KB из страницы 0 в страницу 1
    LD B,#80        ; Страница 0 плагина
    LD HL,#8000     ; Адрес источника
    LD C,#81        ; Страница 1 плагина
    LD DE,#8000     ; Адрес назначения
    EXA
    LD A,#00        ; Инит S и D
    CALL WLD
    LD A,#05
    LD B,8          ; 8 бёрстов
    CALL WLD
    LD A,#06
    LD B,255        ; По 512 байт
    CALL WLD
    LD A,#FE        ; Запуск с ожиданием
    CALL WLD
    EXA

Макросы для удобства

; Определения для вызова функций
WLD     EQU #6006

; Окна
PRWOW   MACRO
        LD A,1
        JP WLD
        ENDM

RRESB   MACRO
        LD A,2
        JP WLD
        ENDM

; Клавиатура
ESC     MACRO
        LD A,#17
        JP WLD
        ENDM

ENKE    MACRO
        LD A,#16
        JP WLD
        ENDM

; Файлы
LOAD512 MACRO
        LD A,#30
        JP WLD
        ENDM

GEDPL   MACRO
        LD A,#0F
        JP WLD
        ENDM

C API (SDCC)

Источник: src_sdcc/inc/wc_api.h + src_sdcc/asm/wc_api.s
Компилятор: SDCC 4.x, соглашение sdcccall(1)

Соглашение вызова sdcccall(1)

Аргумент Тип Регистр
1-й uint8_t A
1-й uint16_t / указатель HL
2-й uint16_t / указатель DE
3-й+ любой стек (callee-cleans)
Возврат uint8_t A
Возврат uint16_t HL

WC API портит: AF, BC, DE, HL, IX при каждом вызове.
WC API сохраняет: IY, AF', BC', DE', HL', SP.


Управление памятью (страницы)

// Переключить окно #C000 на логическую страницу плагина N
void wc_mngc_pl(uint8_t page);

// Переключить окно #0000 на логическую страницу плагина N
void wc_mng0_pl(uint8_t page);

// Переключить окно #8000 на логическую страницу плагина N
void wc_mng8_pl(uint8_t page);

// Переключить окно #C000 на VPL-страницу мегабуфера N (физич. = WC_PAGE_TVBPG + N)
void wc_mngcvpl(uint8_t vpage);

// Переключить видеобуфер (WC_VIDEO_TXT / WC_VIDEO_BUF1..4)
void wc_mngv_pl(uint8_t mode);

⚠️ После любого вызова WC API окно #C000 сбрасывается на текстовую страницу!
Если плагин работал с mngcvpl(), после каждого UI-вызова нужно снова вызвать mngcvpl().


Отображение / UI

// Восстановить дисплей WC (TXT-режим, панели)
// ⚠ Затирает #1000–#1447 в окне 0!
void wc_gedpl(void);

// Нарисовать окно
void wc_prwow(wc_window_t *win);

// Убрать окно (восстановить фон из RESB)
void wc_rresb(wc_window_t *win);

// Прокрутить область окна
void wc_scrlwow(wc_window_t *win, uint8_t y, uint8_t x,
                uint8_t h, uint8_t w, uint8_t flags);

// Вывести строку с разметкой WC в окно
// Возвращает: номер строки после последнего символа
uint8_t wc_txtpr(wc_window_t *win, const char *str, uint8_t y, uint8_t x);

// Вывести сообщение (несколько абзацев, разделённых 0x00 0x00)
uint8_t wc_mezz(wc_window_t *win, uint8_t msg_num,
                const char *str, uint8_t y, uint8_t x);

// Вывести строку без разметки (raw)
void wc_prsrw(wc_window_t *win, const char *str,
              uint8_t y, uint8_t x, uint16_t len);

// Вывести строку без разметки с заданным атрибутом цвета
void wc_prsrw_attr(wc_window_t *win, const char *str,
                   uint8_t y, uint8_t x, uint16_t len, uint8_t attr);

// Получить адрес экрана по позиции в окне
uint16_t wc_gadrw(wc_window_t *win, uint8_t y, uint8_t x);

// Показать/убрать курсор
void wc_cursor(wc_window_t *win);
void wc_curser(wc_window_t *win);

// Диалог Yes/No или Ok/Cancel
// mode: WC_YN_YES_NO, WC_YN_OK_CANCEL, WC_YN_POLL, WC_YN_EXIT
// Возвращает: 0=нет/отмена, 1=да/ок (при POLL: текущий выбор)
uint8_t wc_yn(uint8_t mode);

// Ввод строки в окне
void wc_istr(wc_window_t *win, uint8_t mode);

// Вставить символ val по адресу addr в текстовой памяти
void wc_nork(uint16_t addr, uint8_t val);

Клавиатура

// Опрос конкретной клавиши (возвращает 1 если нажата)
uint8_t wc_key_space(void);
uint8_t wc_key_up(void);
uint8_t wc_key_down(void);
uint8_t wc_key_left(void);
uint8_t wc_key_right(void);
uint8_t wc_key_tab(void);
uint8_t wc_key_enter(void);
uint8_t wc_key_esc(void);
uint8_t wc_key_bspc(void);
uint8_t wc_key_pgup(void);
uint8_t wc_key_pgdn(void);
uint8_t wc_key_home(void);
uint8_t wc_key_end(void);
uint8_t wc_key_f1(void);
uint8_t wc_key_f2(void);
uint8_t wc_key_f3(void);
uint8_t wc_key_f4(void);
uint8_t wc_key_f5(void);
uint8_t wc_key_f6(void);
uint8_t wc_key_f7(void);
uint8_t wc_key_f8(void);
uint8_t wc_key_f9(void);
uint8_t wc_key_f10(void);

// Модификаторы (без автоповтора)
uint8_t wc_key_alt(void);
uint8_t wc_key_shift(void);
uint8_t wc_key_ctrl(void);

// Прочие клавиши
uint8_t wc_key_del(void);
uint8_t wc_key_ins(void);
uint8_t wc_key_caps(void);
uint8_t wc_key_any(void);          // любая клавиша нажата (без автоповтора)

// Ждать нажатия любой клавиши, вернуть скан-код
uint8_t wc_key_wait_any(void);

// Ждать отпускания всех клавиш
void    wc_key_wait_release(void);

// Получить скан-код нажатой клавиши
// mode: WC_KBSCN_NORMAL (с учётом SHIFT/CL/Lang) или WC_KBSCN_RAW
uint8_t wc_kbscn(uint8_t mode);

Файловые операции

Все буферы и строки файловых функций обязаны быть в #8000–#FFFF
(WC ремапит #0000–#7FFF внутри FAT-операций).

// Прочитать blocks×512 байт по адресу dest из открытого файла
// Возвращает: 0=OK, WC_EOF=конец файла, иное=ошибка
uint8_t wc_load512(uint16_t dest, uint8_t blocks);

// Прочитать blocks×256 байт по адресу dest
uint8_t wc_load256(uint16_t dest, uint8_t blocks);

// Записать blocks×512 байт по адресу src в открытый файл
void wc_save512(uint16_t src, uint8_t blocks);

// Пропустить sectors×512 байт в открытом файле (без чтения)
void wc_loadnone(uint8_t sectors);

// Сменить поток (контекст файловой операции)
// mode: WC_STREAM_ROOT, WC_STREAM_CLONE, WC_STREAM_WCDIR, 0/1
void wc_stream(uint8_t mode);

// Управление каталогом (WC_ADIR_SEEK_START, WC_ADIR_RESET_NEXT)
void wc_adir(uint8_t mode);

// Открыть файл по имени в текущем каталоге
// name_with_flag: [1 байт флагов][имя][0]
// Возвращает: 0=не найден, ненулевое=найден
uint8_t wc_fentry(uint16_t name_with_flag);

// Найти следующий файл в каталоге
// flags: [7]=только короткие имена, [1:0]=00 все/01 файлы/10 каталоги
// Возвращает: 0 (Z=1)=конец каталога, ненулевое=найден
uint8_t wc_findnext(uint16_t entry_buf, uint8_t flags);

// Открыть файл, найденный последним wc_fentry()
void wc_gfile(void);

// Войти в каталог, найденный последним wc_fentry()
void wc_gdir(void);

// Создать файл: [1 байт флагов][длина][имя][0]
uint8_t wc_mkfile(uint16_t name_with_flag);

// Создать каталог
uint8_t wc_mkdir(uint16_t name);

// Переименовать файл/каталог
uint8_t wc_rename(uint16_t old_name, uint16_t new_name);

// Удалить файл
uint8_t wc_delfl(uint16_t name_with_flag);

// Перейти к началу файла плагина (позиционировать поток на первый блок)
void wc_gipagpl(void);

// Прочитать FAT ENTRY (32 байта) файла в буфер по адресу addr
void wc_tentry(uint16_t addr);

// Обойти цепочку секторов, записать список секторов в buf..bufend
void wc_chtosep(uint16_t buf, uint16_t bufend);

// Получить заголовок помеченного файла
// panel = IX структура панели WC, filenum = номер файла, namebuf = буфер
void wc_tmrkdfl(uint16_t panel, uint16_t filenum, uint16_t namebuf);

Графика и видео

// Переключить видеорежим: WC_VIDEO_TXT / WC_VIDEO_BUF1..4
void wc_mngv_pl(uint8_t mode);

// Отобразить видеостраницу vpage (0x00–0x3F) на окно #C000
void wc_mngcvpl(uint8_t vpage);

// Отобразить видеостраницу vpage на окно #0000
// ⚠ GEDPL (~wc_gedpl) затирает #1000–#1447 — не хранить данные там!
void wc_mng0vpl(uint8_t vpage);

// Отобразить видеостраницу vpage на окно #8000
void wc_mng8vpl(uint8_t vpage);

// Установить видеорежим TSConfig
// mode: TSCONF_VM_* | TSCONF_RRES_* (байт VConfig)
void wc_gvmod(uint8_t mode);

// Установить Y-смещение прокрутки графики
void wc_gyoff(uint16_t y);

// Установить X-смещение прокрутки графики
void wc_gxoff(uint16_t x);

// Установить страницу тайловой карты
void wc_gvtm(uint8_t page);

// Установить страницу графики тайловой плоскости (plane=0 или 1)
void wc_gvtl(uint8_t plane, uint8_t page);

// Установить страницу графики спрайтов
void wc_gvsgp(uint8_t page);

DMA

// Настройка и запуск DMA TSConfig.
// Подфункции:
//   0x00 — src+dst: B=src_page, HL=src_addr, C=dst_page, DE=dst_addr
//   0x01 — только src; 0x02 — только dst
//   0x05 — DMA_T; 0x06 — DMA_N; 0x07 — T+N
//   0xFC — RAM→RAM (с ожиданием)  0xFB — BLT→RAM
//   0xFA — FILL                   0xF9 — RAM→CRAM (палитра)
//   0xF8 — RAM→SFILE (спрайты)    0xFD — запустить без ожидания
//   0xFE — запустить с ожиданием  0xFF — ждать готовности DMA
void wc_dmapl(uint8_t subfunc);

Системные функции

// Прерывания (WC_INT_DISABLE_ALL / NO_TIME / NO_PS2 / PLUGIN)
// При WC_INT_PLUGIN — следующий вызов wc_int_pl_handler() задаёт адрес
void wc_int_pl(uint8_t mode);

// Установить адрес обработчика ISR плагина (после wc_int_pl(WC_INT_PLUGIN))
void wc_int_pl_handler(uint16_t handler_addr);

// Управление CPU/AY частотой
// mode: WC_TURBO_CPU (param 0=3.5, 1=7, 2=14, 3=28 МГц)
//       WC_TURBO_AY  (param 0=1.750, 1=1.773, 2=3.5, 3=3.546 МГц)
//       WC_TURBO_RESTORE (0xFF) — восстановить из настроек WC
void wc_turbopl(uint8_t mode, uint8_t param);

// Получить параметр из INI-файла плагина
// param_num: 0-based номер параметра
// Возвращает: номер опции (0-based), 0xFF если параметр не задан
uint8_t wc_prm_pl(uint8_t param_num);

// Резидентный JP на другую страницу плагина (без возврата!)
// page: номер страницы (от 0), addr: адрес в #8000–#BFFF
void wc_resident_jump(uint8_t page, uint16_t addr);

// Резидентный CALL на другую страницу плагина (с возвратом)
// Сохраняет все регистры кроме A и HL
void wc_resident_call(uint8_t page, uint16_t addr);

// Заполнить буфер символом c (аналог memset)
void wc_strset(char *dsr, uint16_t len, char c);

Системные переменные (прямой доступ по адресу)

// Читаются напрямую, без вызова WC API:
extern volatile uint8_t  wc_exit_code;      // #8000 − записать перед return из main()
                                             // 0=ESC, 1=не распознан, 2=следующий,
                                             // 3=перечитать каталог, 4=предыдущий

#define WC_SYS_ABT  (*(volatile uint8_t*)0x6004)  // 1 = был нажат ESC
#define WC_SYS_ENT  (*(volatile uint8_t*)0x6005)  // 1 = был нажат ENTER
#define WC_SYS_TMN  (*(volatile uint16_t*)0x6009) // таймер INT (инкремент каждый INT)
#define WC_SYS_HEI  (*(volatile uint8_t*)0x600E)  // высота TXT-экрана (25/30/36)
#define WC_SYS_PG0  (*(volatile uint8_t*)0x6000)  // текущая страница окна #0000
#define WC_SYS_PGC  (*(volatile uint8_t*)0x6003)  // текущая страница окна #C000

Пример минимального плагина (SDCC C)

#include "inc/wc_api.h"
#include "inc/types.h"

// Структура окна в DATA (0x8000+)
static wc_window_t g_win;

// Код выхода (WC читает A при RET из main)
uint8_t wc_exit_code;

int main(void) {

    // --- Настройка окна ---
    g_win.type     = WC_WIN_SINGLE;
    g_win.cur_mask = 0x07;
    g_win.x        = 255;   // по центру
    g_win.y        = 255;
    g_win.width    = 40;
    g_win.height   = 8;
    g_win.color    = WC_COLOR(WC_BLACK, WC_BRIGHT_WHITE);
    g_win.buf_addr = 0x0000; // автосохранение фона

    // --- Отрисовка UI ---
    wc_gedpl();
    wc_prwow(&g_win);
    wc_txtpr(&g_win, "Hello from plugin!", 1, 1);

    // --- Главный цикл ---
    while (1) {
        if (wc_key_esc()) break;
        if (wc_key_enter()) {
            // ... какое-то действие
        }
    }

    // --- Выход ---
    wc_rresb(&g_win);
    wc_gedpl();

    wc_exit_code = 0;   // 0 = нормальный выход (ESC)
    return 0;
}

Константы и структуры

Цветовая палитра (EGA-совместимая)

#define WC_COLOR(bg, fg)    ((uint8_t)(((bg) << 4) | (fg)))

#define WC_BLACK            0      #define WC_DARK_GRAY        8
#define WC_BLUE             1      #define WC_BRIGHT_BLUE      9
#define WC_RED              2      #define WC_BRIGHT_RED       10
#define WC_MAGENTA          3      #define WC_BRIGHT_MAGENTA   11
#define WC_GREEN            4      #define WC_BRIGHT_GREEN     12
#define WC_CYAN             5      #define WC_BRIGHT_CYAN      13
#define WC_YELLOW           6      #define WC_BRIGHT_YELLOW    14
#define WC_WHITE            7      #define WC_BRIGHT_WHITE     15

Стили окон

Константа Значение Описание
WC_WIN_NO_BORDER 0x00 Без рамки, со стандартным курсором
WC_WIN_SINGLE 0x01 Одинарная рамка, без курсора
WC_WIN_DOUBLE 0x02 Двойная рамка + курсор
WC_WIN_TYPE3..TYPE8 0x03..0x08 Рамки 2/3 типа ± курсор/заголовки

Флаги (OR с типом):

Флаг Значение Описание
WC_WIN_HEADER 0x10 Инверсный заголовок сверху
WC_WIN_WIDE_CURSOR 0x40 Курсор на всю ширину
WC_WIN_SHADOW 0x80 Тень у окна

Структура wc_window_t (16 байт)

typedef struct {
    uint8_t  type;       /* +0:  стиль+флаги (WC_WIN_*)                */
    uint8_t  cur_mask;   /* +1:  маска цвета курсора                   */
    uint8_t  x;          /* +2:  X (255=по центру)                     */
    uint8_t  y;          /* +3:  Y (255=по центру)                     */
    uint8_t  width;      /* +4:  ширина (0=весь экран)                 */
    uint8_t  height;     /* +5:  высота (0=весь экран)                 */
    uint8_t  color;      /* +6:  WC_COLOR(bg, fg)                      */
    uint8_t  _reserved;  /* +7:  ВСЕГДА 0!                             */
    uint16_t buf_addr;   /* +8:  буфер фона (0=авто, 0xFFFF=без буфера)*/
    uint8_t  divider1;   /* +10: разделитель 1 (смещение от верха)     */
    uint8_t  divider2;   /* +11: разделитель 2 (смещение от низа)      */
    uint8_t  cursor_pos; /* +12: позиция курсора (от 1)                */
    uint8_t  cursor_bot; /* +13: нижний ограничитель курсора           */
    uint8_t  cursor_clr; /* +14: цвет курсора                          */
    uint8_t  under_clr;  /* +15: цвет под курсором                     */
} wc_window_t;

Авто-центрирование (x=255, y=255) работает для режимов 80×25, 80×30, 90×36. Добавлено в WC v1.02.

Структура FAT-записи (32 байта)

typedef struct {
    uint8_t  name[11];    /* +0:  короткое имя 8.3 (без точки)        */
    uint8_t  attr;        /* +11: атрибуты FAT (см. WC_FAT_ATTR_*)    */
    uint8_t  _res1;       /* +12: NTRes                                */
    uint8_t  crt_time_ms; /* +13: время создания (0.1 сек)             */
    uint16_t crt_time;    /* +14: время создания (FAT format)          */
    uint16_t crt_date;    /* +16: дата создания                        */
    uint16_t acc_date;    /* +18: дата доступа                         */
    uint16_t cluster_hi;  /* +20: старшее слово кластера               */
    uint16_t mod_time;    /* +22: время модификации                    */
    uint16_t mod_date;    /* +24: дата модификации                     */
    uint16_t cluster_lo;  /* +26: младшее слово кластера               */
    uint32_t file_size;   /* +28: размер файла                         */
} wc_fat_entry_t;

Атрибуты FAT:

Константа Значение Описание
WC_FAT_ATTR_RDONLY 0x01 Только чтение
WC_FAT_ATTR_HIDDEN 0x02 Скрытый
WC_FAT_ATTR_SYSTEM 0x04 Системный
WC_FAT_ATTR_VOLLBL 0x08 Метка тома
WC_FAT_ATTR_DIR 0x10 Каталог
WC_FAT_ATTR_ARCHIVE 0x20 Архивный
WC_FAT_ATTR_LFN 0x0F LFN-запись (RDONLY|HIDDEN|SYSTEM|VOLLBL)

Структура FindNext

typedef struct {
    uint32_t size;    /* опционально, если WC_FIND_WITH_SIZE         */
    uint16_t date;    /* опционально, если WC_FIND_WITH_DATE         */
    uint16_t time;    /* опционально, если WC_FIND_WITH_TIME         */
    uint8_t  flag;    /* 0x10=каталог, 0x00=файл                     */
    char     name[1]; /* имя, z-string (длина переменная)            */
} wc_findnext_entry_t;

Флаги для wc_findnext(entry_buf, flags):

Константа Значение Описание
WC_FIND_ALL 0x00 Все записи
WC_FIND_FILES 0x01 Только файлы
WC_FIND_DIRS 0x02 Только каталоги
WC_FIND_WITH_SIZE 0x04 Включить поле size
WC_FIND_WITH_DATE 0x08 Включить поле date
WC_FIND_WITH_TIME 0x10 Включить поле time
WC_FIND_FULL 0x1C Все опциональные поля
WC_FIND_SHORT_ONLY 0x80 Только короткие имена 8.3

Коды ошибок файловых операций

Константа Значение Описание
WC_EOF 0x0F Конец файла / конец цепочки
WC_ERR_LONG_NAME 1 Недопустимое длинное имя
WC_ERR_SHORT_IDX 2 Короткое имя требует индекса
WC_ERR_LONG_EXISTS 3 Длинное имя уже существует
WC_ERR_SHORT_EXISTS 4 Короткое имя уже существует
WC_ERR_NOT_FOUND 8 Файл/каталог не найден
WC_ERR_NO_SPACE 16 Нет свободного места
WC_ERR_UNKNOWN 255 Неизвестная ошибка

Константы скроллинга (wc_scrlwow)

Константа Значение Описание
WC_SCRL_DOWN 0x00 Прокрутка вниз
WC_SCRL_UP 0x01 Прокрутка вверх
WC_SCRL_WITH_ATTRS 0x80 Прокручивать и атрибуты
WC_SCRL_CLEAR_SRC 0x40 Очистить источник после сдвига

Константы потоков (wc_stream)

Константа Значение Описание
WC_STREAM_ROOT 0xFF Корневой каталог
WC_STREAM_CLONE 0xFE Клонировать текущий поток в #00 и #01
WC_STREAM_WCDIR 0xFD Каталог WC (для INI)
0x00, 0x01 — Выбрать поток 0 или 1

Константы видеобуферов

Константа Значение Описание
WC_VIDEO_TXT 0x00 Текстовый режим WC
WC_VIDEO_BUF1 0x01 Видеобуфер 1 (стр. #20–#2F)
WC_VIDEO_BUF2 0x02 Видеобуфер 2 (стр. #30–#3F)
WC_VIDEO_BUF3 0x03 Видеобуфер 3 (стр. #40–#4F)
WC_VIDEO_BUF4 0x04 Видеобуфер 4 (стр. #50–#5F)

Мегабуфер (64 стр.) и видеобуферы пересекаются физически: VPL-страница N = физическая WC_PAGE_TVBPG + N = #20 + N.

Размеры TXT-экрана

Константа Значение
WC_SCREEN_80x25 25
WC_SCREEN_80x30 30
WC_SCREEN_90x36 36

Таблица кодов функций

Полный маппинг ASM → WC API code → C wrapper

Код A ASM C функция Параметр в A' (EXA)? Примечание
#00 MNGC_PL wc_mngc_pl(page) Да (page) #FF=font, #FE=TXT
#01 PRWOW wc_prwow(win) — IX=win
#02 RRESB wc_rresb(win) — IX=win
#03 PRSRW wc_prsrw(win,str,y,x,len) —
#04 PRIAT (часть prsrw_attr) Да (color) Вызывается сразу после #03
#05 GADRW wc_gadrw(win,y,x) — → HL=addr
#06 CURSOR wc_cursor(win) —
#07 CURSER wc_curser(win) —
#08 YN wc_yn(mode) Да (mode)
#09 ISTR wc_istr(win,mode) Да (mode)
#0A NORK wc_nork(addr,val) Да (val)
#0B TXTPR wc_txtpr(win,str,y,x) — → A=next_y
#0C MEZZ wc_mezz(win,msg,str,y,x) Да (msg_num)
#0D DMAPL wc_dmapl(subfunc) Да (subfunc)
#0E TURBOPL wc_turbopl(mode,param) — B=mode, C=param
#0F GEDPL wc_gedpl() — ⚠ Портит #1000–#1447
#10..#29 Keys wc_key_*() — → NZ=нажата
#2A KBSCN wc_kbscn(mode) Да (mode)
#2B DEL wc_key_del() —
#2C CAPS wc_key_caps() —
#2D ANYK wc_key_any() —
#2E USPO wc_key_wait_release() —
#2F NUSP wc_key_wait_any() —
#30 LOAD512 wc_load512(dest,blocks) — B=blocks
#31 SAVE512 wc_save512(src,blocks) —
#32 GIPAGPL wc_gipagpl() —
#33 TENTRY wc_tentry(addr) —
#34 CHTOSEP wc_chtosep(buf,bufend) —
#36 TMRKDFL wc_tmrkdfl(panel,fnum,buf) —
#38 ADIR wc_adir(mode) Да (mode)
#39 STREAM wc_stream(mode) — D=mode
#3A FINDNEXT wc_findnext(buf,flags) Да (flags)
#3B FENTRY wc_fentry(name) — → Z/NZ
#3C LOAD256 wc_load256(dest,blocks) —
#3D LOADNONE wc_loadnone(sectors) — B=sectors
#3E GFILE wc_gfile() —
#3F GDIR wc_gdir() —
#40 MNGV_PL wc_mngv_pl(mode) Да (mode)
#41 MNGCVPL wc_mngcvpl(vpage) Да (vpage)
#42 GVmod wc_gvmod(mode) Да (mode)
#43 GYOFF wc_gyoff(y) — HL=y
#44 GXOFF wc_gxoff(x) — HL=x
#45 GVtm wc_gvtm(page) — C=page
#46 GVtl wc_gvtl(plane,page) — B=plane,C=page
#47 GVsgp wc_gvsgp(page) — C=page
#48 MKfile wc_mkfile(name) —
#49 MKdir wc_mkdir(name) —
#4A RENAME wc_rename(old,new) —
#4B DELFL wc_delfl(name) —
#4E MNG0_PL wc_mng0_pl(page) Да (page)
#4F MNG8_PL wc_mng8_pl(page) Да (page)
#50 MNG0VPL wc_mng0vpl(vpage) Да (vpage)
#51 MNG8VPL wc_mng8vpl(vpage) Да (vpage)
#53 PRM_PL wc_prm_pl(param) Да (param) → Z=нет, NZ: A=opt
#54 SCRLWOW wc_scrlwow(win,y,x,h,w,fl) Да (flags)
#55 INS wc_key_ins() —
#56 INT_PL wc_int_pl(mode) Да (mode)
— PLRESAD wc_resident_jump(p,addr) — CALL #6020, JP
— PLRESCALL wc_resident_call(p,addr) — CALL #6028
— STRSET wc_strset(dst,len,c) — Утилита (LDIR)