Files
Sprinter-SDCC/docs/new/02-bios.md
T
snark13 64ce6339eb docs: справочники по железу Sprinter + правка gfx_scroll_h
- docs/new/ — сводные справочники (архитектура, BIOS, DSS, память,
  графика, акселератор, IRQ, порты, ввод, звук, известные баги);
- docs/Original/ — первоисточники, из которых они собраны (BIOS, Estex
  DSS, мануалы, описание акселератора), + Форум.doc/.docx в reference;
- libbgi/common/gfx_scroll_h.c — обход бага скролла при ширине >256
  (правка автора: шаг банды 255 и продвижение указателей на cw; старый
  вариант с 256 оставлен закомментированным с TODO);
- удалён applications/PoP/roomtest/hang_variants.png — рабочая раскладка
  из разбора позы виса, в репозитории ей не место.

Большие архивы (docs/extra ~568 МБ, docs/sources с вложенными git-репо
~68 МБ) в коммит НЕ включены — см. обсуждение.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 18:26:31 +03:00

1235 lines
53 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 Управление памятью (0C0h0C7h, 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, 0F5h0F7h)
### 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-функции (40h47h)
Подтверждены в исходниках 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 функции (0C8h0CFh)
Подтверждены в исходниках 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 (96h9Ch)
#### 96h — EMM.GetBanksPorts
Получение адреса порта окна и текущей страницы (аналог 0C6h с другим форматом вызова).
| | Регистр | Описание |
|--|---------|----------|
| Вход | C | `96h` |
| Вход | A | Номер окна (03: 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 (015) |
| Выход (CF=0) | HL | Физический адрес |
| Выход (CF=0) | A | Физическая страница |
| Выход (CF=1) | — | Номер RAM-disk ≥ 16 |
#### 99h — SET_DISK_REDIR
Установка перенаправления диска TR-DOS на указанное устройство.
| | Регистр | Описание |
|--|---------|----------|
| Вход | C | `99h` |
| Вход | E | Тип устройства: 0=FDD, 13=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 (015) |
| Выход (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 (0E8h0E9h)
#### 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 (0FBh0FCh)
#### 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`