# 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`
