# 2. BIOS Sprinter Sp2000 — полный справочник ## 2.1 Общие сведения BIOS Sprinter — набор системных функций, доступных через три способа вызова: | Способ | Применение | Прерывания | |--------|-----------|-----------| | `CALL 3D13h` | Из любой точки, через системный вход | **Отключает** (DI) | | `RST 8` | Из EXE (обработчик в DSS), код в #0008 | Не отключает | | `RST 18h` | При подключённом ПЗУ в W0 | Не отключает | Для `CALL 3D13h` после вызова программа сама включает прерывания (EI). Если прерывания нужны постоянно — использовать `RST 18h`/`RST 8` с обработчиком и стеком в `#8000..#BFFF` в режиме IM 2. ### Конвенция регистров - **C** — номер функции - Остальные регистры — входные параметры (по функции) - **CF=0** — успех, выходные данные в регистрах - **CF=1** — ошибка, код ошибки в **A** ### Включение/отключение ПЗУ в W0 ```asm LD A,0 OUT (07Ch),A ; включить ПЗУ BIOS в окно 0 ; ... вызовы RST 18h ... LD A,0 OUT (03Ch),A ; отключить ПЗУ, вернуть ОЗУ ``` ### Ограничения - Стек — обязательно в `#8000..#BFFF` (W2), так как часть функций переключает W1 и W3 - HL, IX обычно сохраняются в функциях вывода текста, но не гарантируется во всех - Некоторые функции окно́вых операций (WIN_COPY_WIN, WIN_RESTORE_WIN, WIN_MOVE_WIN) **требуют DI** при вызове через RST 18h/8 — используют стек для ускорения --- ## 2.2 Системные функции (00h–0Fh) ### 00h — BOOT Перезагрузка системы. Параметров нет. Не возвращается (полный ресет). ### 01h — INIT Инициализация BIOS. Параметров нет. Вызывается автоматически при старте. Повторный вызов сбрасывает состояние окон, палитр и системных переменных к умолчаниям. ### 02h — GET_KEY (`A=0`) Ожидание и получение нажатой клавиши. | | Регистр | Описание | |--|---------|----------| | Вход | A=0 | (зарезервировано) | | Выход | A | ASCII-код нажатой клавиши | Блокирует выполнение до нажатия. Не эхо-печатает символ на экран. Возвращает расширенный ASCII (8-бит), для F-клавиш и стрелок — смотри GET_EXT_KEY. ### 03h — GET_EXT_KEY Получение расширенной клавиши (без ожидания, опрос). | | Регистр | Описание | |--|---------|----------| | Вход | — | | | Выход | D | Скан-код клавиатуры | | Выход | E | ASCII-символ (0 если нет символа) | Если нет нажатия — возвращает D=E=0 (или неопределённое значение — проверять). Для F-клавиш, стрелок и других не-ASCII клавиш E=0, D=скан-код. ### 04h — PR_OK Проверка готовности к вводу. Параметров нет. Назначение точно не документировано. ### 05h — IS_EXT_KEY Проверка, есть ли в буфере расширенная клавиша. | | Регистр | Описание | |--|---------|----------| | Вход | — | | | Выход | A | 0 = нет клавиши, 1 = есть | Не блокирует, не считывает. После `A=1` вызывает `GET_EXT_KEY`. ### 06h Зарезервировано. ### 08Fh — FN_TURBO Управление режимом турбо и режимом FDD. | | Регистр | Описание | |--|---------|----------| | Вход | C | `08Fh` | | Вход | A | `2` = turbo off, `3` = turbo on, `12h` = FDD 720K, `13h` = FDD 1.44M | | Выход | CF=0 | Успех | | Выход | CF=1 | Неверный режим | Переключение турбо может не произойти, если прошивка ППЛМ не поддерживает его. Ошибки при этом нет (CF=0). --- ## 2.3 Управление памятью (0C0h–0C7h, 09Eh, 09Dh) ### 0C0h — EMM_FN0 Определение объёмов ОЗУ. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C0h` | | Выход | HL | Общий объём ОЗУ в страницах по 16 КБ | | Выход | BC | Свободный объём ОЗУ в страницах по 16 КБ | ### 0C1h — EMM_FN1 Инициализация распределения памяти. Стирает всю информацию о выделенных ранее блоках ОЗУ. Блоки с системной информацией и первые 256 КБ ОЗУ помечаются занятыми. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C1h` | | Выход | — | Нет | ### 0C2h — EMM_FN2 Выделение блока ОЗУ. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C2h` | | Вход | B | Число запрашиваемых страниц (16 КБ каждая) | | Выход (CF=0) | A | Идентификатор блока | | Выход (CF=1) | A | `1` = не хватает памяти | ### 0C3h — EMM_FN3 Освобождение блока ОЗУ. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C3h` | | Вход | A | Идентификатор блока | | Выход (CF=1) | C | Неверный идентификатор | Правильность идентификатора отслеживается не всегда. ### 0C4h — EMM_FN4 Получение физического номера страницы из блока по логическому номеру. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C4h` | | Вход | A | Идентификатор блока | | Вход | B | Логический номер страницы в блоке | | Выход (CF=0) | A | Физический номер страницы | | Выход (CF=1) | A | `0` = блок не существует, `255` = страница за пределами блока | ### 0C5h — EMM_FN5 Получение списка всех физических страниц блока. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C5h` | | Вход | A | Идентификатор блока | | Вход | HL | Адрес буфера (256 байт) | | Выход (CF=0) | B | Число страниц в блоке | | Выход (CF=0) | HL | Тот же буфер; в нём — список физических страниц по порядку, завершающийся байтом `0FFh` | | Выход (CF=1) | — | Неверный ID блока; данные в буфере могут быть затерты | Буфер должен быть на 1 байт больше числа страниц в блоке. ### 0C6h — EMM_FN6 Получение адреса порта окна и текущей подключённой страницы. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C6h` | | Вход | A | Номер окна (0, 1, 2 или 3) | | Выход (CF=0) | C | 8-битный адрес порта окна | | Выход (CF=0) | B | Физический номер текущей страницы | | Выход (CF=1) | — | Неверный номер окна | > **Примечание:** функция практически не используется — адреса портов окон фиксированы с начала разработки: `PAGE0=82h`, `PAGE1=0A2h`, `PAGE2=0C2h`, `PAGE3=0E2h`. Рекомендуется вызвать её один раз для верификации. ### 0C7h — EMM_FN7 Получение следующей страницы в блоке по физическому номеру. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0C7h` | | Вход | A | Физическая страница | | Выход (CF=0) | A | Следующая физическая страница того же блока; `0FFh` = конец блока | | Выход (CF=1) | — | Страница не принадлежит никакому блоку (свободна) | Информация о распределении памяти хранится в RAM Allocation Table (FAT-подобная), поэтому переход по «следующей» странице быстрее, чем поиск по логическому номеру. ### 09Eh — EMM_FN8 Слияние двух блоков памяти в один. | | Регистр | Описание | |--|---------|----------| | Вход | C | `09Eh` | | Вход | A | Идентификатор блока 1 | | Вход | B | Идентификатор блока 2 | | Выход (CF=0) | A | Идентификатор объединённого блока | | Выход (CF=1) | A | Неверный идентификатор | ### 09Dh — EMM_FN9 Разделение блока на две части. | | Регистр | Описание | |--|---------|----------| | Вход | C | `09Dh` | | Вход | A | Идентификатор блока | | Вход | B | Новая длина первой части (в страницах) | | Выход (CF=0) | A | Идентификатор блока-результата (первая часть) | | Выход (CF=0) | B | Идентификатор блока-остатка (вторая часть) | | Выход (CF=1) | — | Неверный идентификатор | --- ## 2.4 Функции «железа» (0EFh, 0F2h, 0F5h–0F7h) ### 0EFh — FN_VERSION Выдача информации о версии BIOS и модели компьютера. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0EFh` | | Вход | HL | Адрес буфера для строки (результат — ASCII, поля разделены, конец — двойной ноль) | | Выход (CF=0) | HL | Тот же буфер с заполненной строкой | | Выход (CF=0) | DE | Версия BIOS | | Выход (CF=0) | BC | Версия железа (*см. таблицу*) | | Выход (CF=0) | A | Количество полей в буфере (всегда 2) | | Выход (CF=1) | — | Очень старая версия BIOS, нет функции | **Значения BC (версия железа):** | BC | BIOS_v3.txt | IvanMak.txt | |----|-------------|-------------| | `FFFF` | Не определено | Не определено | | `FFFE` | Spectrum, режим Sprinter ZX | Sprinter-1 | | `FFFD` | Конфигурация Sprinter | Sprinter-2 | | `FFFC` | Зарезервировано | Spectrum+AY8910 | | `FFFB` | Зарезервировано | Game-1 | | `FFFA` | Зарезервировано | Video-1 | | `FFF9` | Зарезервировано | DooM | | иные | Новые прошивки | Новые прошивки | > **Примечание:** BIOS_v3.txt помечает `FFF9–FFFC` как «зарезервировано», IvanMak присваивает им конкретные конфигурации. Исходный код BIOS v3.04 (FUNC_BIOS_MAIN.ASM) возвращает `ID_SPRINTER` с тремя полями: `"Firmware vX.Y"`, `"Sprinter"`, версия битстрима. Версия дискового ПЗУ — v2.56, CPLD — v3.05 (определяются в `_BIOS.REV` и сборке). Реальные возвращаемые коды BC зависят от прошивки ППЛМ. Поля в буфере HL (через `HL`): первое — версия BIOS, второе — название модели компьютера. ### 0F2h — FN_SICF Установка режима синхронизации и очистка страниц режима экрана. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0F2h` | | Вход | A | `0` — режим по умолчанию (очистка страниц режима), `1` — Scorpion (312 строк, INT как в Scorpion-256), `2` — Pentagon (320 строк, INT как в Pentagon-128) | | Выход (CF=0) | — | Успех | | Выход (CF=1) | — | Неверный номер режима | При `A=0` происходит полная очистка страниц режима — на всём экране остаётся только бордер. Смена режима синхронизации может привести к временному сбою монитора. ### 0F5h — CMOS_TEST Проверка наличия микросхемы CMOS (часы реального времени). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0F5h` | | Выход (CF=0) | — | Часы есть (физическая микросхема DS12887A или эмуляция) | | Выход (CF=1) | — | Часов нет | Функции CMOS работают всегда — если микросхемы нет, BIOS эмулирует её память. ### 0F6h — CMOS_RD Чтение регистра CMOS. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0F6h` | | Вход | D | Номер регистра CMOS | | Выход | A | Прочитанные данные | | Выход (CF=0) | — | Часы есть | | Выход (CF=1) | — | Часов нет | ### 0F7h — CMOS_WR Запись в регистр CMOS. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0F7h` | | Вход | D | Номер регистра CMOS | | Вход | A | Записываемые данные | | Выход (CF=0) | — | Часы есть | | Выход (CF=1) | — | Часов нет | --- ## 2.5 Функции управления окнами (0B0h–0B8h) > **Важно:** в текущей версии BIOS идентификатор окна (`A`) для **всех** оконных функций обязан быть `0`. Возможность работы с несколькими окнами не реализована — при открытии нового окна старый описатель теряется. Единственный валидный идентификатор — `0`. ### Дескриптор окна (для WIN_OPEN) 32-байтовый блок, адрес в **IX**: | Смещение | Размер | Описание | |----------|--------|----------| | IX+0 | 1 | Горизонтальный размер окна (в знакоместах) | | IX+1 | 1 | Вертикальный размер окна (в знакоместах) | | IX+2 | 1 | Положение окна по горизонтали на экране (знакоместа) | | IX+3 | 1 | Положение окна по вертикали на экране (знакоместа) | | IX+4 | 1 | **Режим знакоместа** | | | | Бит 4: `1` = text mode, `0` = graf mode | | | | Бит 5: `0` = 16 точек/знакоместо, `1` = 8 точек | | | | graf mode: биты 7–6 = номер палитры, биты 3–0 несущественны | | | | text mode: биты 7–6,3–0 = номер знакогенератора; `11xxxxxx` = бордер | | IX+5 | 1 | Бит 0: `1` = включить спектрумовскую адресацию экрана | | IX+6 | 1 | Положение X в поле графики (в знакоместах) | | IX+7 | 1 | Положение Y в поле графики (в знакоместах) | | IX+8..31 | 24 | Зарезервировано (должны быть нулями) | При открытии окна дескриптор копируется в системную страницу ОЗУ — программа может не сохранять его. Вместо этого используется **идентификатор окна** (возвращается WIN_OPEN). > **Важно:** в текущей версии BIOS хранится только один описатель окна. Идентификатор всегда 0. При открытии нового окна старый описатель теряется. ### 0B0h — WIN_OPEN Открытие окна. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B0h` | | Вход | IX | Адрес 32-байтового дескриптора окна | | Вход | E | Бит 0: какую страницу режима включать; бит 4: на какой странице открывать | | Выход (CF=0) | A | Идентификатор окна | | Выход (CF=1) | — | Слишком много окон | ### 0B1h — WIN_CLOSE Закрытие окна. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B1h` | | Вход | A | Идентификатор окна | | Выход (CF=1) | — | Неверный идентификатор | Окно с номером 0 никогда не закрывается — попытка закрыть его возвращает CF=1. ### 0B2h — WIN_COPY_WIN Копирование текстового окна в буфер (запоминание). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B2h` | | Вход | A | Идентификатор глобального окна | | Вход | H | Размер по вертикали (в символах) | | Вход | L | Размер по горизонтали (в символах) | | Вход | D | Вертикальное положение в глобальном окне | | Вход | E | Горизонтальное положение в глобальном окне | | Вход | IX | Адрес буфера (относительно `#C000`; если от `#8000` — страница недействительна) | | Вход | A' | Страница буфера (должна принадлежать программе) | | Выход (CF=1) | — | Неверный идентификатор | > **Требует DI** при вызове через RST 18h/8 — использует стек для ускорения. ### 0B3h — WIN_RESTORE_WIN Восстановление окна из буфера. Параметры — полностью идентичны WIN_COPY_WIN. > **Требует DI** при вызове через RST 18h/8. ### 0B4h — WIN_GET_SYM Получение символа и атрибута с экрана. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B4h` | | Вход | A | Идентификатор окна | | Вход | D | Вертикальная позиция символа | | Вход | E | Горизонтальная позиция символа | | Выход (CF=0) | L | Символ | | Выход (CF=0) | H | Атрибут | | Выход (CF=0) | B | Номер знакогенератора | | Выход (CF=1) | — | Неверный идентификатор окна | > **Важно:** анализ исходного кода BIOS v3.04 (FUNC_LOW_PRINT.ASM) подтверждает: `A` **обязан быть 0**. Реализация начинается с `AND A / SCF / RET NZ` — при `A ≠ 0` сразу возвращается CF=1. Многооконная поддержка не реализована. ### 0B5h — WIN_PUT_SYM Вывод символа на экран. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B5h` | | Вход | A | Идентификатор окна | | Вход | D | Вертикальная позиция | | Вход | E | Горизонтальная позиция | | Вход | L | Символ | | Вход | H | Атрибут символа | | Вход | B | Номер знакогенератора | | Выход (CF=1) | — | Неверный идентификатор окна | ### 0B6h — WIN_SET_ZG Установка знакогенератора. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B6h` | | Вход | A | Системный номер знакогенератора | | Вход | DE | Указатель на 2 КБ данных знакогенератора | | Выход (CF=1) | — | Старая версия, нет функции | ### 0B7h — WIN_MOVE_WIN Перемещение окна. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B7h` | | Вход | A | Идентификатор глобального окна | | Вход | H | Размер локального окна по вертикали (символы) | | Вход | L | Размер локального окна по горизонтали (символы) | | Вход | D | Положение локального окна по вертикали (символы) | | Вход | E | Положение локального окна по горизонтали (символы) | | Вход | IX | Новое положение локального окна (как DE — D=верт, E=гор) | | Выход (CF=1) | — | Неверный идентификатор | > **Требует DI** при вызове через RST 18h/8. ### 0B8h — WIN_GET_ZG Получение знакогенератора. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0B8h` | | Вход | DE | Адрес буфера (2 КБ) | | Выход (CF=1) | — | Старая версия, нет функции | --- ## 2.6 Функции вывода текста (081h–08Eh) Все функции этого раздела работают с **текущим окном** (последнее открытое). К графическому экрану не применимы. CF=0 на выходе — всегда успех (кроме особо оговоренных). ### 081h — LP_PRINT_ALL Печать `B` одинаковых символов с атрибутом. | | Регистр | Описание | |--|---------|----------| | Вход | C | `081h` | | Вход | A | Символ | | Вход | E | Атрибут | | Вход | B | Количество символов | HL, IX сохраняются. ### 082h — LP_PRINT_SYM Печать `B` одинаковых символов **без изменения атрибута**. | | Регистр | Описание | |--|---------|----------| | Вход | C | `082h` | | Вход | A | Символ | | Вход | B | Количество символов | HL, IX сохраняются. ### 083h — LP_PRINT_ATR Печать `B` одинаковых атрибутов. Символы на экране не меняются. | | Регистр | Описание | |--|---------|----------| | Вход | C | `083h` | | Вход | E | Атрибут | | Вход | B | Количество символов | HL, IX сохраняются. ### 084h — LP_SET_PLACE Установка текущей позиции печати в окне. | | Регистр | Описание | |--|---------|----------| | Вход | C | `084h` | | Вход | E | Горизонтальная позиция (столбец) | | Вход | D | Вертикальная позиция (строка) | Превышение границ окна приводит к переустановке позиции с начала (за вычетом полного размера окна) — не ошибка. ### 085h — LP_PRINT_LN Вывод строки символов с атрибутом с текущей позиции. | | Регистр | Описание | |--|---------|----------| | Вход | C | `085h` | | Вход | HL | Адрес строки (обязательно в `#4000..#BFFF`) | | Вход | E | Атрибут | | Вход | B | Длина строки | ### 086h — LP_PRINT_LN2 Вывод строки символов без атрибутов с текущей позиции. | | Регистр | Описание | |--|---------|----------| | Вход | C | `086h` | | Вход | HL | Адрес строки (`#4000..#BFFF`) | | Вход | B | Длина строки | ### 087h — LP_PRINT_LN3 Вывод строки до разделителя, с атрибутом. После разделителя — пробелы до длины `B`. | | Регистр | Описание | |--|---------|----------| | Вход | C | `087h` | | Вход | HL | Адрес строки (`#4000..#BFFF`) | | Вход | E | Атрибут | | Вход | B | Максимальная длина | | Вход | D | Символ-разделитель | ### 088h — LP_PRINT_LN4 Вывод строки до разделителя, без атрибутов. После разделителя — пробелы. | | Регистр | Описание | |--|---------|----------| | Вход | C | `088h` | | Вход | HL | Адрес строки (`#4000..#BFFF`) | | Вход | B | Максимальная длина | | Вход | D | Символ-разделитель | ### 089h — LP_CLS_WIN Очистка экрана (заполнение пробелами с заданным атрибутом). | | Регистр | Описание | |--|---------|----------| | Вход | C | `089h` | | Вход | D | Вертикальное положение локального окна | | Вход | E | Горизонтальное положение локального окна | | Вход | H | Размер по вертикали | | Вход | L | Размер по горизонтали | | Вход | B | Атрибут очистки | ### 08Ah — LP_SCROLL_UD Скроллинг части глобального окна вверх/вниз. | | Регистр | Описание | |--|---------|----------| | Вход | C | `08Ah` | | Вход | B | `1` = вверх, `2` = вниз | | Вход | D | Начальная строка скроллинга | | Вход | E | Число скроллируемых строк | Скроллируются полные строки глобального окна. ### 08Bh — LP_PRINT_LN5 Вывод строки до разделителя с атрибутом. После разделителя вывод **останавливается** (не заполняется пробелами). | | Регистр | Описание | |--|---------|----------| | Вход | C | `08Bh` | | Вход | HL | Адрес строки (`#4000..#BFFF`) | | Вход | E | Атрибут | | Вход | B | Максимальная длина | | Вход | D | Символ-разделитель | ### 08Ch — LP_PRINT_LN6 Вывод строки до разделителя без атрибутов. Останов на разделителе. | | Регистр | Описание | |--|---------|----------| | Вход | C | `08Ch` | | Вход | HL | Адрес строки (`#4000..#BFFF`) | | Вход | B | Максимальная длина | | Вход | D | Символ-разделитель | ### 08Dh — LP_CLS_WIN2 Очистка экрана с указанием символа заполнения. | | Регистр | Описание | |--|---------|----------| | Вход | C | `08Dh` | | Вход | D | Вертикальное положение локального окна | | Вход | E | Горизонтальное положение локального окна | | Вход | H | Размер по вертикали | | Вход | L | Размер по горизонтали | | Вход | B | Атрибут очистки | | Вход | A | Символ заполнения | ### 08Eh — LP_GET_PLACE Получение текущей позиции печати. | | Регистр | Описание | |--|---------|----------| | Вход | C | `08Eh` | | Выход | D | Текущая строка (вертикаль) | | Выход | E | Текущий столбец (горизонталь) | --- ## 2.7 Графические функции (0A0h–0A8h) ### 0A0h — PIC_OPEN_WIN Открытие окна в пиксельных координатах (в отличие от WIN_OPEN, работающего в знакоместах). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A0h` | | Вход | IX | Адрес 32-байтового дескриптора окна (формат как у WIN_OPEN) | | Вход | HL | Упакованные пиксельные координаты: X + Y×64 + #4000 + #1000×RGMOD | | Вход | E | Бит 0: страница режима | | Выход (CF=0) | — | Успех | ### 0A1h — PIC_POINT Установка точки (пикселя) на экране. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A1h` | | Вход | DE | Координата Y (вертикаль, пиксели) | | Вход | HL | Координата X (горизонталь, пиксели) | | Вход | A | Идентификатор окна | | Вход | B | Цвет точки | | Выход (CF=1) | — | Неверный идентификатор окна | Координаты отсчитываются от верхнего левого угла экрана. ### 0A2h — PIC_FN2 Заполнение или копирование блока. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A2h` | | Вход | DE | Координата Y (вертикаль, пиксели) | | Вход | HL | Координата X (горизонталь, пиксели) | | Вход | IX | Размеры: IXH = вертикальный размер, IXL = горизонтальный | | Вход | A | Цвет заполнения | | Вход | B | Бит 0: `1` = вторая страница режима | | Выход (CF=0) | — | Успех | ### 0A3h — PIC_FN3 Копирование блока между страницами. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A3h` | | Вход | DE | Координата Y назначения | | Вход | HL | Координата X назначения | | Вход | A'HL' | Адрес источника (теневые регистры) | | Вход | BC' | Длина в байтах | | Вход | B | Бит 0: `1` = вторая страница режима | | Выход (CF=0) | — | Успех | ### 0A4h — PIC_SET_PAL Установка палитры. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A4h` | | Вход | HL | Указатель на данные палитры (B,R,G,0 для каждого цвета) | | Вход | E | Номер начального цвета | | Вход | D | Количество устанавливаемых цветов | | Вход | B | Маска (для нормального режима — `0FFh`) | | Вход | A | Бит 0–3: номер палитры (0..7; 8..15 зарезервированы). Бит 7: `0` = установить, `1` = загрузить палитру в память. Биты 4–6: зарезервированы (0). | Формат данных палитры по адресу HL: ```asm DB blue1, green1, red1, 0 DB blue2, green2, red2, 0 ... DB blueN, greenN, redN, 0 ``` N = количество цветов. 0 соответствует 256 цветам. Перед записью в VRAM данные проходят `AND` с маской `B`. > **Примечание:** исходный код BIOS v3.04 (FUNC_SCREEN.ASM:190-261) подтверждает бит 7: `ADD A,A` сдвигает A влево, устанавливая CF из бита 7; при CF=1 выполняется `PIC_GET_PAL` (чтение палитры в память), при CF=0 — установка. IvanMak и Parinov описывают регистр неполно (бит 7 опущен). **Страницы палитры:** - **0–3** — графические режимы (выбор через биты 7–6 байта режима знакоместа) - **4** — PAPER (текстовый и спектрумовский режимы) - **5** — INK - **6** — PAPER в режиме FLASH - **7** — INK в режиме FLASH Для отключения FLASH в конкретном атрибуте: установить цвета палитры 4 = 6 и 5 = 7. Для включения FLASH в режиме IBM-CGA: 6 = 7 = 4 (PAPER мерцает в INK). ### 0A5h — PIC_FN5 Установка страницы режима (RGMOD). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A5h` | | Вход | E | Режим: бит 0 = RGMOD | | Выход | — | Нет | ### 0A6h — SET_PAL_INIT Установка внутренней палитры (инициализация). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A6h` | | Вход | A | Страница палитры | | Вход | B | `1` = графическая палитра, `2` = спектрумовская, `3` = текстовая CGA | | Выход (CF=1) | — | Неверный номер палитры | ### 0A7h — PIC_FN7 Рисование линии. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A7h` | | Вход | DE | Координата Y начала | | Вход | HL | Координата X начала | | Вход | H' | Длина линии (приращение по X) | | Вход | A | Цвет линии | | Вход | B | Бит 0: `1` = вторая страница режима | | Выход (CF=0) | — | Успех | ### 0A8h — PIC_FN8 Рисование линии с массивом цветов. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0A8h` | | Вход | DE | Координата Y начала | | Вход | HL | Координата X начала | | Вход | H' | Длина линии | | Вход | IX | Массив цветов (последовательность байт цвета для каждого пикселя) | | Вход | B | Бит 0: `1` = вторая страница режима | | Выход (CF=0) | — | Успех | --- ## 2.8 Функции диска (50h–5Fh) ### Кодировка номера устройства (для всех DRV-функций) Регистр A = биты 7..4 (тип) + биты 3..0 (номер): | Тип (биты 7..4) | Устройство | |-----------------|-----------| | `0x` | FDD (дисковод) | | `6x` | RAM-DISK | | `8x` | HDD | | `Cx` | CD-ROM | Номер сектора: **HL:IX** — HL = старшая часть, IX = младшая. ### 50h, 52h, 53h — зарезервированы Не реализованы. Вызов без параметров, возврата нет. ### 51h — DRV_RESET Сброс контроллера и настройка на указанное устройство. | | Регистр | Описание | |--|---------|----------| | Вход | C | `51h` | | Вход | A | Номер и тип устройства | | Выход (CF=1) | — | Нет диска или нет устройства | ### 54h — DRV_VERIFY Проверка секторов (внутренняя, на совпадение ECC). | | Регистр | Описание | |--|---------|----------| | Вход | C | `54h` | | Вход | A | Номер и тип устройства | | Вход | HL:IX | Номер сектора | | Вход | B | Количество секторов | | Выход (CF=1) | — | Ошибка проверки | > **Примечание:** функция реализована **только для ATA/HDD** (ATA_5x_VERIFY в ATA_DRV.asm:472). Для FDD, RAM-диска и CD-ROM не поддерживается — возвращает CF=1. В ранних версиях (до v3.0x) действительно отсутствовала. ### 55h — DRV_READ Чтение секторов с устройства. | | Регистр | Описание | |--|---------|----------| | Вход | C | `55h` | | Вход | A | Номер и тип устройства | | Вход | HL:IX | Номер сектора | | Вход | B | Количество секторов | | Вход | DE | Адрес буфера для данных | | Выход (CF=0) | HL:IX | Номер сектора + количество прочитанных | | Выход (CF=0) | DE | Адрес буфера + (количество × размер сектора) | | Выход (CF=1) | — | Ошибка чтения | ### 56h — DRV_WRITE Запись секторов на устройство. | | Регистр | Описание | |--|---------|----------| | Вход | C | `56h` | | Вход | A | Номер и тип устройства | | Вход | HL:IX | Номер сектора | | Вход | B | Количество секторов | | Вход | DE | Адрес буфера с данными | | Выход (CF=0) | HL:IX | Номер сектора + количество записанных | | Выход (CF=0) | DE | Адрес буфера + (количество × размер сектора) | | Выход (CF=1) | — | Ошибка записи | ### 57h — DRV_DETECT Определение параметров устройства (тип носителя). | | Регистр | Описание | |--|---------|----------| | Вход | C | `57h` | | Вход | A | Номер и тип устройства | | Выход (CF=0) | A | Биты: bit7=0 = 720 КБ, bit7=1 = 1.44 МБ | | Выход (CF=1) | — | Нет устройства или носителя | ### 58h — DRV_GET_PAR Получение параметров носителя. | | Регистр | Описание | |--|---------|----------| | Вход | C | `58h` | | Вход | A | Номер и тип устройства | | Выход (CF=0) | L | Число секторов на дорожке | | Выход (CF=0) | H | Число головок | | Выход (CF=0) | DE | Количество цилиндров | | Выход (CF=0) | IX | Размер сектора в байтах | | Выход (CF=0) | B | Доп. параметры: bit7 = тип 1.44/720 | | Выход (CF=1) | — | Нет устройства | Если `HL=DE=0FFFFh` — устройства нет. ### 59h — DRV_SET_PAR Установка параметров носителя. | | Регистр | Описание | |--|---------|----------| | Вход | C | `59h` | | Вход | A | Номер и тип устройства | | Вход | L | Число секторов на дорожке | | Вход | H | Число головок | | Вход | DE | Количество цилиндров | | Вход | IX | Размер сектора в байтах | | Вход | B | Доп. параметры: bit7 = тип 1.44/720 | | Выход (CF=0) | — | Успех | ### 5Ah — EXT_VERSION Версия дисковой спецификации. | | Регистр | Описание | |--|---------|----------| | Вход | C | `5Ah` | | Выход (CF=0) | D | Версия | | Выход (CF=0) | E | Модификация | | Выход (CF=1) | — | Ошибка | ### 5Fh — DRV_LIST Список дисковых устройств. | | Регистр | Описание | |--|---------|----------| | Вход | C | `5Fh` | | Вход | IX | Буфер для списка | | Выход (CF=0) | — | Буфер заполнен | Формат списка в буфере: ``` IX+0 — размер заполненного буфера IX+1 — количество FDD IX+2 — количество HDD IX+3 — количество CD-ROM IX+4 — #00 = конец списка, иначе количество устройств нового типа ``` --- ## 2.9 Дополнительные функции (из IvanMak.txt) ### 80h — LP_OPEN_S Открытие стандартных окон. Вход: A = номер окна (см. таблицу). Выход: CF=1 = ошибка. **Типы стандартных окон:** | A | Описание | |---|----------| | 0 | 32×24 ZX Spectrum | | 1 | 64×24 текстовое | | 2 | 40×32 текстовое | | 3 | 80×32 текстовое | | 4 | 32×24 ZX Spectrum, HL = положение на экране | | 5 | 64×24 текстовое, HL = положение | | 6 | 40×32 текстовое, HL = положение | | 7 | 80×32 текстовое, HL = положение | | 8 | Графическое окно 0, HL = положение | | 9 | Графическое окно 1, HL = положение | ### 0F0h — SPRINTER_1 Переключение конфигурации ППЛМ в Sprinter-1. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0F0h` | | Выход (CF=1) | — | Фатальная ошибка, требуется RESET | Если текущая прошивка уже Sprinter-1 — перезагрузка ПЛМ не производится. ### 0F1h — SPRINTER_2 Переключение в Sprinter-2. Аналогично SPRINTER_1, C=`0F1h`. ### 0F3h — SPRINTER_ALL Переключение на пользовательскую конфигурацию. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0F3h` | | Вход | A | Страница с файлом прошивки ПЛМ (≤127) | | Выход (CF=1) | — | Фатальная ошибка, требуется RESET | Файл прошивки должен быть предварительно загружен в указанную страницу. > **Важно:** во время переключения конфигурации (0F0h–0F3h) происходят сбой синхронизации монитора и перестройка всей схемы. Перед вызовом — DI, после — полная реинициализация периферии. ### Функции с пометкой «в разработке» (из IvanMak.txt) Эти функции перечислены в исходнике, но явно помечены как неготовые: - **0F4h — DCP_FN0**: управление дешифратором портов. Позволит открывать/закрывать дополнительные порты. «В данный момент не доделана». - **0F8h — SET_PORTS**: глобальная установка порта по внутреннему номеру. Позволяет читать/писать любые порты независимо от того, открыты ли они. - **0F9h — READ_PORTS**: глобальное чтение порта. - **0FAh — WRITE_PORTS**: глобальная запись порта. Из комментариев: «В данный момент функции недоступны и находятся в разработке». Позволят читать/писать закрытые системные порты (1FFD, 7FFD) и эмулировать отсутствующие устройства. ### HDD-функции (40h–47h) Подтверждены в исходниках BIOS v3.04 — добавлены к версии 3.06. Перечень: | Номер | Название | |-------|----------| | 40h | HDD_INIT | | 41h | HDD_RECAL | | 42h | HDD_TEST_IDE | | 43h | HDD_PREPARE | | 44h | HDD_READ_BPB | | 45h | HDD_READ | | 46h | HDD_WRITE | | 47h | HDD_PART | ### RAM-Disk функции (0C8h–0CFh) Подтверждены в исходниках BIOS v3.04 — добавлены к версии 3.06: | Номер | Название | |-------|----------| | 0C8h | BLK_RD_WR — чтение/запись блока секторами (256 байт) | | 0C9h | BLK_TO_RAMD — загрузить блок в RAM-disk | | 0CAh | RAMD_CLEAR — очистить RAM-disk | | 0CBh | RAMD_TO_DRV — скопировать RAM-disk на диск | | 0CCh | FDD_TO_DRV — скопировать FDD на устройство | | 0CDh | HDD_TO_DRV — скопировать HDD на устройство | | 0CEh | GET_RAMD_ST — получить статус RAM-disk | | 0CFh | GET_DRV_ST — получить статус устройства | --- ## 2.10 Функции, добавленные к версии 3.06 Следующие функции отсутствуют в документации BIOS_v3.txt и IvanMak, но реализованы в исходных кодах BIOS v3.04. ### Управление памятью и RAM-disk (96h–9Ch) #### 96h — EMM.GetBanksPorts Получение адреса порта окна и текущей страницы (аналог 0C6h с другим форматом вызова). | | Регистр | Описание | |--|---------|----------| | Вход | C | `96h` | | Вход | A | Номер окна (0–3: 0→SLOT0, 1→SLOT1, 2→SLOT2, 3→SLOT3) | | Выход (CF=0) | C | Адрес порта окна | | Выход (CF=0) | B | Текущая физическая страница | | Выход (CF=1) | — | Неверный номер окна | #### 97h — EMM.CheckColdInit Проверка необходимости холодной инициализации (используется при загрузке). | | Регистр | Описание | |--|---------|----------| | Вход | C | `97h` | Если системная страница содержит корректный ID_SPRINTER — тёплый старт (возврат к caller). Если ID не совпадает — переход на полную инициализацию, которая не возвращается. #### 98h — RAMD_CALC_PAGE Расчёт физического адреса сектора RAM-disk. | | Регистр | Описание | |--|---------|----------| | Вход | C | `98h` | | Вход | DE | Track/sector RAM-disk | | Вход | A | Номер RAM-disk (0–15) | | Выход (CF=0) | HL | Физический адрес | | Выход (CF=0) | A | Физическая страница | | Выход (CF=1) | — | Номер RAM-disk ≥ 16 | #### 99h — SET_DISK_REDIR Установка перенаправления диска TR-DOS на указанное устройство. | | Регистр | Описание | |--|---------|----------| | Вход | C | `99h` | | Вход | E | Тип устройства: 0=FDD, 1–3=FDD, 4=RAMD0, 5=RAMD1, 6=RAMD2, 7=RAMD3, 8=HDD | | Выход | A | Предыдущее значение перенаправления | #### 9Ah — GET_DISK_REDIR Получение текущего перенаправления диска. | | Регистр | Описание | |--|---------|----------| | Вход | C | `9Ah` | | Выход (CF=0) | A | Текущий тип устройства (0=FDD, 4=RAMD0, 8=HDD) | #### 9Bh — GET_RAMD_NUM Получение номера RAM-disk по его ID. | | Регистр | Описание | |--|---------|----------| | Вход | C | `9Bh` | | Вход | A | ID RAM-disk | | Выход (CF=0) | A | Номер RAM-disk (0–15) | | Выход (CF=1) | — | RAM-disk с таким ID не найден | #### 9Ch — SWAP_RAM_DRIVES Переключение между наборами Sprinter и ZX RAM-дисков. | | Регистр | Описание | |--|---------|----------| | Вход | C | `9Ch` | | Вход | B | `0` = переключить на Sprinter, `0FFh` = переключить на ZX, `0FEh` = только получить инфо | | Выход | A | Текущий набор RAM-дисков | ### Терминальный вывод (0E0h) #### 0E0h — LP_PR_LINE_DIR Терминальный вывод строки с обработкой управляющих символов (BELL, Backspace, LF, CR). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0E0h` | | Вход | HL | Адрес строки | | Вход | DE | Координаты: D=позиция Y, E=позиция X | | Вход | B | Цвет атрибута | | Вход | A | Управляющий байт | ### PC-link (0E8h–0E9h) #### 0E8h — FN_SEND_BYTE Отправка байта через PC-link (LPT1 параллельный порт, протокол Kempston PC-Link). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0E8h` | | Вход | A | Байт для отправки | | Выход (CF=0) | — | Успех | | Выход (CF=1) | — | Таймаут — PC не отвечает | #### 0E9h — FN_RECEIVE_B Приём байта через PC-link. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0E9h` | | Выход (CF=0) | A | Полученный байт | | Выход (CF=1) | — | Таймаут | ### Клавиатура (0EAh) #### 0EAh — FN_KBD_OUT Посылка байта на внешнюю AT-клавиатуру (через SIO канал A, микросхема Z80182). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0EAh` | | Вход | A | Байт данных | | Вход | B | Параметр скорости | | Выход (CF=0) | — | Успех | ### Микросхема ACEX (0EDh) #### 0EDh — FN_CRIPT Чтение информации о кристалле ACEX CPLD. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0EDh` | | Вход | B | `0` = board ID, `1` = chip version | | Выход (B=0, CF=0) | HL | Номер платы | | Выход (B=0, CF=0) | A | Тип платы | | Выход (B=0, CF=0) | BC | BoardID.start | | Выход (B=0, CF=0) | DE | BoardID.end | | Выход (B=1, CF=0) | A | Версия кристалла (chip_version) | ### Конфигурация AY8910 (0EEh) #### 0EEh — RST_CONF.AY8910 Переключение конфигурации ППЛМ в режим ZX Spectrum + AY8910. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0EEh` | | Выход (CF=0) | — | Успех | ### Режим Spectrum (0FBh–0FCh) #### 0FBh — GOTO_SPEC Переход в режим ZX Spectrum. Устанавливает FDD 720K, переключает ПЗУ, переводит систему в режим совместимости со Spectrum. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0FBh` | #### 0FCh — ZX_MEMORY_MANAGER Переключение на ZX-менеджер страниц памяти (стандартный ZX Spectrum порт 7FFD). | | Регистр | Описание | |--|---------|----------| | Вход | C | `0FCh` | ### REINIT (0FDh) #### 0FDh — REINIT Перезапуск системы с выбором режима. | | Регистр | Описание | |--|---------|----------| | Вход | C | `0FDh` | | Вход | B | `1` = RESTART (полный перезапуск), `2` = Soft reset, `3` = Hard reset, `4` = освобождение всей памяти кроме ZX-страниц | --- ## 2.11 Быстрый вызов RST 8 Для вызова BIOS из EXE-файла через RST 8 в `#0008` устанавливается код: ```asm PUSH AF LD A,0 OUT (7Ch),A ; включить ПЗУ BIOS в W0 POP AF RET ``` Этот код уже присутствует в блоке ОС Estex при загрузке EXE. **Ограничение:** адресное пространство `#0000..#3FFF` во время работы BIOS занято ПЗУ — данные для функций не могут там располагаться. Оптимизация кода для RST 8 недопустима (в ПЗУ стоит обратное переключение через порт `#3Ch`). --- ## 2.12 Кросс-ссылки - DSS/ESTEX: `03-dss.md` - Видеорежимы и палитра: `05-graphics.md` - Порты: `11-ports.md` - Баги BIOS: `12-bugs.md` - Управление окнами DSS (SETWIN/SETWIN1/SETWIN2): `03-dss.md §3.6` - Функции DSS (GET_DRV_ST, SET_DISK_REDIR, EMM): `03-dss.md` - Дескрипторы окон: проектный `libc-reference.md`