41 KiB
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-вызова.
Категории функций
- Управление памятью
- Работа с окнами
- Работа с клавиатурой
- Файловые операции
- Работа с графикой
- Системные функции
- DMA операции
- Константы и структуры
- Таблица кодов функций
Управление памятью
#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
- #00 (
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) |