1 Commits

Author SHA1 Message Date
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
32 changed files with 23762 additions and 3 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.
+893
View File
@@ -0,0 +1,893 @@
# Функции BIOS v2.12
### Вызов функций BIOS
Вызов функций BIOS осуществляется из ассемблерного кода.
Номер функции задается в регистре C процессора. В остальные регистры,
при необходимости, загружаются входные параметры функции. После исполнения
функции происходит возврат в программу, из которой произошел вызов функции.
Установленный флаг CF (CF=1) означает, что работа функции произошла с
ошибкой. В некоторых регистрах передаются выходные параметры.
Ниже приведены таблицы входных и выходных параметров для каждой функции:
- Функции работы с памятью
- Функции управления 'железом'
- Функции управления окнами и режимами экрана
- Функции вывода текста на экран
- Графические функции
- Функции работы с жесткими дисками и дисководами
При работе функций BIOS необходимо что бы стек находился в области
8000h..0BFFFh, так как часть функций использует переключение страниц
PAGE1 и PAGE3.
Вызов функций BIOS возможен в различных конфигурациях компьютера Sprinter.
Конфигурация Spectrum: вызов функций BIOS осуществляется через 3D13h.
При этом работают и все функции TR-DOS.
Конфигурации Sprinter: вызов функций BIOS осуществляется через RST 18h
при подключенном системном ПЗУ.
Для постоянного подключения системного ПЗУ можно воспользоваться
такой последовательностью команд:
```asm
LD A,0
OUT (07Ch),A
```
После ее исполнения в 0-м окне Z80 будет включено ПЗУ BIOSа и программа
может вызывать функции BIOSа через RST 18h.
Отключение ПЗУ BIOSа из нулевого окна Z80 производится следующей
последовательностью команд:
```asm
LD A,0
OUT (03Ch),A
```
При необходимости, функции BIOSа могут быть вызваны программой, находящейся
в ОЗУ непосредственно в нулевом окне Z80. Для этого надо установить в
адресе 0008h следующий код:
```asm
ADDRESS_0008h:
PUSH AF
LD A,0
OUT (7Ch),A
POP AF
RET
```
После этого BIOS можно вызывать командой RST 8. (Функции TR-DOS, так
же как и в случае RST 18 остаются недоступны.) Вызывая программы таким
образом, через RST 8, следует помнить что адреса 3FFFh..0000h после входа
в BIOS будут содержать код ПЗУ, поэтому, если фунция использует данные в
ОЗУ, они должны находиться в других адресах.
Оптимизация программы для RST 8 недопустима, так как в ПЗУ, для
обратного переключения, стоит такая же программа, только порт 3Ch для
отключения ПЗУ BIOSа.
Вызов функций BIOS в exe-файлах, вызываемых с помощью операционной
системы Estex, производится командой RST 8. Необходимая программа в адресе
0008h уже имеется в блоке кода ОС Estex.
### Функции работы с памятью
**0C0h (192) EMM_FN0 Определение объемов ОЗУ**
Значение регистров на входе:
C=0C0h
Значение регистров на выходе:
HL - общий объем ОЗУ в страницах по 16k
BC - объем свободного ОЗУ в страницах по 16k
**0C1h (193) EMM_FN1 Инициализация распределения памяти**
Стирается вся информация о выделенных ранее блоках ОЗУ.
Блоки с системной информацией и первые 256K ОЗУ объявляются занятыми.
Значение регистров на входе:
C=0C1h
Значение регистров на выходе:
нет
**0C2h (194) EMM_FN2 Выделение блока ОЗУ**
Значение регистров на входе:
C=0C2h
B - число запрашиваемых страниц
Значение регистров на выходе:
CF=0 - нормальное завершение - A - идентификатор блока
CF=1 - ошибка - A=1 - не хватает памяти
**0C3h (195) EMM_FN3 Освободить блок ОЗУ**
Значение регистров на входе:
C=0C3h
A - идентификатор блока
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неправильный идентификатор
идентификатор не всегда отслеживается правильно
**0C4h (196) EMM_FN4 Получить физический номер страницы из блока памяти**
Значение регистров на входе:
C=0C4h
A - идентификатор блока
B - логическая номер страницы в блоке
Значение регистров на выходе:
CF=0 - A - логический номер страницы
CF=1 - ошибка:
A=0 - блок не существует
A=255 - запрашиваемый номер страницы слишком велик
**0C5h (197) EMM_FN5 Получить список физических страниц блока**
Значение регистров на входе:
C=0C5h
A - идентификатор блока
HL - буфер 256 байт для размещения списка страниц
Значение регистров на выходе:
CF=0 - нормальное завершение:
B - число страниц в блоке
HL - тот же адрес буфера, в буфере список физических
страниц по порядку, заканчивающийся байтом 0FFh
CF=1 - неверный идентификатор блока; старая информация в буфере
может быть затерта
**0C6h (198) EMM_FN6 Получение адресов портов окон**
Примечание по использованию функции получения адресов портов окон (0C6h):
>Cледует хотя бы один раз вызвать эти функции и сравнить адреса
>портов с теми, что используются в программе и, если они не совпадают,
>выдать соответствующее предупреждение. В данный момент эти порты
>таковы: PAGE0=82h, PAGE1=0A2h, PAGE2=0C2h, PAGE3=0E2h
Значение регистров на входе:
C=0C6h
A - номер окна процессора - 0,1,2 или 3
Значение регистров на выходе:
CF=0 - нормальное завершение
C - 8-битный адрес порта окна
B - физический номер подключенной в окно страницы
CF=1 - ошибка - неверный номер окна
**0C7h (199) EMM_FN7 Получить номер следующей страницы блока**
Примечание по использованию функции EMM_FN7 (0C7h):
> Информация о распределении памяти хранится в виде RAM Allocation Table,
> похожей на дисковый FAT. Поэтому нахождение физического номера
> следующей страницы по предыдущему физическому номеру происходит
> значительно быстрее, чем поиск по увеличенному на единицу логическому
> номеру.
Значение регистров на входе:
C=0C7h
A - физическая страница
Значение регистров на выходе:
CF=0 - нормальное завершение
A - следуюшая физическая страница блока
A=0FFh - индицирует конец блока
CF=1 - ошибка - страница не принадлежит никакому блоку.
фактически, это означает, что она свободна.
**09Eh (158) EMM_FN8 Слияние блоков**
Значение регистров на входе:
A - идентификатор блока 1
B - идентификатор блока 2
Значение регистров на выходе:
CF=0 - нормальное завершение
A - идентификатор объединенного блока
CF=1 - ошибка - неверный идентификатор блока
**09Dh (157) EMM_FN9 Разделение блока**
Значение регистров на входе:
C=09Dh
A - идентификатор блока
B - новая длина блока
Значение регистров на выходе:
CF=0 - нормальное завершение
A - идентификатор блока результата
B - идентификатор блока остатка
CF=1 - ошибка - неверный идентификатор блока
### Функции управления 'железом'
**0EFh (239) FN_VERSION Выдача информации о версии BIOSа и железа.**
Значение регистров на входе:
C=0EFh
HL - буфер, куда будет помещена ASCII строка с несколькими
полями, номером версии BIOS и названием модели
компьютера. Конец строки отмечен двойным нулем.
Значение регистров на выходе:
CF=0 - нормальное завершение
HL - тот же буфер с записанной строкой.
DE - версия BIOSа
BC - версия железа подробности ниже
A - количество полей в буфере (в данный момент - 2)
Первое поле - версия BIOS.
Второе - название модели компьютера.
CF=1 - ошибка - Очень старая версия,
не имеющая данной функции
**0F2h (242) FN_SICF=0 Установка синхронизации, очистка страницы режима экрана**
Значение регистров на входе:
C=0F2h
A - режим синхронизации
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный номер режима синхронизации
### Функции работы с CMOS данными и Turbo режимом
Комментарий к функциям CMOS (0F5h-0F7h):
> Функции CMOS_RD, CMOS_WR, CMOS_TEST работают всегда. Если в машине нет
> микросхемы CMOS, то эмулируется ее память. Наличие микросхемы
> определяется функцией CMOS_TEST.
**0F5h (245) CMOS_TEST Проверить наличие CMOS**
Значение регистров на входе:
C=0F5h
Значение регистров на выходе:
CF=0 - часы есть
CF=1 - часов нет
**0F6h (246) CMOS_RD Читать из регистра CMOS**
Значение регистров на входе:
C=0F6h
D - номер регистра CMOS
Значение регистров на выходе:
A - считанные данные
CF=0 - часы есть
CF=1 - часов нет
**0F7h (247) CMOS_WR Писать в регистр CMOS**
Значение регистров на входе:
C=0F7h
D - номер регистра CMOS
A - записываемые данные
Значение регистров на выходе:
CF=0 - часы есть
CF=1 - часов нет
**08Fh (143) FN_TURBO Функция управления турбо режимом.**
Комментарий к функции FN_TURBO (08Fh):
Переключение режима турбо может не произойти, если прошивка не
поддерживает это переключение. При этом ошибки не происходит. Так
же, переключение режима TURBO блокируется кнопкой "Turbo" в
режиме Turbo-OFF
Значение регистров на входе:
C=08Fh
A - режим турбо: 2 - off, 3 - on
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный режим турбо
### Функции управления окнами и режимами экрана
**0B0h (176) WIN_OPEN Функция открытия окна.**
Значение регистров на входе:
C=0B0h
IX - описатель окна
E - флаги окна:
бит 0 указывает какую страницу режима включать после
исполнения функции;
бит 4 указывает на какой странице режима открывать окно
Значение регистров на выходе:
CF=0 - нормальное завершение:
A - идентификатор окна
CF=1 - ошибка слишком много окон
**0B1h (177) WIN_CLOSE закрытие окна**
Значение регистров на входе:
C=0B1h
A - идентификатор окна
Значение регистров на выходе:
CF=0 - успешное завершение
CF=1 - ошибка - неверный идентификатор
Окно с номером 0 никогда не закрывается и попытка
закрытия приводит к ошибке
**0B2h (178) WIN_COPY_WIN Копирование данных текстового окна в память (запоминание окна)**
При работе этой функции через RST 18h или RST 8, обязателен запрет
прерываний, так как функция пользуется стеком для ускорения своей работы.
Значение регистров на входе:
C=0B2h
A - идентификатор глобального окна
H - размер окна в символах по вертикали
L - размер окна в символах по горизонтали
D - вертикальное положение окна в глобальном окне
E - горизонтальное положение окна в глобальном окне
IX - адрес буфера для запоминания данных
адрес буфера указывается для окна 0C000h если адрес
указан с 8000h, номер страницы буфера не действителен
ниже 8000h адрес указывать нельзя
A' - страница буфера для данных окна эта страница должна
принадлежать программе
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка - неверный идентификатор окна
**0B3h (179) WIN_RESTORE_WIN Копирование из памяти в текстовое окно (восстановление окна)**
При работе этой функции через RST 18h или RST 8, обязателен запрет
прерываний, так как функция пользуется стеком для ускорения своей работы.
Значение регистров на входе:
C=0B2h
A - идентификатор глобального окна
H - размер окна в символах по вертикали
L - размер окна в символах по горизонтали
D - вертикальное положение окна в глобальном окне
E - горизонтальное положение окна в глобальном окне
IX - адрес буфера для запоминания данных
адрес буфера указывается для окна 0C000h если адрес
указан с 8000h, номер страницы буфера не действителен
ниже 8000h адрес указывать нельзя
A' - страница буфера для данных окна эта страница должна
принадлежать программе
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка - неверный идентификатор окна
**0B4h (180) WIN_GET_SYM Взять символ с экрана**
Значение регистров на входе:
C=0B4h
A - идентификатор окна
DE - положение символа в окне:
D - вертикаль, E - горизонталь
Значение регистров на выходе:
CF=0 - нормальное завершение
L - символ, H - атрибут,
B - знакогенератор
CF=1 - ошибка неверный идентификатор окна
**0B5h (181) WIN_PUT_SYM Положить символ на экран**
Значение регистров на входе:
C=0B5h
A - идентификатор окна
DE - положение символа в окне:
D - вертикаль, E - горизонталь
L - символ, H - атрибут символа
B - знакогенератор
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка неверный идентификатор окна
**0B6h (182) WIN_SET_ZG установка знакогенератора**
Значение регистров на входе:
C=0B6h
A - системный номер знакогенератора
DE - указатель на 2Kb блок данных знакогенератора
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка (старая версия, нет функции)
**0B7h (183) WIN_MOVE_WIN Перемещение окна**
При работе этой функции через RST 18h или RST 8, обязателен запрет
прерываний, так как функция пользуется стеком для ускорения своей работы.
Значение регистров на входе:
C=0B7h
A - идентификатор глобального окна
H - размер локального окна по вертикали в символах
L - размер локального окна по горизонтали в символах
D - положение локального окна по вертикали в символах
E - положение локального окна по горизонтали в символах
IX - новое положение локального окна (подобно DE)
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка - неверный идентификатор окна
**0B8h (184) WIN_GET_ZG Получение знакогенератора**
Значение регистров на входе:
C=0B8h
DE - адрес, куда будет загружено 2kb знакогенератора
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка (старая версия, нет функции)
### Функции вывода текста на экран
**081h (129) LP_PRINT_ALL Печать символов с атрибутом**
На экран выводится строка из B одинаковых символов
Значение регистров на входе:
C=081h
A - символ
E - атрибут
B - число выводимых символов
регистры HL,IX - сохраняются
Значение регистров на выходе:
CF=0 - всегда
**082h (131) LP_PRINT_SYM Вывод символов на экран без атрибута**
На экран выводится строка из B одинаковых символов атрибут
остается тот, который был на экране
Значение регистров на входе:
C=082h
A - символ
B - число выводимых символов
регистры HL,IX - сохраняются
Значение регистров на выходе:
CF=0 - всегда
**083h (131) LP_PRINT_ATR печать атрибутов**
На экран выводится строка из B одинаковых атрибутов.
Символы не меняются.
Значение регистров на входе:
C=083h
E - атрибут
B - число выводимых символов
регистры HL,IX - сохраняются
Значение регистров на выходе:
CF=0 - всегда
**084h (132) LP_SET_PLACE Установка текущего знакоместа в окне**
Позиция печати устанавливается в соответстии с регистром DE
Значение регистров на входе:
C=084h
E - положение символа по горизонтали
D - номер символа по вертикали
Превышение границ приводит не к ошибке, а к переустановке
с начала, за вычетом полного размера окна
Значение регистров на выходе:
CF=0 - всегда
**085h (133) LP_PRINT_LN Вывод строки символов на экран с текущего знакоместа**
Значение регистров на входе:
C=085h
HL - адрес строки должен быть между 04000h и 0BFFFh
E - атрибут, с которым будет выведена строка
B - длина выводимой строки
Значение регистров на выходе:
CF=0 - всегда
**086h (134) LP_PRINT_LN2 Вывод строки символов на экран без атрибутов**
Значение регистров на входе:
C=086h
HL - адрес строки должен быть между 04000h и 0BFFFh
B - длина выводимой строки
Значение регистров на выходе:
CF=0 - всегда
**087h (135) LP_PRINT_LN3 Вывод строки символов до разделителя**
После разделителя выводятся пробелы, что бы вывести B символов
Значение регистров на входе:
C=087h
HL - адрес строки должен быть между 04000h и 0BFFFh
E - атрибут, с которым будет выведена строка
B - длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**088h (136) LP_PRINT_LN4 Вывод строки символов до разделителя, без атрибутов**
символы из выводятся на экран, пока не встретится символ равный D,
далее печатаются пробелы, как дополнение строки до B символов.
Атрибуты не изменяются.
Значение регистров на входе:
C=088h
HL - адрес строки должен быть между 04000h и 0BFFFh
B - длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**089h (137) LP_CLS_WIN Очистка экрана**
Выполнение производится выводом пробелов с заданным атрибутом
Значение регистров на входе:
C=089h
DE - положение локального окна
H - размер в символах локального окна по вертикали
L - размер в символах локального окна по горизонтали
B - атрибут очистки
Значение регистров на выходе:
CF=0 - всегда
**08Ah (138) LP_SCROLL_UD Скроллинг части глобального окна вверх/вниз**
Скроллируются полные строки глобального окна
Значение регистров на входе:
C=08Ah
B - тип скроллинга: 1 - вверх; 2 - вниз
D - начальная строка скроллинга
E - число скроллируемых строк
Значение регистров на выходе:
CF=0 - всегда
**08Bh (139) LP_PRINT_LN5 Вывод строки символов на экран до разделителя**
После разделителя вывод останавливается
Значение регистров на входе:
HL - адрес строки должен быть между 04000h и 0BFFFh
E - атрибут, с которым будет выведена строка
B - максимальная длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**08Ch (140) LP_PRINT_LN6 Вывод строки символов на экран до разделителя без атрибутов**
После разделителя вывод останавливается.
Значение регистров на входе:
C=08Ch
HL - адрес строки должен быть между 04000h и 0BFFFh
B - максимальная длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**08Dh (141) LP_CLS_WIN2 Очистка экрана с указанием символа заполнения**
Значение регистров на входе:
C=08Dh
DE - положение локального окна
H - размер в символах локального окна по вертикали
L - размер в символах локального окна по горизонтали
B - атрибут очистки
A - символ очистки
Значение регистров на выходе:
CF=0 - всегда
**08Eh (142) LP_GET_PLACE Получить текущее положение вывода на экран**
Значение регистров на входе:
C=08Eh
Значение регистров на выходе:
CF=0 - всегда
DE - координаты, в которых будет напечатан
следующий символ:
D - вертикаль, E - горизонталь
### Графические функции
**0A1h (161) PIC_POINT Установить точку**
Значение регистров на входе:
C=0A1h
DE - координата по вертикали (пиксели)
HL - координата по горизонтали (пиксели)
Координаты считаются от верхнего левого угла экрана
A - идентификатор окна
B - цвет точки
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный идентификатор окна
**0A4h (164) PIC_SET_PAL Установка палитры**
Значение регистров на входе:
C=0A4h
HL - данные палитры
E - номер начального цвета
D - количество устанавливаемых цветов
B - маска при установке палитры.
Для нормального режима должнa быть 0FFh
A - номер палитры 0..15; от 8 до 15 - резервные
Значение регистров на выходе:
CF=0 - всегда
**0A6h (166) SET_PAL_INIT Установка внутренней палитры**
Значение регистров на входе:
C=0A6h
A - страница палитры
B - номер палитры:
B=2 - установка спектрумовской палитры
B=1 - установка графической плаитры
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный номер палитры
### Функции работы с жесткими дисками и дисководами
**50h,52h,53h (80,82,83) Зарезервированы**
Значение регистров на входе и на выходе:
нет
**51h (81) DRV_RESET Сброс контроллера и настройка на диск**
Значение регистров на входе:
C=51h
A - номер и тип устройства
бит 7..4 - тип устройства:
#0x - FDD
#6x - RAM-DISK
#8x - HDD
#Cx - CD-ROM
бит 3..0 - номер устройства
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка, нет диска или нет устройства
**54h (84) DRV_VERIFY Проверка секторов**
Проверка внутренняя на совпадение ECC
Значение регистров на входе:
C=54h
A - номер и тип устройства (см. выше)
HL:IX - номер сектора (IX - младшая часть номера сектора)
B - количество проверяемых секторов
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - проверка с ошибкой
**55h (85) DRV_READ Чтение с устройства**
Значение регистров на входе:
C=55h
A - номер и тип устройства (см. выше)
HL:IX - номер сектора (IX - младшая часть номера сектора)
B - количество секторов
DE - адрес буфера для данных
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка чтения
HL:IX - номер сектора + кол-во прочитанных секторов
DE - адрес буфера для данных + (кол-во прочитанных секторов * размер сектора)
**56h (86) DRV_WRITE Запись на устройства**
Значение регистров на входе:
C=56h
A - номер и тип устройства (см. выше)
HL:IX - номер сектора (IX - младшая часть номера сектора)
B - количество секторов
DE - адрес буфера данных для записи
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка записи
HL:IX - номер сектора + кол-во прочитанных секторов
DE - адрес буфера для данных + (кол-во прочитанных секторов * размер сектора)
**57h (87) DRV_DETECT Определение параметров устройства**
Значение регистров на входе:
C=57h
A - номер и тип устройства (см. выше)
Значение регистров на выходе:
CF=0 - нормальное завершение
A - bit7=0 диск 720Кb
bit7=1 диск 1.44Mb
CF=1 - нет устройства или нет носителя
**58h (88) DRV_GET_PAR Получить параметры носителя**
Значение регистров на входе:
C=58h
A - номер и тип устройства (см. выше)
Значение регистров на выходе:
CF=0 - нормальное завершение
L - число секторов
H - число головок
DE - количество цилиндров
если HL=DE=0FFFFh - устройства нет
IX - размер сектора в байтах
B - доп. параметры для дискет:
бит7 - тип 1.44Mb/720Kb
CF=1 - нет устройства
**59h (89) DRV_SET_PAR Установить параметры носителя**
Значение регистров на входе:
A - номер и тип устройства (см. выше)
L - число секторов
H - число головок
DE - количество цилиндров
IX - размер сектора в байтах
B - доп. параметры для дискет
бит7 - тип 1.44Mb/720Kb
Значение регистров на выходе:
CF=0 - нормальное завершение
**5Ah (90) EXT_VERSION Номер версии дисковой спецификации.**
Значение регистров на входе:
C=5Ah
Значение регистров на выходе:
CF=0 - нормальное завершение
D - версия
E - модификация
CF=1 - ошибка
**5Fh (95) DRV_LIST Список дисковых устройств**
Значение регистров на входе:
C=5Fh
IX - буфер для списка устройств
Значение регистров на выходе:
CF=0 - нормальное завершение
В буфере список дисков в формате:
IX+0 - размер заполненого буфера
IX+1 - кол-во устройств FDD
IX+2 - кол-во устройств HDD
IX+3 - кол-во устройств CD DRIVE
IX+4 - #00 - конец списка, иначе кол-во устройств нового типа
### Примечания и комментарии.
##### *Примечание по использованию функции получения адресов портов окон (0C6h).*
Cледует хотя бы один раз вызвать эти функции и сравнить адреса портов с
теми, что используются в программе и, если они не совпадают, выдать
соответствующее предупреждение. В данный момент эти порты таковы:
PAGE0=82h, PAGE1=0A2h, PAGE2=0C2h, PAGE3=0E2h
##### *Примечание по использованию функции EMM_FN7 (0C7h).*
Информация о распределении памяти хранится в виде RAM Allocation Table,
похожей на дисковый FAT. Поэтому нахождение физического номера следующей
страницы по предыдущему физическому номеру происходит значительно быстрее,
чем поиск по увеличенному на единицу логическому номеру.
##### *Комментарий к функции FN_VERSION (0EFh).*
Значения регистра BC на выходе и соответствующая ему конфигурация
BC=FFFF - Не определено
BC=FFFE - Конфигурация Spectrum, режим Sprinter ZX
BC=FFFD - Конфигурация Sprinter
BC=FFFC - Зарезервировано
BC=FFFB - Зарезервировано
BC=FFFA - Зарезервировано
BC=FFF9 - Зарезервировано
Иные значения BC - новые прошивки.
##### *Комментарий к функциям CMOS (0F5h-0F7h)*
Функции CMOS_RD, CMOS_WR, CMOS_TEST работают всегда. Если в машине нет
микросхемы CMOS, то эмулируется ее память. Наличие микросхемы
определяется функцией CMOS_TEST.
##### *Комментарий к функции FN_TURBO (08Fh)*
Переключение режима турбо может не произойти, если прошивка не
поддерживает это переключение. При этом ошибки не происходит. Так же,
переключение режима TURBO блокируется кнопкой "Turbo" в режиме Turbo-OFF
##### *Комментарий к функциям печати текста.*
Эти функции работают с текущим окном, которым всегда является последнее
открытое окно. К графическому экрану функции печати текста не применимы.
##### *Описатель окна.*
Для открытия окон используется 32-хбайтовый описатель окна (дескриптор),
адрес которого указывается в регистре IX.
IX - 32-хбайтовый описатель окна
(IX+0) - горизонтальный размер окна в знакоместах
(IX+1) - вертикальный размер в знакоместах
(IX+2) - положение окна по горизонтали на экране в знакоместах
(IX+3) - положение окна по вертикали на экране в знакоместах
(IX+4) - режим знакоместа
bit4=1 - text_mode bit4=0 - graf_mode
bit5=0 - 16, bit5=1 - 8 точек в знакоместе
graf_mode bit3..0 - не существенны
bit7..6 - номер палитры
text_mode bit7..6,3..0 - номер знакогенератора
исключение: bit7..6=B"11" - бордер
(IX+5) - дополнительный режим знакоместа
bit0=1 - указывает на включение спектрумовской
адресации экрана
(IX+6) - положение по X в поле графики (по знакоместам)
(IX+7) - положение по Y в поле графики (по знакоместам)
разъяснения о положении в поле графики - ниже
(IX+8..31) - зарезервировано (переменные окна)
в этих байтах должны быть нули
При открытии окна описатель копируется в системную страницу ОЗУ и
программа может не сохранять его. Что бы описатель окна не потерялся,
программа получает идентификатор окна. Он же идентификатор глобального
окна. В функциях запоминания, восстановления, перемещения, а так же
функциях стирания, скроллинга и т.п. идентификатор окна определяет
область экрана, относительно которой производится работа с локальными
окнами. Подразумеваются локальные окна в смысле "окно в окне".
Идентификатор окна определяет глобальное окно, отнoсительно которого
адресуются локальные. В части функций глобальное окно определяется по
умолчанию, как последнее, с которым производились действия с явным
указанием идентификатора.
В данный момент BIOS хранит только один описатель окна - последний,
с которым была произведена функция открытия. Идентификатор окна
выставляется в 0. В дальнейшем планитруется разработка функций со
множеством окон, потому, во избежание неприятностей в будущем, при
работе с окнами, программисту следует запоминать идентификатор окна
и пользоваться этим значением при работе с ним.
Типы стандартных окон:
0 - окно 32x24 в формате ZX Spectrum
1 - текстовое окно 64x24
2 - текстовое окно 40x32
3 - текстовое окно 80x32
4 - окно в формате ZX Spectrum, HL - положение окна на экране в знакоместах
5 - текстовое окно 64x24, HL - положение окна на экране в знакоместах
6 - текстовое окно 40x32, HL - положение окна на экране в знакоместах
7 - текстовое окно 80x32, HL - положение окна на экране в знакоместах
8 - графическое окно 0, HL - положение окна на экране
9 - графическое окно 1, HL - положение окна на экране
Данные палитры должны представлять собой список приблизительно такого вида:
DB blue1,green1,red1,0
DB blue2,green2,red2,0
.....................
DB blueN,greenN,redN,0
N - количество цветов. Значеное равное 0 соответствует 256-ти цветам.
При записи в видео-ОЗУ все данные предварительно проходят функцию AND
со значением регистра маски - B.
Страницы палитры 0..3 соответствуют графическим режимам. Для вывода в
соответствующей палитре нужно задать соответствующее значение bit7..6 в
байте режима знакоместа
Страницы 4..7 соответствуют текстовому режиму и спектрумовскому режиму.
В странице 4 задается цвет PAPER для каждого атрибута. В странице 5
задается цвет INK для каждого атрибута. В странице 6 задается цвет PAPER,
которым он будет моргать в режиме FLASH В странице 7 задается цвет INK,
которым он будет моргать в режиме FLASH. Таким образом, для каждого из
256-ти атрибутов задается четыре цвета если цвета 4,5 совпадают с
цветами 6,7 то режим FLASH оказывается отключенным. Для его включения
в спектрумовском режиме надо поменять местами цвета 6 и 7. Если надо
включить FLASH в режим IBM-CGA, следует установить цвета 6 и 7
одинаковыми и равными цвету 4. По сути режим FLASH всегда включен, и
на экране постоянно меняются цвета PAPER с 4-го на 6-й, а цвета INK с
5 на 7-й. Если эти пары цветов для атрибута знакоместа устанавливаются
одинаковыми, то FLASH в этом месте не виден.
##### *Комментарий к функциям работы с устройствами хранения информации.*
В этих функциях в регистре A обычно задается номер и тип устройства:
бит 0..3 - номер устройства
бит 4..7 - тип устройства:
0 - дисковод
6 - ram-disk
8 - HDD
C - CD-ROM
остальные номера не используются
А так же задаются: старшая часть номера сектора в регисте HL,
младшая часть номера сектора в регистре IX.
@@ -0,0 +1,901 @@
# Функции BIOS v3.00
### Вызов функций BIOS
**Вызов функций BIOS осуществляется из ассемблерного кода.**
Номер функции задается в регистре C процессора. В остальные
регистры, при необходимости, загружаются входные параметры функции.
После исполнения функции происходит возврат в программу, из которой
произошел вызов функции. Установленный флаг CF (CF=1) означает, что
работа функции произошла с ошибкой. В некоторых регистрах передаются
выходные параметры.
Ниже приведены таблицы входных и выходных параметров для каждой функции:
- Функции работы с памятью
- Функции управления 'железом'
- Функции управления окнами и режимами экрана
- Функции вывода текста на экран
- Графические функции
- Функции работы с жесткими дисками и дисководами
При работе функций BIOS необходимо что бы стек находился в области
8000h..0BFFFh, так как часть функций использует переключение страниц
PAGE1 и PAGE3.
Вызов функций BIOS возможен в различных конфигурациях компьютера
Sprinter.
**Конфигурация Spectrum:** вызов функций BIOS осуществляется через
3D13h. При этом работают и все функции TR-DOS.
**Конфигурации Sprinter:** вызов функций BIOS осуществляется через RST
18h при подключенном системном ПЗУ.
Для постоянного подключения системного ПЗУ можно воспользоваться такой
последовательностью команд:
```asm
LD A,0
OUT (07Ch),A
```
После ее исполнения в 0-м окне Z80 будет включено ПЗУ BIOSа и программа
может вызывать функции BIOSа через RST 18h.
Отключение ПЗУ BIOSа из нулевого окна Z80 производится следующей
последовательностью команд:
```asm
LD A,0
OUT (03Ch),A
```
При необходимости, функции BIOSа могут быть вызваны программой,
находящейся в ОЗУ непосредственно в нулевом окне Z80. Для этого надо
установить в адресе 0008h следующий код:
```asm
ADDRESS_0008h:
PUSH AF
LD A,0
OUT (7Ch),A
POP AF
RET
```
После этого BIOS можно вызывать командой RST 8. (Функции TR-DOS, так
же как и в случае RST 18 остаются недоступны.) Вызывая программы таким
образом, через RST 8, следует помнить что адреса 3FFFh..0000h после
входа в BIOS будут содержать код ПЗУ, поэтому, если фунция использует
данные в ОЗУ, они должны находиться в других адресах.
Оптимизация программы для RST 8 недопустима, так как в ПЗУ, для
обратного переключения, стоит такая же программа, только порт 3Ch для
отключения ПЗУ BIOSа.
Вызов функций BIOS в exe-файлах, вызываемых с помощью операционной
системы Estex, производится командой RST 8. Необходимая программа в
адресе 0008h уже имеется в блоке кода ОС Estex.
### Функции работы с памятью
**0C0h (192) EMM_FN0 Определение объемов ОЗУ**
Значение регистров на входе:
C=0C0h
Значение регистров на выходе:
HL - общий объем ОЗУ в страницах по 16k
BC - объем свободного ОЗУ в страницах по 16k
**0C1h (193) EMM_FN1 Инициализация распределения памяти**
Стирается вся информация о выделенных ранее блоках ОЗУ.
Блоки с системной информацией и первые 256K ОЗУ объявляются занятыми.
Значение регистров на входе:
C=0C1h
Значение регистров на выходе:
нет
**0C2h (194) EMM_FN2 Выделение блока ОЗУ**
Значение регистров на входе:
C=0C2h
B - число запрашиваемых страниц
Значение регистров на выходе:
CF=0 - нормальное завершение - A - идентификатор блока
CF=1 - ошибка - A=1 - не хватает памяти
**0C3h (195) EMM_FN3 Освободить блок ОЗУ**
Значение регистров на входе:
C=0C3h
A - идентификатор блока
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неправильный идентификатор
идентификатор не всегда отслеживается правильно
**0C4h (196) EMM_FN4 Получить физический номер страницы из блока памяти**
Значение регистров на входе:
C=0C4h
A - идентификатор блока
B - логическая номер страницы в блоке
Значение регистров на выходе:
CF=0 - A - логический номер страницы
CF=1 - ошибка:
A=0 - блок не существует
A=255 - запрашиваемый номер страницы слишком велик
**0C5h (197) EMM_FN5 Получить список физических страниц блока**
Значение регистров на входе:
C=0C5h
A - идентификатор блока
HL - буфер 256 байт для размещения списка страниц
Значение регистров на выходе:
CF=0 - нормальное завершение:
B - число страниц в блоке
HL - тот же адрес буфера, в буфере список физических
страниц по порядку, заканчивающийся байтом 0FFh
CF=1 - неверный идентификатор блока; старая информация в буфере
может быть затерта
**0C6h (198) EMM_FN6 Получение адресов портов окон**
Примечание по использованию функции получения адресов портов окон (0C6h):
>Cледует хотя бы один раз вызвать эти функции и сравнить адреса
>портов с теми, что используются в программе и, если они не совпадают,
>выдать соответствующее предупреждение. В данный момент эти порты
>таковы: PAGE0=82h, PAGE1=0A2h, PAGE2=0C2h, PAGE3=0E2h
Значение регистров на входе:
C=0C6h
A - номер окна процессора - 0,1,2 или 3
Значение регистров на выходе:
CF=0 - нормальное завершение
C - 8-битный адрес порта окна
B - физический номер подключенной в окно страницы
CF=1 - ошибка - неверный номер окна
**0C7h (199) EMM_FN7 Получить номер следующей страницы блока**
Примечание по использованию функции EMM_FN7 (0C7h):
> Информация о распределении памяти хранится в виде RAM Allocation Table,
> похожей на дисковый FAT. Поэтому нахождение физического номера
> следующей страницы по предыдущему физическому номеру происходит
> значительно быстрее, чем поиск по увеличенному на единицу логическому
> номеру.
Значение регистров на входе:
C=0C7h
A - физическая страница
Значение регистров на выходе:
CF=0 - нормальное завершение
A - следуюшая физическая страница блока
A=0FFh - индицирует конец блока
CF=1 - ошибка - страница не принадлежит никакому блоку.
фактически, это означает, что она свободна.
**09Eh (158) EMM_FN8 Слияние блоков**
Значение регистров на входе:
A - идентификатор блока 1
B - идентификатор блока 2
Значение регистров на выходе:
CF=0 - нормальное завершение
A - идентификатор объединенного блока
CF=1 - ошибка - неверный идентификатор блока
**09Dh (157) EMM_FN9 Разделение блока**
Значение регистров на входе:
C=09Dh
A - идентификатор блока
B - новая длина блока
Значение регистров на выходе:
CF=0 - нормальное завершение
A - идентификатор блока результата
B - идентификатор блока остатка
CF=1 - ошибка - неверный идентификатор блока
### Функции управления 'железом'
**0EFh (239) FN_VERSION Выдача информации о версии BIOSа и железа.**
Значение регистров на входе:
C=0EFh
HL - буфер, куда будет помещена ASCII строка с несколькими
полями, номером версии BIOS и названием модели
компьютера. Конец строки отмечен двойным нулем.
Значение регистров на выходе:
CF=0 - нормальное завершение
HL - тот же буфер с записанной строкой.
DE - версия BIOSа
BC - версия железа подробности ниже
A - количество полей в буфере (в данный момент - 2)
Первое поле - версия BIOS.
Второе - название модели компьютера.
CF=1 - ошибка - Очень старая версия,
не имеющая данной функции
**0F2h (242) FN_SICF=0 Установка синхронизации, очистка страницы режима экрана**
Значение регистров на входе:
C=0F2h
A - режим синхронизации
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный номер режима синхронизации
### Функции работы с CMOS данными и Turbo режимом
Комментарий к функциям CMOS (0F5h-0F7h):
> Функции CMOS_RD, CMOS_WR, CMOS_TEST работают всегда. Если в машине нет
> микросхемы CMOS, то эмулируется ее память. Наличие микросхемы
> определяется функцией CMOS_TEST.
**0F5h (245) CMOS_TEST Проверить наличие CMOS**
Значение регистров на входе:
C=0F5h
Значение регистров на выходе:
CF=0 - часы есть
CF=1 - часов нет
**0F6h (246) CMOS_RD Читать из регистра CMOS**
Значение регистров на входе:
C=0F6h
D - номер регистра CMOS
Значение регистров на выходе:
A - считанные данные
CF=0 - часы есть
CF=1 - часов нет
**0F7h (247) CMOS_WR Писать в регистр CMOS**
Значение регистров на входе:
C=0F7h
D - номер регистра CMOS
A - записываемые данные
Значение регистров на выходе:
CF=0 - часы есть
CF=1 - часов нет
**08Fh (143) FN_TURBO Функция управления турбо режимом.**
Комментарий к функции FN_TURBO (08Fh):
Переключение режима турбо может не произойти, если прошивка не
поддерживает это переключение. При этом ошибки не происходит. Так
же, переключение режима TURBO блокируется кнопкой "Turbo" в
режиме Turbo-OFF
Значение регистров на входе:
C=08Fh
A - режим турбо: 2 - off, 3 - on
A - режим FDD: 12h - 720Kb, 13h - 1.44Mb
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный режим турбо
### Функции управления окнами и режимами экрана
**0B0h (176) WIN_OPEN Функция открытия окна.**
Значение регистров на входе:
C=0B0h
IX - описатель окна
E - флаги окна:
бит 0 указывает какую страницу режима включать после
исполнения функции;
бит 4 указывает на какой странице режима открывать окно
Значение регистров на выходе:
CF=0 - нормальное завершение:
A - идентификатор окна
CF=1 - ошибка слишком много окон
**0B1h (177) WIN_CLOSE закрытие окна**
Значение регистров на входе:
C=0B1h
A - идентификатор окна
Значение регистров на выходе:
CF=0 - успешное завершение
CF=1 - ошибка - неверный идентификатор
Окно с номером 0 никогда не закрывается и попытка
закрытия приводит к ошибке
**0B2h (178) WIN_COPY_WIN Копирование данных текстового окна в память (запоминание окна)**
При работе этой функции через RST 18h или RST 8, обязателен запрет
прерываний, так как функция пользуется стеком для ускорения своей работы.
Значение регистров на входе:
C=0B2h
A - идентификатор глобального окна
H - размер окна в символах по вертикали
L - размер окна в символах по горизонтали
D - вертикальное положение окна в глобальном окне
E - горизонтальное положение окна в глобальном окне
IX - адрес буфера для запоминания данных
адрес буфера указывается для окна 0C000h если адрес
указан с 8000h, номер страницы буфера не действителен
ниже 8000h адрес указывать нельзя
A' - страница буфера для данных окна эта страница должна
принадлежать программе
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка - неверный идентификатор окна
**0B3h (179) WIN_RESTORE_WIN Копирование из памяти в текстовое окно (восстановление окна)**
При работе этой функции через RST 18h или RST 8, обязателен запрет
прерываний, так как функция пользуется стеком для ускорения своей работы.
Значение регистров на входе:
C=0B2h
A - идентификатор глобального окна
H - размер окна в символах по вертикали
L - размер окна в символах по горизонтали
D - вертикальное положение окна в глобальном окне
E - горизонтальное положение окна в глобальном окне
IX - адрес буфера для запоминания данных
адрес буфера указывается для окна 0C000h если адрес
указан с 8000h, номер страницы буфера не действителен
ниже 8000h адрес указывать нельзя
A' - страница буфера для данных окна эта страница должна
принадлежать программе
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка - неверный идентификатор окна
**0B4h (180) WIN_GET_SYM Взять символ с экрана**
Значение регистров на входе:
C=0B4h
A - идентификатор окна
DE - положение символа в окне:
D - вертикаль, E - горизонталь
Значение регистров на выходе:
CF=0 - нормальное завершение
L - символ, H - атрибут,
B - знакогенератор
CF=1 - ошибка неверный идентификатор окна
**0B5h (181) WIN_PUT_SYM Положить символ на экран**
Значение регистров на входе:
C=0B5h
A - идентификатор окна
DE - положение символа в окне:
D - вертикаль, E - горизонталь
L - символ, H - атрибут символа
B - знакогенератор
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка неверный идентификатор окна
**0B6h (182) WIN_SET_ZG установка знакогенератора**
Значение регистров на входе:
C=0B6h
A - системный номер знакогенератора
DE - указатель на 2Kb блок данных знакогенератора
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка (старая версия, нет функции)
**0B7h (183) WIN_MOVE_WIN Перемещение окна**
При работе этой функции через RST 18h или RST 8, обязателен запрет
прерываний, так как функция пользуется стеком для ускорения своей работы.
Значение регистров на входе:
C=0B7h
A - идентификатор глобального окна
H - размер локального окна по вертикали в символах
L - размер локального окна по горизонтали в символах
D - положение локального окна по вертикали в символах
E - положение локального окна по горизонтали в символах
IX - новое положение локального окна (подобно DE)
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка - неверный идентификатор окна
**0B8h (184) WIN_GET_ZG Получение знакогенератора**
Значение регистров на входе:
C=0B8h
DE - адрес, куда будет загружено 2kb знакогенератора
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка (старая версия, нет функции)
### Функции вывода текста на экран
**081h (129) LP_PRINT_ALL Печать символов с атрибутом**
На экран выводится строка из B одинаковых символов
Значение регистров на входе:
C=081h
A - символ
E - атрибут
B - число выводимых символов
регистры HL,IX - сохраняются
Значение регистров на выходе:
CF=0 - всегда
**082h (131) LP_PRINT_SYM Вывод символов на экран без атрибута**
На экран выводится строка из B одинаковых символов атрибут
остается тот, который был на экране
Значение регистров на входе:
C=082h
A - символ
B - число выводимых символов
регистры HL,IX - сохраняются
Значение регистров на выходе:
CF=0 - всегда
**083h (131) LP_PRINT_ATR печать атрибутов**
На экран выводится строка из B одинаковых атрибутов.
Символы не меняются.
Значение регистров на входе:
C=083h
E - атрибут
B - число выводимых символов
регистры HL,IX - сохраняются
Значение регистров на выходе:
CF=0 - всегда
**084h (132) LP_SET_PLACE Установка текущего знакоместа в окне**
Позиция печати устанавливается в соответстии с регистром DE
Значение регистров на входе:
C=084h
E - положение символа по горизонтали
D - номер символа по вертикали
Превышение границ приводит не к ошибке, а к переустановке
с начала, за вычетом полного размера окна
Значение регистров на выходе:
CF=0 - всегда
**085h (133) LP_PRINT_LN Вывод строки символов на экран с текущего знакоместа**
Значение регистров на входе:
C=085h
HL - адрес строки должен быть между 04000h и 0BFFFh
E - атрибут, с которым будет выведена строка
B - длина выводимой строки
Значение регистров на выходе:
CF=0 - всегда
**086h (134) LP_PRINT_LN2 Вывод строки символов на экран без атрибутов**
Значение регистров на входе:
C=086h
HL - адрес строки должен быть между 04000h и 0BFFFh
B - длина выводимой строки
Значение регистров на выходе:
CF=0 - всегда
**087h (135) LP_PRINT_LN3 Вывод строки символов до разделителя**
После разделителя выводятся пробелы, что бы вывести B символов
Значение регистров на входе:
C=087h
HL - адрес строки должен быть между 04000h и 0BFFFh
E - атрибут, с которым будет выведена строка
B - длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**088h (136) LP_PRINT_LN4 Вывод строки символов до разделителя, без атрибутов**
символы из выводятся на экран, пока не встретится символ равный D,
далее печатаются пробелы, как дополнение строки до B символов.
Атрибуты не изменяются.
Значение регистров на входе:
C=088h
HL - адрес строки должен быть между 04000h и 0BFFFh
B - длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**089h (137) LP_CLS_WIN Очистка экрана**
Выполнение производится выводом пробелов с заданным атрибутом
Значение регистров на входе:
C=089h
DE - положение локального окна
H - размер в символах локального окна по вертикали
L - размер в символах локального окна по горизонтали
B - атрибут очистки
Значение регистров на выходе:
CF=0 - всегда
**08Ah (138) LP_SCROLL_UD Скроллинг части глобального окна вверх/вниз**
Скроллируются полные строки глобального окна
Значение регистров на входе:
C=08Ah
B - тип скроллинга: 1 - вверх; 2 - вниз
D - начальная строка скроллинга
E - число скроллируемых строк
Значение регистров на выходе:
CF=0 - всегда
**08Bh (139) LP_PRINT_LN5 Вывод строки символов на экран до разделителя**
После разделителя вывод останавливается
Значение регистров на входе:
HL - адрес строки должен быть между 04000h и 0BFFFh
E - атрибут, с которым будет выведена строка
B - максимальная длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**08Ch (140) LP_PRINT_LN6 Вывод строки символов на экран до разделителя без атрибутов**
После разделителя вывод останавливается.
Значение регистров на входе:
C=08Ch
HL - адрес строки должен быть между 04000h и 0BFFFh
B - максимальная длина выводимой строки
D - символ-разделитель, указывающий конец строки
Значение регистров на выходе:
CF=0 - всегда
**08Dh (141) LP_CLS_WIN2 Очистка экрана с указанием символа заполнения**
Значение регистров на входе:
C=08Dh
DE - положение локального окна
H - размер в символах локального окна по вертикали
L - размер в символах локального окна по горизонтали
B - атрибут очистки
A - символ очистки
Значение регистров на выходе:
CF=0 - всегда
**08Eh (142) LP_GET_PLACE Получить текущее положение вывода на экран**
Значение регистров на входе:
C=08Eh
Значение регистров на выходе:
CF=0 - всегда
DE - координаты, в которых будет напечатан
следующий символ:
D - вертикаль, E - горизонталь
### Графические функции
**0A1h (161) PIC_POINT Установить точку**
Значение регистров на входе:
C=0A1h
DE - координата по вертикали (пиксели)
HL - координата по горизонтали (пиксели)
Координаты считаются от верхнего левого угла экрана
A - идентификатор окна
B - цвет точки
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный идентификатор окна
**0A4h (164) PIC_SET_PAL Установка палитры**
Значение регистров на входе:
C=0A4h
HL - данные палитры
E - номер начального цвета
D - количество устанавливаемых цветов
B - маска при установке палитры.
Для нормального режима должнa быть 0FFh
A -
0..3 биты - значения 0..7 - номер палитры
- значения 8..15 - зарезервированы
4..6 биты - зарезервированы (установить в 0)
7 бит -
- значение 0 - установить
- значение 1 - загрузить палитру в память
Значение регистров на выходе:
CF=0 - всегда
**0A6h (166) SET_PAL_INIT Установка внутренней палитры**
Значение регистров на входе:
C=0A6h
A - страница палитры
B - номер палитры:
B=3 - установка текстовой палитры CGA
B=2 - установка спектрумовской палитры
B=1 - установка графической плаитры
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - неверный номер палитры
### Функции работы с жесткими дисками и дисководами
**50h,52h,53h (80,82,83) Зарезервированы**
Значение регистров на входе и на выходе:
нет
**51h (81) DRV_RESET Сброс контроллера и настройка на диск**
Значение регистров на входе:
C=51h
A - номер и тип устройства
бит 7..4 - тип устройства:
#0x - FDD
#6x - RAM-DISK
#8x - HDD
#Cx - CD-ROM
бит 3..0 - номер устройства
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка, нет диска или нет устройства
**54h (84) DRV_VERIFY Проверка секторов**
Проверка внутренняя на совпадение ECC
Значение регистров на входе:
C=54h
A - номер и тип устройства (см. выше)
HL:IX - номер сектора (IX - младшая часть номера сектора)
B - количество проверяемых секторов
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - проверка с ошибкой
**55h (85) DRV_READ Чтение с устройства**
Значение регистров на входе:
C=55h
A - номер и тип устройства (см. выше)
HL:IX - номер сектора (IX - младшая часть номера сектора)
B - количество секторов
DE - адрес буфера для данных
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка чтения
HL:IX - номер сектора + кол-во прочитанных секторов
DE - адрес буфера для данных + (кол-во прочитанных секторов * размер сектора)
**56h (86) DRV_WRITE Запись на устройства**
Значение регистров на входе:
C=56h
A - номер и тип устройства (см. выше)
HL:IX - номер сектора (IX - младшая часть номера сектора)
B - количество секторов
DE - адрес буфера данных для записи
Значение регистров на выходе:
CF=0 - нормальное завершение
CF=1 - ошибка записи
HL:IX - номер сектора + кол-во прочитанных секторов
DE - адрес буфера для данных + (кол-во прочитанных секторов * размер сектора)
**57h (87) DRV_DETECT Определение параметров устройства**
Значение регистров на входе:
C=57h
A - номер и тип устройства (см. выше)
Значение регистров на выходе:
CF=0 - нормальное завершение
A - bit7=0 диск 720Кb
bit7=1 диск 1.44Mb
CF=1 - нет устройства или нет носителя
**58h (88) DRV_GET_PAR Получить параметры носителя**
Значение регистров на входе:
C=58h
A - номер и тип устройства (см. выше)
Значение регистров на выходе:
CF=0 - нормальное завершение
L - число секторов
H - число головок
DE - количество цилиндров
если HL=DE=0FFFFh - устройства нет
IX - размер сектора в байтах
B - доп. параметры для дискет:
бит7 - тип 1.44Mb/720Kb
CF=1 - нет устройства
**59h (89) DRV_SET_PAR Установить параметры носителя**
Значение регистров на входе:
A - номер и тип устройства (см. выше)
L - число секторов
H - число головок
DE - количество цилиндров
IX - размер сектора в байтах
B - доп. параметры для дискет
бит7 - тип 1.44Mb/720Kb
Значение регистров на выходе:
CF=0 - нормальное завершение
**5Ah (90) EXT_VERSION Номер версии дисковой спецификации.**
Значение регистров на входе:
C=5Ah
Значение регистров на выходе:
CF=0 - нормальное завершение
D - версия
E - модификация
CF=1 - ошибка
**5Fh (95) DRV_LIST Список дисковых устройств**
Значение регистров на входе:
C=5Fh
IX - буфер для списка устройств
Значение регистров на выходе:
CF=0 - нормальное завершение
В буфере список дисков в формате:
IX+0 - размер заполненого буфера
IX+1 - кол-во устройств FDD
IX+2 - кол-во устройств HDD
IX+3 - кол-во устройств CD DRIVE
IX+4 - #00 - конец списка, иначе кол-во устройств нового типа
### Примечания и комментарии.
##### *Примечание по использованию функции получения адресов портов окон (0C6h).*
Cледует хотя бы один раз вызвать эти функции и сравнить адреса портов с
теми, что используются в программе и, если они не совпадают, выдать
соответствующее предупреждение. В данный момент эти порты таковы:
PAGE0=82h, PAGE1=0A2h, PAGE2=0C2h, PAGE3=0E2h
##### *Примечание по использованию функции EMM_FN7 (0C7h).*
Информация о распределении памяти хранится в виде RAM Allocation Table,
похожей на дисковый FAT. Поэтому нахождение физического номера следующей
страницы по предыдущему физическому номеру происходит значительно быстрее,
чем поиск по увеличенному на единицу логическому номеру.
##### *Комментарий к функции FN_VERSION (0EFh).*
Значения регистра BC на выходе и соответствующая ему конфигурация
BC=FFFF - Не определено
BC=FFFE - Конфигурация Spectrum, режим Sprinter ZX
BC=FFFD - Конфигурация Sprinter
BC=FFFC - Зарезервировано
BC=FFFB - Зарезервировано
BC=FFFA - Зарезервировано
BC=FFF9 - Зарезервировано
Иные значения BC - новые прошивки.
##### *Комментарий к функциям CMOS (0F5h-0F7h)*
Функции CMOS_RD, CMOS_WR, CMOS_TEST работают всегда. Если в машине нет
микросхемы CMOS, то эмулируется ее память. Наличие микросхемы
определяется функцией CMOS_TEST.
##### *Комментарий к функции FN_TURBO (08Fh)*
Переключение режима турбо может не произойти, если прошивка не
поддерживает это переключение. При этом ошибки не происходит. Так же,
переключение режима TURBO блокируется кнопкой "Turbo" в режиме Turbo-OFF
##### *Комментарий к функциям печати текста.*
Эти функции работают с текущим окном, которым всегда является последнее
открытое окно. К графическому экрану функции печати текста не применимы.
##### *Описатель окна.*
Для открытия окон используется 32-хбайтовый описатель окна (дескриптор),
адрес которого указывается в регистре IX.
IX - 32-хбайтовый описатель окна
(IX+0) - горизонтальный размер окна в знакоместах
(IX+1) - вертикальный размер в знакоместах
(IX+2) - положение окна по горизонтали на экране в знакоместах
(IX+3) - положение окна по вертикали на экране в знакоместах
(IX+4) - режим знакоместа
bit4=1 - text_mode bit4=0 - graf_mode
bit5=0 - 16, bit5=1 - 8 точек в знакоместе
graf_mode bit3..0 - не существенны
bit7..6 - номер палитры
text_mode bit7..6,3..0 - номер знакогенератора
исключение: bit7..6=B"11" - бордер
(IX+5) - дополнительный режим знакоместа
bit0=1 - указывает на включение спектрумовской
адресации экрана
(IX+6) - положение по X в поле графики (по знакоместам)
(IX+7) - положение по Y в поле графики (по знакоместам)
разъяснения о положении в поле графики - ниже
(IX+8..31) - зарезервировано (переменные окна)
в этих байтах должны быть нули
При открытии окна описатель копируется в системную страницу ОЗУ и
программа может не сохранять его. Что бы описатель окна не потерялся,
программа получает идентификатор окна. Он же идентификатор глобального
окна. В функциях запоминания, восстановления, перемещения, а так же
функциях стирания, скроллинга и т.п. идентификатор окна определяет
область экрана, относительно которой производится работа с локальными
окнами. Подразумеваются локальные окна в смысле "окно в окне".
Идентификатор окна определяет глобальное окно, отнoсительно которого
адресуются локальные. В части функций глобальное окно определяется по
умолчанию, как последнее, с которым производились действия с явным
указанием идентификатора.
В данный момент BIOS хранит только один описатель окна - последний,
с которым была произведена функция открытия. Идентификатор окна
выставляется в 0. В дальнейшем планитруется разработка функций со
множеством окон, потому, во избежание неприятностей в будущем, при
работе с окнами, программисту следует запоминать идентификатор окна
и пользоваться этим значением при работе с ним.
Типы стандартных окон:
0 - окно 32x24 в формате ZX Spectrum
1 - текстовое окно 64x24
2 - текстовое окно 40x32
3 - текстовое окно 80x32
4 - окно в формате ZX Spectrum, HL - положение окна на экране в знакоместах
5 - текстовое окно 64x24, HL - положение окна на экране в знакоместах
6 - текстовое окно 40x32, HL - положение окна на экране в знакоместах
7 - текстовое окно 80x32, HL - положение окна на экране в знакоместах
8 - графическое окно 0, HL - положение окна на экране
9 - графическое окно 1, HL - положение окна на экране
Данные палитры должны представлять собой список приблизительно такого вида:
DB blue1,green1,red1,0
DB blue2,green2,red2,0
.....................
DB blueN,greenN,redN,0
N - количество цветов. Значеное равное 0 соответствует 256-ти цветам.
При записи в видео-ОЗУ все данные предварительно проходят функцию AND
со значением регистра маски - B.
Страницы палитры 0..3 соответствуют графическим режимам. Для вывода в
соответствующей палитре нужно задать соответствующее значение bit7..6 в
байте режима знакоместа
Страницы 4..7 соответствуют текстовому режиму и спектрумовскому режиму.
В странице 4 задается цвет PAPER для каждого атрибута. В странице 5
задается цвет INK для каждого атрибута. В странице 6 задается цвет PAPER,
которым он будет моргать в режиме FLASH В странице 7 задается цвет INK,
которым он будет моргать в режиме FLASH. Таким образом, для каждого из
256-ти атрибутов задается четыре цвета если цвета 4,5 совпадают с
цветами 6,7 то режим FLASH оказывается отключенным. Для его включения
в спектрумовском режиме надо поменять местами цвета 6 и 7. Если надо
включить FLASH в режим IBM-CGA, следует установить цвета 6 и 7
одинаковыми и равными цвету 4. По сути режим FLASH всегда включен, и
на экране постоянно меняются цвета PAPER с 4-го на 6-й, а цвета INK с
5 на 7-й. Если эти пары цветов для атрибута знакоместа устанавливаются
одинаковыми, то FLASH в этом месте не виден.
##### *Комментарий к функциям работы с устройствами хранения информации.*
В этих функциях в регистре A обычно задается номер и тип устройства:
бит 0..3 - номер устройства
бит 4..7 - тип устройства:
0 - дисковод
6 - ram-disk
8 - HDD
C - CD-ROM
остальные номера не используются
Binary file not shown.
+155
View File
@@ -0,0 +1,155 @@
Estex: Disk SubSystem (DSS) Programming Guide
Table of Contents
1. Introducing
2. Identification of system functions
3. Disk devices functions
1. Introducing
This document contains the list of functions and concepts of
interaction with a disk subsystem.
DSS is a collection of very useful functions that reside in
DSS itself, ready for use by any your programs. These functions
are stored in library SYSTEM.DOS and allow management of files,
memory allocation, loading and execution of the programs.
File specification
The file specification is a string, containing a names of disk,
directories separated by a symbol "\" and name of file. The names
of disk drive and directories can be discard.
for example:
C:\TEXT\DOC\text.doc
A:file.txt
\TEXT\info.txt
The DSS used chars with colon suffix as names of disk devices
(A:, B:, C: etc.) The name of disk can be written down before
filename for specified disk there it placed.
For example: command
DIR C:DATFILE
searches for DATFILE in the current directory of disk C:.
When disk name not specified DSS used current disk. At start
DSS, the current disk is a disk whence was loaded DSS.
The filenames consist of two parts. The first part contain 8
chars of file name. The second part is not necessary and contain
3 chars of file type (also known as extentsion). At the writing
of filename, both parts are separated by char point.
For example: the names "NAME" and "NAME." is specified same file.
In the name don't allows symbols with codes less 32 and chars
. " / \ [ ] : | < > + = ; ,
As the subdirectories files too, their names are formed by
same way. The name of root directory always "\". And each
subdirectories contain two items with names "." and "..". The
name "." specified a current directory and name ".." specified
name of parent(uplevel) directory.
Some console commands and DSS functions allow to use global
symbols ? and * which can be used for filename templates.
The symbol ? means that any one char of filename. The
symbol * means that it char can be replaced by any symbols.
For example:
*.txt - means, all files with type "txt"
a??.* - means, files which contain three or less symbols and
first symbol is "a"
dc*.exe - means, files with type "exe" and began "dc"
File attributes
The each bit of byte attributes specified various attribute.
And it can be changed by DSS function.
bit 0 - Read only
bit 1 - Hidden
bit 2 - System
bit 3 - Volume label
bit 4 - Directory
bit 5 - Archive
bit 6 - Reserved
bit 7 - Reserved
Attribute "read only". When value is 1, file can be read,
but can't be written or deleted.
Attribute "hidden". When value is 1, DSS can't manipulate
with this file.
Attribute "system". Specified system file.
Attribute "volume label". In old version of MSDOS used for
specified volume laben, now it can be used for long filenames.
And must be 0 for compatibles.
Attribute "directory". When value is 1, means that this
file is directory.
Attribute "archive". This bite sets in 1 when DSS writing
in this file. It can be used in backup utilities for detect
changed files.
File handle
When any file are opened, DSS build File Control Block in
DSS working areas.
The Handle (and assigned file) identified by number which
returned DSS to program after file opening and used it in all
further DSS calls. In other words, when file is opening, the
program informs DSS his name and has taken back file handle.
Which used in further file operations.
All necessary information for working with file are placed
in DSS working areas.
2. Identification of system functions
00h (00) VERSION (Version of DSS)
input:
C - 00h
output:
D - version number
E - modification
The function return version number of DSS.
3. Disk devices functions
01h (01) CHDISK (Change current disk)
input:
A - disk number (0-A,1-B...)
C - 01h
output:
A - error code, if CF=1
A - number of disks, if CF=0
The function changes current disk device.
02h (02) CURDISK (Current disk number)
input:
C - 02h
output:
A - current disk number (0-A,1-B...)
The function returns number of current disk device.
03h (03) DSKINFO (Disk information)
input:
A - disk number (0-A,1-B...0FFh-current)
C - 03h
output:
A - error code, if CF=1
A - sectors per cluster, if CF=0
HL - clusters per disk
DE - free clusters
BC - bytes per sector
The function returns information about disk device
(capacity and free space).
for example:
LD C,03h ;Function DSKINFO
LD A,0FFh ;Information about current disk
RST 10h ;Execution of function
LD A,D ;There is a free
OR E ;space?
JR Z,NO_SPACE ;No, the disk is completely filled
09h (09) BOOTDSK (Number of boot disk)
input:
C - 09h
B = 0
output:
A - number of boot disk (0-A,1-B...)
The function returns number of boot disk device whence was loaded DSS.
+126
View File
@@ -0,0 +1,126 @@
Estex: Дисковая подсистема (DSS) – Обзор
1. Введение
2. Загрузка подсистемы
3. Системная консоль
4. Файловая система
1. Введение
Estex - операционная система компьютера Sprinter, включающая
в себя различные модули. Данный документ описывает модуль дисковой
подсистемы.
В DSS используется та же самая файловая система, как и в
MS-DOS FAT16 и полностью с ней совместима.
2. Загрузка подсистемы
После включения питания или сброса компьютера, BIOS считывает
первичный загрузчик с 1-го сектора загрузочного диска.
Если загрузка происходит с HDD или дискеты, то сначала загрузочный
сектор считывается в память и ему передается управление по загрузке
модуля дисковой подсистемы SYSTEM.DOS.
Затем выполняются следующие действия:
• инициализация дисковой подсистемы и вывод сообщения "Starting DOS..."
• загрузка системной консоли SYSTEM.EXE
• выполнение команд указанных в файле SYSTEM.BAT
Обычно файл SYSTEM.BAT содержит путь к программе файловой навигации
пользователя или другому часто используемому приложения.
Например "c:\fn\fn.exe".
Если во время загрузки вы хотите пропустить выполнение SYSTEM.BAT.
То вам следует нажать клавишу "SHIFT", как только появиться
сообщение "Starting DOS..." и удерживать пока не появится приглашение
консоли ("C:\>").
3. Системная консоль
В DSS многие задачи могут быть выполнены через интерфейс командной
строки называемой системной консолью. Основная задача консоли ввод
команд и их исполнение. Также она имеет ряд функций, которые выполняют
такие действия как управление файлами, перемещение по файловой структуре
каталогов, редактирование командной строки и переменных среды.
Системная консоль позволяет пользователю взаимодействовать с
операционной системой. Для DOS системная консоль это SYSTEM.EXE. Если вы
видите на экране приглашение командной строки (A:\> или C:\>), то это
означает что SYSTEM.EXE загружен и активизирован. Когда вы вводите
командную строку, командный процессор интерпретирует команду и выполняет
необходимые действия.
На сегодняшний день в консоли доступны следующие команды:
CD Displays the name of or changes the current directory.
CHDIR Displays the name of or changes the current directory.
CLS Clears the screen.
DATE Displays or sets the date.
DEL Deletes one or more files.
DIR Displays a list of files and subdirectories in a directory.
ECHO Displays messages, or turns command echoing on or off.
ERASE Deletes one or more files.
EXIT Quits the SYSTEM.EXE program (command interpreter).
HELP Provides Help information for console commands.
MD Creates a directory.
MKDIR Creates a directory.
PAUSE Suspends processing of a batch file and displays a message.
RD Removes a directory.
REM Records comments (remarks) in batch files or SYSTEM.BAT.
REN Renames a file or files.
RENAME Renames a file or files.
RMDIR Removes a directory.
TIME Displays or sets the system time.
VER Displays the System version.
4. Файловая система
Сейчас, в качестве файловой системы Estex использует FAT12 и FAT16.
С помощью файловой системы FAT (File Allocation Table) организуются
данные на винчестере и дискетах.
Для указания спецификации файла используется следующая форма:
[drive:][directory\]filename[.ext]
Файловая спецификация - это строка символов содержащая наименования
диска, директорий отделенных символом "\" и имя файла. Имена диска и
директории могут быть опущены, если требуемый файл расположен в текущей
директории.
Например:
C:\TEXT\DOC\text.doc
A:file.txt
\TEXT\info.txt
В DSS в качестве имен дисковых устройств используются буквы с
последующим символом двоеточия (A:, B:, C: и.т.д.) Имя диска может быть
набрано перед именем файла для указания диска, на котором он расположен.
Например:
команда
DIR C:TESTFILE
ищет TESTFILE в текущей директории диска C:.
Если имя диска не указанно используется текущий диск. После запуска DSS,
текущим диском является диск, с которого была загружена DSS.
Имена файлов состоят из двух частей. Первая часть может содержать
8 букв, цифр или следующие специальные символы:
$ % ' _ @ { } ~ ` ! # ( ).
Вторая часть не является обязательной и содержит любую комбинацию из трех
букв, цифр или специальных символов с предшествующей точкой (.).
Например имена "NAME" и "NAME." указывают на одинаковый файл.
В имени файла не допускаются символы с кодом меньше 32, а также символы
. " / \ [ ] : | < > + = ; ,
Поскольку директории также являются файлами их имена образуются по
тем же правилам.
Имя корневой директории всегда "\". И каждая поддиректория содержит
два элемента с именами "." and "..". Имя "." указывает на текущую
директорию, а имя ".." указывает на родительную (на уровень выше)
директорию.
Некоторые команды и функции DSS позволяют использовать глобальные
символы * и ? которые могут использоваться для задания шаблона имени
файла.
Символ ? означает любой один символ в имени файла.
Символ * означает, что он может быть заменен на любое количество
любых символов.
for example:
*.txt - означает, все файлы с типом "txt"
a??.* - означает, файлы содержащие три и менее символов и первый символ "a"
dc*.exe - означает, файлы с типом "exe" и начинающиеся на "dc"
В именах файлов не делается различий между заглавными и прописными
символами.
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
Акселератор компьютера Sprinter.
Акселератор предназначен для ускорения операций по пересылке блоков данных в ОЗУ и видео-ОЗУ.
Акселератор позволяет:
- быстро заполнять горизонтальную или вертикальную линию длиной до 256 точек одним цветом (в режиме 640x256 - одинарную/двойную горизонтальную линию длиной до 512 точек)
- быстро копировать горизонтальную или вертикальную линию длиной до 256 точек (в режиме 640x256 - горизонтальную линию до 512 точек)
- проводить быстрые операции AND, OR, XOR с блоками памяти.
Акселератор не может работать с блоками данных ПЗУ и Быстрого-ОЗУ.
ОЗУ акселератора является частью внутреннего ОЗУ ППЛМ.
Операции по пересылке данных производятся путем записи блока данных в это
внутреннее ОЗУ, а затем копировании его в нужное место ОЗУ из ОЗУ акселератора.
Блок данных, записываемый в ОЗУ акселератора может иметь различную
длинну из диапазона 1..256 байт.
После одной записи копирование может производиться несколько раз и, таким
образом, можно производить заполнение экрана текстурами.
Для заполнения экрана одним цветом используется другой режим
акселератора. В нем вместо копируемого блока данных из внутреннего ОЗУ
производится запись данных с шины процессора, которые в этот момент не
изменяются.
Управление акселератором производится непосредственно из программы.
Для этого изпользуются команды процессора, которые, фактически, являются
операциями типа NOP.
LD B,B - выключить акселетарор.
LD D,D - включить акселератор в режим приема байта размера блока
далее следует команда типа LD A,dat, где dat и будет новым
размером блока. Если размер блока был установлен ранее,
его можно не устанавливать.
LD C,C - Операция Fill - заполнение одним байтом. Последующая
команда типа LD (HL),A приведет к заполнению указанного
ранее количества байт значением A
LD E,E - Операция Fill для графического экрана - заполнение
вертикальных линий.
LD H,H - rezerved
LD L,L - копирование блока. Последующая команда типа LD A,(HL)
приведет к заполнению ОЗУ акселератора данными из адреса (HL),
а команда типа LD (DE),A приведет к перезаписи данных из ОЗУ
акселератора в ОЗУ или видео-ОЗУ.
LD A,A - копирование блока для графического экрана подобна команде
LD L,L, но работает с вертикальными линиями экрана.
Пример использования акселератора:
; Считаем, что экранная страница уже открыта по адресу #C000
LD HL,#C040 ; адрес начала линии первого экрана
LD DE,#C180 ; адрес начала линии второго экрана
LD BC,#140 ; длина экрана по горизонтали
DI ; запретить прерывания для работы с акселератором
LD D,D ; включить акселератор на установку размера блока
LD A,0 ; установить размер блока - 256 байт
LD A,A ; установить акселератор на копирование
; вертикальных линий.
LDIR ; копировать
LD B,B ; выключить акселератор
EI ; включить прерывания
Эта часть программы произведет копирование всего содержимого первого экрана на другой.
Время исполения составляет примерно 26 милисекунд.
Дополнительные функции акселератора (AND, OR, XOR) работают таким же образом.
Для выполнения логических функций используются команды XOR (HL); OR (HL); AND (HL).
Пример кодирования блока в 256 байт.
LD HL,ADRES_1
LD DE,XOR_DAT
DI
LD D,D
LD A,0 ; число байт, которые надо закодировать
LD L,L
LD A,(DE) ; взять блок данных в ОЗУ акселератора
XOR (HL) ; произвести операцию XOR с данными акселератора
LD (HL),A ; запомнить в ОЗУ результат операции
LD B,B
EI
Скорость работы акселератора ограничивается только физической
скоростью работы основного ОЗУ. Определить примерное время работы команды с
акселератором можно по такой формуле:
Время работы = время работы команды без акселератора + время работы
акселератора
Время работы акселератора = число пересылаемых байт /7 микросекунд
Во время работы акселератора необходимо отключать прерывания, так как в этот момент
изменяется система команд процессора и программа на прерывании не сможет работать корректно.
@@ -0,0 +1,635 @@
ÜÜÜÜÜÜ
ÜÛ°°°°°°
Û°° Û°°
Û°°ÜÜÜÛ°°
Û°°°°°°°°
Û°° Û°°
Û°° Û°° àå¨â¥ªâãà  ª®¬¯ìîâ¥à  Sprinter.
ß°° ß°°
‚¢¥¤¥­¨¥.
„ ­­®¥ ®¯¨á ­¨¥ ¯à¥¤¯®« £ ¥â ­ «¨ç¨¥ ®¯à¥¤¥«¥­­ëå §­ ­¨© ç¨â â¥«ï,
  ¨¬¥­­® §­ ­¨¥  àå¨â¥ªâãàë ª®¬¯ìîâ¥à  ZX-Spectrum ¨ ¨å à §­®¢¨¤­®á⥩, ¢
ç áâ­®á⨠Pentagon-128 ¨ Scorpion-256,   â ª ¦¥ §­ ­¨¥ ï§ëª  BASIC ¨
­¥ª®â®à®¥ §­ ª®¬á⢮ á ï§ëª®¬  áᥬ¡«¥à  Z80.
‡¤¥áì ï ¡ã¤ã ­ §ë¢ âì ª®­ä¨£ãà æ¨¥© ¬ è¨­ë - ª®­ªà¥â­ãî ॠ«¨§ æ¨î
ª®­ªà¥â­®© áå¥¬ë ¢ ¯¥à¥¯à®£à ¬¬¨à㥬®© «®£¨ç¥áª®© ¬¨ªà®á奬¥ (‹Œ).
â® ®§­ ç ¥â, çâ® ¬ è¨­  ¨¬¥¥â ¬­®¦¥á⢮ ª®­ä¨£ãà æ¨©, ª ¦¤ ï ¨§ ª®â®àëå
¨¬¥¥â ᢮î á奬ã.
Ÿ â ª ¦¥ ¨á¯®«ì§ãî ¯®­ï⨥ Š˜-އ“. â® ­¥ Š˜ ¢ ä®à¬ «ì­®¬
á¬ëá«¥,   ¡ëáâ஥ އ“, ¢ ª®â®à®¬ ¯à®æ¥áá®à ¬®¦¥â à ¡®â âì ­  ¢ë᮪®©
ç áâ®â¥ ¡¥§ ®¦¨¤ ­¨ï. Š˜-¥¬ íâ® Ž‡“ ­ §ë¢ ¥âáï ⮫쪮 ¯® âà ¤¨æ¨¨,
¯®¤®¡­® Š˜-ã ­  Š537“10 ¢ ª®¬¯ìîâ¥à å Pentagon-128.
Šà âª¨¥ ¤ ­­ë¥ ª®¬¯ìîâ¥à  Sprinter.
p®æ¥áá®p . . . . . . . . . . . Z84C15
’ ªâ®¢ ï ç áâ®â  . . . . 21MHz/3.5MHz
އ“ . . . . . . . . . . . . . . 4096Kb
Š˜ އ“ . . . . . . . . . . . . . 64Kb
‡“ . . . . . . . . . . . . . . .128Kb
‚¨¤¥®-އ“ . . . . . . . . . 256Kb(512)
Š®­âp®««¥p ¤¨áª®¢ . . . . . Šp1818‚ƒ93
®¤¤¥p¦ª  1.44Mb ä®p¬ â  . . 3.5"¤¨áª 
Š®­âp®««¥p ¢¨­ç¥áâ¥p  . . . . . IDE/AT
Š®­âp®««¥p ª« ¢¨ âãpë . . . 101key/AT
Š®­âp®««¥p ¬ëè¨ . . . . . . . MS-Mouse
„¢  á«®â  . . . . . . . áâ ­¤ pâ ISA-8
†¥«¥§­ ï í¬ã«ïæ¨ï AY-3-8910 áâ¥à¥®-OUT
COVOX . . . . . . . . . 8bit x 4chanel
‚¨¤¥®-p¥¦¨¬ë: . . . Spectrum standart
GRAF 320x256x256,640x256x16, TXT 80x32
‚ë室 ¢¨¤¥® ­  TV ¨«¨ CGA ¬®­¨â®p, RGB
’¥å­¨ç¥áª ï ॠ«¨§ æ¨ï.
Ÿ¤à®¬ ¬ è¨­ë ïîâáï ¯à®æ¥áá®à Z84C15 ¨ ‹Œ EPF10K10QC208.
Šà®¬¥ ­¨å ­  ¯« â¥ ¯à¨áãâáâ¢ãîâ ¬¨ªà®á奬a ‡“, 72å-¯¨­®¢ë© SIMM
­  4Mb, 256Kb ¢¨¤¥®-އ“, 64Kb Š˜-އ“, á奬  ª®­â஫«¥à  ¤¨áª®¢®¤  ­ 
ˆ‘ Š1818‚ƒ93, ¡ãä¥àë ¤«ï ¯®¤ª«î祭¨ï ¤¦®©á⨪ , ¬ £­¨â®ä®­ , ¯à¨­â¥à ,
ª« ¢¨ âãàë, ¤¨áª®¢®¤®¢, ¢¨­ç¥áâ¥à , ¬ëè¨, ¡ãä¥à­ë¥ ¬¨ªà®á奬ë 設ë ISA-8
¨ ¥é¥ ®¤­  ‹Œ ä¨à¬ë ALTERA - EPM7032LC44. â  ‹Œ ­¥ ¬¥­ï¥â ᢮¥©
ª®­ä¨£ãà æ¨¨ ¨ ¯à¥¤­ §­ ç¥­  ¤«ï ®¡¥á¯¥ç¥­¨ï ᨭåà®­¨§ æ¨¨ ¨ ­ ç «ì­®£®
§ ¯ã᪠ ª®¬¯ìîâ¥à .   ¯« â¥ â ª ¦¥ ¯à¥¤ãᬮâ७  ¢®§¬®¦­®áâì ¯®¤ª«î祭¨ï
CMOS ç á®¢ ­  ®á­®¢¥ ¬¨ªà®á奬ë DALLAS. Šà®¬¥ ¯¥à¨ä¥à¨¨ ¨ ¡ãä¥à®¢ ¨¬¥îâáï
¬¨ªà®áå¥¬ë ¤¥è¨äà æ¨¨, ¢å®¤ë ª®â®àëå ¯®¤ª«îç îâáï ª ¯à®æ¥áá®àã ç¥à¥§ ‹Œ.
â® ¯®§¢®«ï¥â «¥£ª® ¬¥­ïâì  ¤à¥á æ¨î ãáâனá⢠¡¥§ ª ª®£® «¨¡® ¨§¬¥­¥­¨ï
à §¢®¤ª¨ ¯¥ç â­®© ¯« âë.
‚®§¬®¦­®á⨠ àå¨â¥ªâãàë ¬ è¨­ë.
‘奬  ª®¬¯ìîâ¥p  ®á­®¢ ­  ­  ¡®«ì让 ¯¥p¥¯p®£p ¬¬¨p㥬®© «®£¨ç¥áª®©
¬¨ªp®á奬¥. ®¤ª«î祭¨¥ ¯¥à¨ä¥à¨©­ëå ãáâனá⢠ç¥à¥§ ‹Œ ¯®§¢®«ï¥â ¯®«ãç¨âì
¢ë᮪ãî £¨¡ª®áâì ¬ è¨­ë ¯® ª®­ä¨£ãà æ¨ï¬.
p®£p ¬¬¨p®¢ ­¨¥ ‹Œ ®áãé¥á⢫ï¥âáï ­¥¯®áp¥¤á⢥­­® ¢ ¬®¬¥­â
¢ª«î祭¨ï,   â ª ¦¥ ¯p¨ ¯¥p¥§ £p㧪¥, çâ® ¯®§¢®«ï¥â ª p¤¨­ «ì­® ¬¥­ïâì
á奬㠢 ‹Œ ­¥¯®áp¥¤á⢥­­® ¢® ¢p¥¬ï p ¡®âë. ⮠ᨫ쭮 ¢ë¤¥«ï¥â
 àå¨â¥ªâãàã ª®¬¯ìîâ¥à  ¨§ à鸞 áãé¥áâ¢ãîé¨å ª®¬¯ìîâ¥à®¢ ¨ ¯®í⮬㠬­®£¨¥
¯®­ïâ¨ï, ¯à¨áã騥 ®¡ëç­ë¬ ¬ è¨­ ¬, ¬¥­ïîâ ᢮© á¬ëá«. ” ªâ¨ç¥áª¨ ª®¬¯ìîâ¥à
¨¬¥¥â ¨§¬¥­ï¥¬ãî  àå¨â¥ªâãàã, ¢ ª®â®à®© ¢®§¬®¦­ë ¨§¬¥­¥­¨ï ¢® ¬­®£¨å ç áâïå
á奬ë. ’ ª, ­ ¯à¨¬¥à, ­¥«ì§ï £®¢®à¨âì ® ª®­ªà¥â­ëå  ¤à¥á å ¯®à⮢
¯®¤ª«î祭¨ï ¯¥à¨ä¥à¨¨, â ª ª ª ®­¨ ¬®£ãâ ¡ëâì ¨§¬¥­¥­ë ¢ ®¤­ã ᥪ㭤ã
¯ã⥬ ¯¥à¥¯à®£à ¬¬¨à®¢ ­¨ï ‹Œ ¨ ¤ ­­ëå ¢ އ“, ®â¢¥ç îé¨å §  ª®­ä¨£ãà æ¨î
¯®à⮢. Š®­ªà¥â­ë¥  ¤à¥á  ¯®ï¢«ïîâáï ⮫쪮 ¢ ª®­ªà¥â­ëå ª®­ä¨£ãà æ¨ïå,
­ ¯à¨¬¥à, â ª®© ª ª ª®­ä¨£ãà æ¨ï ZX-Spectrum.
¥à¥¯à®£à ¬¬¨à㥬®áâì áå¥¬ë ¤ ¥â ¤®¢®«ì­® ¡®«ìèãî ᢮¡®¤ã
ä ­â §¨¨ ¯à®£à ¬¬¨áâ  ¯® ª®­ä¨£ãà æ¨¨ ¬ è¨­ë. ‡ ¤ã¬ë¢ ï ª®­ªà¥â­ãî
à ¡®â㠯ணࠬ¬¨áâ ¬®¦¥â ®¯à¥¤¥«¨âì ¢ ª ª®© ª®­ä¨£ãà æ¨¨ ¥¥ ¬®¦­®
ᤥ« âì «ãçè¥,  , ¢®§¬®¦­®, ¨ ¯à¨¤ã¬ âì á¢®î ª®­ä¨£ãà æ¨î, ª®â®àãî
§ â¥¬ ¬®¦­® ॠ«¨§®¢ âì ¢ ‹Œ ¨ ¢ª«îç¨âì ¯¥à¥¤ § ¯ã᪮¬ í⮩ ¯à®£à ¬¬ë.
«®ç­ ï á奬  ª®¬¯ìîâ¥à  Sprinter.
ÚÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ>Sinc
³à¨­â¥à³ ³ 2 ISA SLOTS ³ ³ ÚÄÄÄÄÄÄÄ>R
ÃÄÄÄÄÄÄÄ´ ÀÄÄÄÂÄÂÄÂÄÂÄÂÄÄÄÄÄÄÄÂÄÂÄÂÄÂÄÂÄÄÙ ³ ³ ÚÄÄÄÄÄ>G
³ Œëèì ³ ÚÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄ¿ ³ ³ ³ ÚÄÄÄ>B
ÀÄÂÄÂÄÂÄÙ ³ ãä¥àë ¨ ¤¥è¨äà â®àë ³ ³ ÚÄÁÄÁÄÁÄ¿
³ ³ ³ ÀÄÄÄÂÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÂÄÂÄÄÄÄÂÄÂÄÙ ³ ³ –€ ³
³ ³ ³ ³INT ³ ³ ³ ³ ³ ³ ³ ³ ¡ãä¥à ³
ÚÄÄÁÄÁÄÁÂÄ¿ ³ ³ ³ ³ ³ ÚÁÄÁÄÄÄÄÄÄÁÄ¿ÀÄÄÂÄÂÄÄÙ ÚÄÄÄÄÄÄÄÄ¿
³ ‚­ãâà ³ ÃÄÄÄijÄÄÄÄÄÄÄÄÄÄÙ ÀÄij ³ÄÄÄ´ EPF10K10 ÃÄÄÄÙ ÀÄÄÄÄÄÄ´ ¢¨¤¥® ³
³ ¯®àâë ³ ÃÄÄÄijÄÄÄÄÄÄÄÄÄÄDATAij ³ÄÄÄ´ ÃÄÄV_DATAÄÄÄÄ´ ³
ÃÄÄÄÄÄÄÄÙ ÃÄÄÄijÄÄÄ¿ ÚÄÄÄÄÄÄÄÄij ³ÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ އ“ ³
³ Ã<ÄÄÄÙ ³ ³ ³ ³ ³ ³ ³ ³
³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
³ Z84C15 ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄADRESSÄÄÄÄÄ´ ÃÄV_ADRESSÄÄÄ´ ³
³ ÃÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
³ ³ ³ ³ ³ ³ ³ ³ ³ ³
³ Ã<ÄÄij ³Ä³ ³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>´ ÃÄÄWE,CSiÄÄÄ>´ ³
³ Ã<ÄÄij ³Ä³ ³ÄÄÄÄDIRÄÄÄÄÄÄÄ>´ ³ ÀÄÄÄÄÄÄÄÄÙ
³ Ã<ÄÄij ³Ä³ ³ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>´ ÃÄÄÄÄÄÄÄ> Audio OUTs
³ ³ ³ ³ ³ ³ ³ ³ ÚÄÄÄÄÄÄÄÄ¿
³ ³ ÚÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄ¿ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ MAIN ³
³ ³ ³ ‡“ ¨ Š˜-އ“ Ã<ÄADR'Ä´ ÃÄÄDATAÄÄÄÄÄÄ´ RAM ³
ÀÄÂÄÂÄÂÄÄÂÙ ³ CS Ã<ÄCSÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ SIMM ³
³ D ³ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
³ A ³ ³ ³ EPM7032 ÃÄÄÄÄÄÄÄ>´ ÃÄÄADRESSÄÄÄÄ´ ³
³ T ³ ÀÄÄ>´ Sinchro ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
³ A ³ ³ HDD_DIR Ã<ÄÄÄÄÄÄÄ´ ³ ³ ³
³ ³ ³ ³ ”€— Ã<ÄÄÄÄÄÄÄ´ ÃÄRAS,CAS,WEÄ´ ³
³ ³ ³ ÀÄÂÄÂÄÂÄÂÄÂÄÄÄÄÙ ³ ³ ÀÄÄÄÄÄÄÄÄÙ
³ ³ ³ ³ ³ ³ ³ ³ ³ ³
ÚÄÁÄÁÄÁÄÄÄÄÄÄÄÄÁÄÁÄÁÄÁÄÁÄÄÄÄÄÄÄ¿ ³ ³
³ ¥à¨ä¥à¨©­ë¥ ãáâனá⢠ Ã<ÄÄÄÄ´ ³
³ FDD,HDD,KEMPSTON Ã<DIRÄ´ ³
³ Ã<ÄÄÄÄ´ ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>´ ³
ÚÄÄÄÄÄÄÄÄ¿ ³ ÚÄÄÄÄÄÄÄÄ¿ ³ ³
³ TAPE Ã<ÄÄÙ ³KeyboardÃÄÄÄÄÄÄÄÄÄ>´ ³
³ in/out ³ ô ³ ³
ÀÄÄÄÄÄÄÄÄÙ ÀÁÁÁÁÁÁÁÁÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ
¨áã­®ª 1.
„«ï ¯à®áâ®âë ­¥ª®â®àë¥ ¡ãä¥àë ¨ ¤¥è¨äà â®àë ­  á奬¥ ­¥ 㪠§ ­ë.
Š®«¨ç¥á⢮ ஢®¤®¢ ¢ 設 å â ª ¦¥ ãá«®¢­ë. — áâì ᨣ­ «®¢ ã¯à ¢«¥­¨ï
ãáâனáâ¢ á ‹Œ á¬ã«ì⨯«¨æ¨à®¢ ­ë á  ¤à¥á ¬¨ SIMM- .
„ «ì­¥©è¥¥ ®¯¨á ­¨¥  àå¨â¥ªâãàë ï¥âáï ®¯¨á ­¨¥¬ ª®­ªà¥â­ëå
ª®­ä¨£ãà æ¨© ¨ ç á⥩ ª®­ä¨£ãà æ¨©. ® ¯¥à¥¤ í⨬ á«¥¤ã¥â ᪠§ âì ­¥áª®«ìª®
á«®¢ ® ¯¥à¥ª«î祭¨¨ á ¬¨å ª®­ä¨£ãà æ¨©.
‡ £à㧪  ª®­ä¨£ãà æ¨©.
‚ ¬®¬¥­â ¢ª«î祭¨ï ª®¬¯ìîâ¥à ,   â ª ¦¥ ¯®á«¥ ­ ¦ â¨ï ­  RESET ¢áï
¨­ä®à¬ æ¨ï, ­ å®¤¨¢è ïáï ¢ ‹Œ ®â¢¥ç îé ï §  ª®­ªà¥â­ãî ª®­ä¨£ãà æ¨î,
áâ¨à ¥âáï. ‹Œ ¯¥à¥å®¤¨â ¢ ०¨¬ ®¦¨¤ ­¨ï § £à㧪¨ ¡«®ª  ¤ ­­ëå á奬ë.
‚ íâ®â ¬®¬¥­â ¯à®æ¥áá®à ¯®«­®áâìî ®âª«î祭 ®â ª ª®© «¨¡® ¯¥à¨ä¥à¨¨.
‚ ¥£®  ¤à¥á­®¥ ¯à®áâà ­á⢮ ¯ ¬ï⨠®ª §ë¢ ¥âáï ¢ª«î祭  ®¤­  áâà ­¨æ  ‡“ ¨
®¤­  áâà ­¨æ  އ“ Š˜-¯ ¬ïâ¨. ‹î¡ ï § ¯¨áì ¢  ¤à¥á­®¥ ¯à®áâà ­á⢮ ¯ ¬ïâ¨
¯à®æ¥áá®à  ¢ íâ®â ¬®¬¥­â ¯à¨¢®¤¨â ª § ¯¨á¨ ¤ ­­ëå ¢ ‹Œ ¨ ¯à®£à ¬¬  ¢
¯®¤ª«î祭­®© áâà ­¨æ¥ ‡“ ¨¬¥¥â ⮫쪮 ®¤­ã ¥¤¨­á⢥­­ãî æ¥«ì - § £à㧨âì
¢ ‹Œ ¤ ­­ë¥ ª®­ä¨£ãà æ¨¨. ‚ í⮩ ¦¥ áâà ­¨æ¥ ‡“ ­ å®¤ïâáï ¤ ­­ë¥
­ ç «ì­®© ª®­ä¨£ãà æ¨¨. (‚ ¤ ­­ë© ¬®¬¥­â íâ® ª®­ä¨£ãà æ¨ï Sprinter-1.)
ணࠬ¬  § £à㧪¨ ª®­ä¨£ãà æ¨¨ ¯à®¢¥àï¥â ä« £ ¢ Š˜-¯ ¬ï⨠¨, ¥á«¨ ®­
ãáâ ­®¢«¥­, § £à㦠¥â ¢ ‹Œ ¤ ­­ë¥ ¨§ އ“, ¥á«¨ á¡à®è¥­, â® ¤ ­­ë¥ ¨§
‡“.   í⮬ ®á­®¢ ­® ¯¥à¥ª®­ä¨£ãà¨à®¢ ­¨¥ áå¥¬ë ª®¬¯ìîâ¥à .
„«ï ¨§¬¥­¥­¨ï áå¥¬ë ­ ¤® § £à㧨âì ¢ ¯®á«¥¤­îî áâà ­¨æã Š˜-¯ ¬ïâ¨
¡«®ª ¤ ­­ëå ª®­ä¨£ãà æ¨¨ ᮠᬥ饭¨ï #100 ¨ ¢ëáâ ¢¨âì ä« £, ª®â®àë¬ ï¢«ï¥âáï
⥪á⮢ ï áâப  "FLEX_10K_LOADING", § ¯¨á ­­ ï ¯® ᬥ饭¨î #80 ¢ í⮩ ¦¥
áâà ­¨æ¥ Š˜- . ®á«¥ í⮣® ­ ¤® ¯à®¨§¢¥á⨠¯®«­ë© á¡à®á, ª®â®àë©
®áãé¥á⢫ï¥âáï ¯à®£à ¬¬­® § ¯¨áìî ¢ ᯥ樠«ì­ãî áâà ­¨æã ¯ ¬ï⨠RESET_PAGE.
ணࠬ¬  ¢ ‡“, § ¯ã᪠¥¬ ï ¯® á¡à®áã ­ å®¤¨â ä« £ FLEX_10K_LOADING ¨
­ ç¨­ ¥â § £à㧪㠤 ­­ëå ¢ ‹Œ. ਠí⮬ ®­  ®¤­®¢à¥¬¥­­® § â¨à ¥â ä« £,
çâ® ¯à¥¤®â¢à é ¥â ¯®¢â®à­ãî § £à㧪㠭®¢®© ª®­ä¨£ãà æ¨¨ ¯à¨ ­ ¦ â¨¨ ­ 
ª­®¯ªã RESET ¨ ¯®§¢®«ï¥â ¢¥à­ãâìáï ¯®á«¥ "àãç­®£®" á¡à®á  ¢ ­ ç «ì­ãî
ª®­ä¨£ãà æ¨î. ‡ â¨à ­¨¥ ä« £  â ª ¦¥ ¨§¡ ¢«ï¥â ®â ¬ã祭¨© ¢ á«ãç ¥
¯®¤ª«î祭¨ï ­¥¯à ¢¨«ì­®© ª®­ä¨£ãà æ¨¨ ¢® ¢à¥¬ï íªá¯¥à¨¬¥­â®¢ á ¯à®£à ¬¬ ¬¨.
 ¦ â¨¥ ­  RESET ¢á¥£¤  ¢¥à­¥â á奬㠢 ­ ç «ì­ãî ª®­ä¨£ãà æ¨î.
ਬ¥ç ­¨¥:
‚­ãâ७­ïï ¨­ä®à¬ æ¨ï ¡«®ª  ¤ ­­ëå ‹Œ ï¥âáï § ªàë⮩
¨­ä®à¬ æ¨¥© ä¨à¬ë ALTERA. Šà®¬¥ á ¬¨å ¬¨ªà®á奬 ‹Œ ALTERA ¯®áâ ¢«ï¥â
¨ ¯à®£à ¬¬­®¥ ®¡¥á¯¥ç¥­¨¥ ¤«ï à §¢®¤ª¨ á奬 ¢­ãâਠ‹Œ. Š á®¦ «¥­¨î, íâ 
¯à®£à ¬¬  ­¥ ¬®¦¥â à ¡®â âì ­  ª®¬¯ìîâ¥à¥ ⨯  ZX-Spectrum ¨ ¢ ¡«¨¦ ©è¥¬
®¡®§à¨¬®¬ ¡ã¤ã饬 ­¥ ¯à¥¤¢¨¤¨âáï ¥¥ ¢¥àá¨ï ¤«ï Sprinter- . ®í⮬ã
à §à ¡®âª  ­®¢ëå ª®­ä¨£ãà æ¨© ¬®¦¥â ¯à®¨§¢®¤¨âáï ⮫쪮 ¯à¨ ­ «¨ç¨¨
¤®áâ â®ç­® ¬®é­®© ¬ è¨­ë (¢á¥ ¤¥« «®áì ­  Pentium-166) ¨ ¯à®£à ¬¬ë à §¢®¤ª¨
á奬 ¢ ‹Œ, 業  ­  ª®â®àãî á®áâ ¢«ï¥â á®â­¨ ¤®«« à®¢ ‘˜€.
‚ á¢ï§¨ á í⨬, ¢ ¤ ­­ë© ¬®¬¥­â Sprinter ¨¬¥¥â ­¥áª®«ìª® ª®­ªà¥â­ëå
ª®­ä¨£ãà æ¨©, ¤¢¥ ¨§ ª®â®àëå § ¯¨á ­ë ¢ ‡“,   ®áâ «ì­ë¥ ¬®£ãâ ¡ëâì
¯®¤£à㦥­ë á ¤¨áª¥âë ¨«¨ ¢¨­ç¥áâ¥à . ®áâ®ï­­® ¢¥¤¥âáï ᮢ¥à襭á⢮¢ ­¨¥
ª®­ªà¥â­ëå ª®­ä¨£ãà æ¨© ¨ à §à ¡®âª  ­®¢ëå.
Š®­ä¨£ãà æ¨ï Sprinter-1.
‚ª«î砥⠢ á¥¡ï ª®­ä¨£ãà æ¨î Spectrum-128/256, à á¯à¥¤¥«¥­¨¥ ¯ ¬ïâ¨
¤® 4Mb, à áè¨à¥­­ë© íªà ­ á ०¨¬ ¬¨ Spectrum, Text-80x32, Graf-320x256x256,
ª®­â஫«¥à ¤¨áª®¢®¤ , ª®­â஫«¥à IDE ¢¨­ç¥áâ¥à , ª®­â஫«¥à ª« ¢¨ âãàë AT,
¯®¤ª«î祭­®© ª ª ZX-Keyboard, 8-bit COVOX.
â  ª®­ä¨£ãà æ¨ï ¬ ªá¨¬ «ì­® ¯à¨¡«¨¦¥­  ª ª®­ä®£ãà æ¨¨ ZX-Spectrum
¨ ¯®§¢®«ï¥â à ¡®â âì ­  ®¡ëç­ëå ᯥªâà㬮¢áª¨å ¯à®£à ¬¬ å ¨ ¯®á⥯¥­­®
¬¥­ïâì ¨å ¯®¤ à áè¨à¥­­ë¥ ०¨¬ë íªà ­  ¨ ¯ ¬ïâ¨,   â ª ¦¥ ¤«ï à ¡®âë á
­®¢ë¬¨ ãáâனá⢠¬¨.
Š®­ä¨£ãà æ¨ï Sprinter-2.
‚ª«î砥⠢ á¥¡ï ª®­ä¨£ãà æ¨î Spectrum-128/256, à á¯à¥¤¥«¥­¨¥ ¯ ¬ïâ¨
¤® 4Mb, à áè¨à¥­­ë© íªà ­ á ०¨¬ ¬¨ Spectrum, Text-80x32, Graf-320x256x256,
ª®­â஫«¥à ¤¨áª®¢®¤ , ª®­â஫«¥à IDE ¢¨­ç¥áâ¥à , ª®­â஫«¥à ª« ¢¨ âãàë AT,
¯®¤ª«î祭­®© ª ª ZX-Keyboard, Accelerator.
Š®­ä¨£ãà æ¨ï, ª ª ¨ Sprinter-1 ¯à¨¡«¨¦¥­  ª ᯥªâà㬮¢áª®©, ­®
¨¬¥¥â ¡®«¥¥ ¦¥á⪨¥ âॡ®¢ ­¨ï ª ¯à®£à ¬¬ ¬ ¯® ᮢ¬¥á⨬®áâ¨. ®§¢®«ï¥â
¨á¯®«ì§®¢ âì  ªá¥«¥à â®à ®¯¥à æ¨© á ®á­®¢­ë¬ ¨ ¢¨¤¥®-އ“. €ªá¥«¥à â®à
ã᪮àï¥â ®¯¥à æ¨¨ ¯¥à¥á뫪¨ ¡«®ª®¢ ¤ ­­ëå ¨ § ¯®«­¥­¨ï އ“ ®¤­¨¬ ¡ ©â®¬
¤® 䨧¨ç¥áª®£® ¯à¥¤¥«  ᪮à®á⨠®á­®¢­®£® އ“.
‚ ¯®á«¥¤­¥© ¢¥àᨨ ª®­ä¨£ãà æ¨ï Sprinter-2 ­¥ ¨¬¥¥â Spectrum-®¢áª®©
ª« ¢¨ âãàë. ‚¬¥áâ® ­¥¥ ¨§ ¯®àâ  0FEh áç¨â뢠¥âáï ᪠­ª®¤ ¯à¨è¥¤è¨© á
AT-ª« ¢¨ âãàë.
Š®­ä¨£ãà æ¨ï ZX-Spectrum-256/AY.
â  ª®­ä¨£ãà æ¨ï ¬ ªá¨¬ «ì­® ¯à¨¡«¨¦¥­  ª ZX-Spectrum-128/256
¨ ¢ª«î砥⠢ ᥡï á奬㠬ã§ëª «ì­®£® á®¯à®æ¥áá®à  AY-3-8910. ‚ í⮩
ª®­ä¨£ãà æ¨¨ ®âáãâáâ¢ãîâ à áè¨à¥­­ë¥ ०¨¬ë íªà ­ .
‚â®à ï ¢¥àá¨ï á奬ë AY ¢ª«î砥⠢ ᥡï âਠ£¥­¥à â®à  £®«®á®¢,
£¥­¥à â®à è㬠 ¨ ॣã«ïâ®àë  ¬¯«¨âã¤ë. ƒ¥­¥à â®à ®£¨¡ î饩 ®âáãâáâ¢ã¥â.
’ ª ¦¥ ®âáãâáâ¢ã¥â ¢®§¬®¦­®áâì ç⥭¨ï ¨§ ¯®à⮢ ¤ ­­ëå á®¯à®æ¥áá®à .
‚ âà¥â쥩 ¢¥àᨨ AY ¯à¥¤¯®« £ ¥âáï ¤ ­­ë¥ ­¥¤®áâ âª¨ ¨áª«îç¨âì.
Š®­ä¨£ãà æ¨ï Sprinter-3.
Š®­ä¨£ãà æ¨ï ®â¢ï§ ­  ®â ª®­ä¨£ãà æ¨¨ ZX-Spectrum. ®«­®áâìî
®âª«îç ¥âáï ‡“ ¨ ¢á¥  ¤à¥á­®¥ ¯à®áâà ­á⢮ à §¡¨â® ­  ç¥âëॠ®ª­  ¯® 16k,
¢ ª ¦¤®¥ ¨§ ª®â®àëå ¯®¤ª«îç ¥âáï «î¡ ï ¨§ 256-⨠áâà ­¨æ އ“. Žâáãâáâ¢ã¥â
ᯥªâà㬮¢áª¨© íªà ­, £à ä¨ç¥áª¨© íªà ­ â ª®© ¦¥, ª ª ¢ ª®­ä¨£ãà æ¨ïå
Sprinter-1 ¨ Sprinter-2. ˆ¬¥¥â ¤®¯®«­¨â¥«ì­ë¥ ä㭪樨  ªá¥«¥à â®à .
®§¢®«ï¥â ¯à®¨§¢®¤¨âì ®¯¥à æ¨¨ AND, OR ¨ XOR á ¡«®ª ¬¨ ¤ ­­ëå. ˆ¬¥¥â 8-bit
COVOX.
‚ ¤ «ì­¥©è¥¬ ¯à¥¤¯®« £ ¥âáï ¯®¤ª«î祭¨¥ ¢ í⮩ ª®­ä¨£ãà æ¨¨
á¯à¨­â¥à®¢áª®© §¢ãª®¢®© ª àâë.
Š®­ä¨£ãà æ¨ï Game-1.
®å®¦  ­  ª®­ä¨£ãà æ¨î Sprinter-3. €ªá¥«¥à â®à ­¥ ¨¬¥¥â «®£¨ç¥áª¨å
ä㭪権,   ¤«ï ¢ë¢®¤  §¢ãª  ¨¬¥¥â COVOX-Blaster - COVOX á ¡ãä¥à­ë¬ އ“,
¯®§¢®«ïî騬 ¢ë¢®¤¨âì §¢ãª ¯®¡«®ç­® ¨ ®á¢®¡®¦¤ âì ¯à®æ¥áá®à­®¥ ¢à¥¬ï ¤«ï
¤à㣮© à ¡®âë. Š®­ä¨£ãà æ¨ï ®à¨¥­â¨à®¢ ­  ­  ¨á¯®«ì§®¢ ­¨¥ ¢ ¨£à å ¤«ï
Sprinter- .
‘奬  à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨.
‘奬ë à á¯à¥¤¥«¥­¨ï ¯ ¬ï⨠¢ ª®­ä¨£ãà æ¨ïå Sprinter-1 ¨ Sprinter-2
®¤¨­ ª®¢ë ¨ ¤®áâ â®ç­® ¯à®§à ç­ë. ” ªâ¨ç¥áª¨ ®­  ¯à¥¤áâ ¢«ï¥â ᮡ®© á奬ã
à á¯à¥¤¥«¥­¨ï ¯ ¬ï⨠ª®¬¯ìîâ¥à  Scorpion, á ­ «®¦¥­­®© ­  ­¥¥
¤®¯®«­¨â¥«ì­®© á奬®©, ª®â®à ï ¯®§¢®«ï¥â ¯à®¨§¢®«ì­® ãáâ ­ ¢«¨¢ âì ¢á¥
áâà ­¨æë ¯ ¬ïâ¨, ª ª ‡“, â ª ¨ އ“.
Š ¦¤ ï áâà ­¨æ  ‡“ ¨«¨ އ“ ¨¬¥¥â ᢮© ¯®àâ, ¢ ª®â®à®¬ 㪠§ë¢ ¥âáï
¤¥©á⢨⥫ì­ë© ­®¬¥à áâà ­¨æë ¨§ 256-⨠áâà ­¨æ ¢á¥å 4Mb. ‘âà ­¨æë,
¯à®¥æ¨àã¥¬ë¥ ¢ à §«¨ç­ë¥ ®ª­   ¤à¥á­®£® ¯à®áâà ­á⢠ ¯à®æ¥áá®à  ¨¬¥îâ ᢮¨
ᮡá⢥­­ë¥ ¯®àâë. ’.¥. ‘âà ­¨æ , ¢ª«îç ¥¬ ï ¢  ¤à¥á  #4000..#7FFF, ¨
áâà ­¨æ  ­®¬¥à 5 ®¡ëç­®£® Spectrum-®¢áª®£® à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨, ¢ª«îç ¥¬ ï
¢  ¤à¥á  #C000..#FFFF ¨¬¥îâ à §¤¥«ì­ë¥ ¯®àâë.
‚ᥣ® â ª¨å ¯®à⮢ áâà ­¨æ ¯ ¬ï⨠- 32.
16 ¯®à⮢ ®â¢¥ç îâ §  ­®¬¥à  áâà ­¨æ އ“, ¯®¤ª«îç ¥¬ë¥ ª  ¤à¥á ¬
#C000..#FFFF. …é¥ âਠ¯®àâ  ®â¢¥ç îâ §  ¯®¤ª«î祭¨¥ áâà ­¨æ އ“ ª  ¤à¥á ¬
#0000..#3FFF, #4000..#7FFF ¨ #8000..#BFFF. ‚®á¥¬ì ¯®à⮢ ¨á¯®«ì§ãîâáï ¤«ï
¯®¤ª«î祭¨ï à §«¨ç­ëå áâà ­¨æ ‡“. ޤ¨­ ¯®àâ - ¤«ï ¯®¤ª«î祭¨ï áâà ­¨æë
Š˜-  ¢¬¥áâ® ‡“. ˆ ®¤¨­ ¯®àâ - íâ® ¯®àâ á¨á⥬­®£® ‡“, ¯®¤ª«îç ¥¬®£® ­ 
¬¥áâ® ‡“ áà §ã ¯®á«¥ á¡à®á  ¬ è¨­ë ¯® ª« ¢¨è ¬ Ctrl+Alt+Del.
Žá⠢訥áï 3 ¯®àâ  áâà ­¨æ ¯ ¬ï⨠®áâ îâáï ­  ¤ ­­ë© ¬®¬¥­â ¢ १¥à¢¥.
‘奬  à á¯à¥¤¥«¥­¨ï ¯ ¬ï⨠¯®§¢®«ï¥â ¯®¤ª«îç¨âì ¢  ¤à¥á­®¥ ¯à®áâà ­á⢮
¯à®æ¥áá®à  ­¥ ⮫쪮 އ“ ¨«¨ ‡“, ­® ¨ ¯®àâë ¨ ¯ ¬ïâì ISA ª àâ, ¢áâ ¢«ï¥¬ëå
¢ á«®â.
ਠ¯®¤ª«î祭¨¨ ¢  ¤à¥á  #C000..#FFFF ᪮௨®­®¢áª¨å à áè¨à¥­­ëå
áâà ­¨æ އ“, ­  ¨å ¬¥áâ® ¬®¦­® ¯¥à¥ ¤à¥á®¢ âì á«®âë. „«ï í⮣® ­ ¤® ¯à®áâ®
§ ¯¨á âì ¢ ¯®àâ ®¤­®© ¨§ íâ¨å áâà ­¨æ §­ ç¥­¨¥, ᮮ⢥âáâ¢ãî饥 ISA-á«®âã,
ª ª®â®à®¬ã ­¥®¡å®¤¨¬® ¯à®¨§¢¥á⨠®¡à é¥­¨¥. â® §­ ç¥­¨¥ â ª ¦¥ 㪠§ë¢ ¥â
ª 祬㠢¥¤¥âáï ®¡à é¥­¨¥, ª ¯®àâ ¬ ¨«¨ ¯ ¬ïâ¨.
‘奬  à á¯à¥¤¥«¥­¨ï ¯ ¬ï⨠Sprinter- .
€¤à¥á­®¥ ¯à®áâà ­á⢮ ‘âà ­¨ç­ë¥ ¯®àâë ‡“ ª®¬¯ìîâ¥à 
¯à®æ¥áá®à  ¯®¤ª«îç ¥¬ëå áâà ­¨æ áâà ­¨æë ¯® 16k
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ #0000..#3FFF ÃÄ>´ ¯®àâë ÃÄÄ>´ ROM_BASIC ÃÄÄ>ÂÄÄÂÄÄÂÄ>´ EXPANSION ³
³ ³ ³ #7FFD,³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ³ #1FFD ÃÄ¿ ³ ROM_TR-DOS ÃÄÄ>´ ³ ÃÄ>´ TR-DOS ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÀÄÄÄÄÄÄÄÙ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ #4000..#7FFF ÃÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ ³ ³ ³ ÃÄ>´ BASIC128 ³
³ ³ ³ ³ ÃÄ Ä Ä Ä Ä Ä Ä ´ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ³ ³ ³ ROM_SYSTEM ÃÄÄ>Ù ³ ÃÄ>´ BASIC48 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ #8000..#BFFF ÃÄÄÄÄ¿ ³ À>´ RAM_0000 ÃÄÄÄ>¿ ³ ÃÄ>´ SYSTEM ROM ³
³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ³ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ ÃÄ>´ SYSTEM ROM2 ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÀÄÄ>´ RAM_4000 ÃÄÄÄ>´ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ #C000..#FFFF ÿ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ÃÄ>´ CONFIG 2 ³
³ ³³ ³ ³ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³³ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ ÀÄ>´ CONFIG 1 ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ ÀÄÄÄÄÄÄÄÄ>´ RAM_8000 ÃÄÄÄ>´ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³
³ ³ ³ އ“ ª®¬¯ìîâ¥à 
³ ÚÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³ áâà ­¨æë ¯® 16k
³ ³ ®àâë ÃÄÄ>´ RAM_0 ÃÄÄÄ>´ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ ³ #7FFD,³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄ>ÂÄ>´ RAM_00 ³
À>´ #1FFD ÃÄÄ>´ ÃÄÄÄ>´ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ÃÄ Ä Ä Ä Ä Ä Ä ³ ³ ³ ÃÄ>´ RAM_01 ³
³ ÃÄÄ>´ RAM_7 ÃÄÄÄ>´ ÀÄ>´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ³ ³
³ ÃÄÄ>´ RAM_8 ÃÄ>ÂijÄÄÄ>´ ÃÄ Ä Ä Ä Ä Ä Ä ´
³ ³ ÃÄ Ä Ä Ä Ä Ä Ä ´ ³ ³ ÀÄÄ´ RAM_7F ³
³ ÃÄÄ>´ ÃÄ>´ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÀÄÄÄ>ÂÄ>´ RAM_80 ³
³ ÃÄÄ>´ RAM_F ÃÄ>ÁÄ>¿ ³ ÃÄ Ä Ä Ä Ä Ä Ä ´
ÀÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ³ ³
‚­¥è­¨¥ ãáâனá⢠ ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ÃÄ>´ RAM_FE ³
®àâë ÃÄÄÄÄ>´ ISA_1 Ã<ÄÄÄÄ´ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
ª®¬¯ìîâ¥à  ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÀÄ>´ RAM_FF ³
ÃÄÄÄÄ>´ ISA_2 Ã<ÄÄÄÄ´ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
ÃÄÄÄÄ>´ HDD Ã<ÄÄÄÄ´
³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
ÃÄÄÄÄ>´ OVER DEVICES Ã<ÄÄÄÄÙ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
¨áã­®ª 2.
‚ ¤àã£¨å ª®­ä¨£ãà æ¨ïå á奬  à á¯à¥¤¥«¥­¨ï ¯ ¬ï⨠ã¯à®é ¥âáï ¤«ï
®á¢®¡®¦¤¥­¨ï à¥áãàᮢ ‹Œ. Œ®£ãâ ®âáãâá⢮¢ âì ¯®àâë #1FFD ¨ #7FFD,   â ª
¦¥ ã¯à®é ¥âáï á奬  à ¡®âë á ãáâனá⢠¬¨, ®â®¡à ¦ ¥¬ë¬¨ ­  ¯ ¬ïâì.
‘奬  à á¯à¥¤¥«¥­¨ï ¯®à⮢.
Sprinter ¨¬¥¥â ¤¢¥ ®¡®á®¡«¥­­ë¥ £àã¯¯ë ¯®à⮢. ¥à¢ ï £à㯯 , íâ®
¢­ãâ७­¨¥ ¯®àâë ¯à®æ¥áá®à  Z84C15, ¢â®à ï - ¢­¥è­¨¥ ¯®àâë. €¤à¥á æ¨ï
¯®à⮢ ¯¥à¢®© £àã¯¯ë ­¥ ¬®¦¥â ¡ëâì ¨§¬¥­¥­ , â ª ª ª í⨠¯®àâë ­  ®¤­®¬
ªà¨áâ ««¥ á ¯à®æ¥áá®à®¬. ‚â®à ï £à㯯  ¯®£ª«îç ¥âáï ç¥à¥§ ‹Œ ¨ ¨å  ¤à¥á 
¬®£ãâ ¨§¬¥­ïâìáï ª ª 㣮¤­®, á ¥¤¨­á⢥­­ë¬ ãá«®¢¨¥¬, ­¥¯¥à¥á¥ç¥­¨ï á
 ¤à¥á ¬¨ ¯¥à¢®© £à㯯ë.
Ž â®¬ ª ª¨¥ ¯®àâë ¨¬¥îâáï ­  ªà¨áâ ««¥ Z84C15 ¬®¦­® ¯à®ç¨â âì ¢
¤®ªã¬¥­â æ¨¨ ¯® íâ®¬ã ¯à®æ¥áá®àã ¨ §¤¥áì ï 㯮¬ï­ã ­¥ª®â®àë¥ ¨§ ­¨å. ޤ¨­
¨§ ¯®á«¥¤®¢ â¥«ì­ëå ¯®à⮢ ¨á¯®«ì§ã¥âáï ¤«ï ¢¢®¤  ¤ ­­ëå á  ªâ¨¢­®© ¬ëè¨.
ޤ¨­ ¨§ ¯ à ««¥«ì­ëå ¨á¯®«ì§ã¥âáï ¤«ï ¢ë¢®¤  ¤ ­­ëå, ­  ¢â®à®© ¯ à ««¥«ì­ë©
¯®àâ § ¢¥¤¥­ë ᨣ­ «ë ¯à¥à뢠­¨© ¨ § ¯à®á®¢ ¯àאַ£® ¤®áâ㯠 ᮠ᫮⮢ ISA.
 à ««¥«ì­ë© ¯®àâ ¯à®æ¥áá®à  Z84C15 ãáâ஥­ â ª¨¬ ®¡à §®¬, çâ® ­  ­¥¬
¢®§¬®¦­  ®à£ ­¨§ æ¨ï ¯à¥à뢠­¨© ¯® ᨣ­ « ¬ ¯à¨å®¤ï騬 ç¥à¥§ ¯ à ««¥«ì­ë©
¯®àâ. ” ªâ¨ç¥áª¨ ¢â®à®© ¯ à ««¥«ì­ë© ¯®à⠨ᯮ«ì§ã¥âáï ª ª ª®­â஫«¥à
¯à¥à뢠­¨©.
‘奬  à á¯à¥¤¥«¥­¨ï ¯®à⮢ ¢â®à®© £àã¯¯ë ¨¬¥¥â á¢®î ®á®¡¥­­®áâì.
ƒ« ¢­®© ¨¤¥¥© ¡ë«® ¯®«ã祭¨¥ ¢®§¬®¦­®á⨠¡ëáà® ¨§¬¥­ïâì ª®­ä¨£ãà æ¨î ¯®à⮢
¡¥§ ¯¥à¥£à㧪¨ ‹Œ. â® ¤®á⨣­ãâ® ¯ã⥬ ¯à¨¬¥­¥­¨ï ª àâë à á¯à¥¤¥«¥­¨ï
¯®à⮢, à á¯®« £ î饩áï ­  ᯥ樠«ì­®© áâà ­¨æ¥ އ“.
ਠ¯®ï¢«¥­¨¨ 横«  ®¡à é¥­¨ï ª ¯®àâã á­ ç «  ¯à®¨á室¨â ®¡à é¥­¨¥
ª އ“ ª àâë ¯®à⮢. ‚ ª à⥠¯®à⮢ § ¯¨á ­® ª ª®© ¨¬¥­­® ¯®àâ ¯®¤ª«î祭 ª
¤ ­­®¬ã  ¤à¥áã. „ «¥¥ ¯à®¨á室¨â ¢­ãâ७­ïï ¤¥è¨äà æ¨ï ¯® ¡ ©âã ¨§ ª àâë
¯®à⮢ ¨ ®¡à é¥­¨¥ ª ¢ë¡à ­­®¬ã ¯®àâã. ‚ ०¨¬¥ ­¥âãà¡® íâ® ¯à®¨á室¨â ¡¥§
ª ª¨å «¨¡® § ¤¥à¦¥ª,   ¢ ०¨¬¥ âãà¡® ¯à®æ¥áá®àã ¢ëáâ ¢«ï¥âáï ᨣ­ « WAIT ¢
§ ¢¨á¨¬®á⨠®â ­¥®¡å®¤¨¬®© ¤«¨­ë 横«  ®¡à é¥­¨ï ª ¯®àâã.
„«ï ¯®¤ª«î祭¨ï ª ª ª®¬ã «¨¡®  ¤à¥áã ¨«¨ ®âª«î祭¨ï ®â ­¥£® ª ª®£®
«¨¡® ¯®àâ  ¤®áâ â®ç­® ®âªàëâì ª àâã ¯®à⮢ ¨ ¢¯¨á âì ¢ ­ã¦­®¥ ¬¥áâ® ®¤¨­
¡ ©â.
‚ áâà ­¨æ¥ ª àâë ¯®à⮢ ᮤ¥à¦¨âáï ç¥âëॠª àâë, ª®â®àë¥ ¬®£ãâ
¯¥à¥ª«îç âìáï ç¥à¥§ á¨á⥬­ë© ¯®àâ. ’ ª¨¬ ®¡à §®¬ ¬®¦­® ®áãé¥á⢨âì ¡ëáâ஥
¯¥à¥ª«î祭¨¥ ª®­ä¨£ãà æ¨¨ ¯®à⮢, çâ® ¬®¦¥â ¡ëâì ¯®«¥§­® ¯à¨ à ¡®â¥
Spectrum-®¢áª¨å ¯à®£à ¬¬ ᮢ¬¥áâ­® á® Sprinter-®¢áª¨¬ ¡¨®á®¬.
Š®­ªà¥â­ë¥  ¤à¥á  ¯®à⮢, ¨á¯®«ì§ã¥¬ë¥ ¢ Sprinter-¥.
‡¤¥áì ï ¯à¨¢¥¤ã  ¤à¥á æ¨î ¯®à⮢ ¤«ï ª®­ä¨£ãà æ¨© Sprinter-1 ¨
Sprinter-2. ‘ࠧ㠮⬥çã, çâ® í⨠ ¤à¥á  «¥£ª® ¬®£ãâ ¡ëâì ¨§¬¥­¥­ë ¯à®á⮩
¯à®£à ¬¬®©, ¢ á«ãç ¥ ¯®ï¢«¥­¨ï â ª®© ­¥®¡å®¤¨¬®áâ¨.
‘â ­¤ àâ­ë¥ ¯®àâë.
#FE - RD_KBD - ¯®àâ ª« ¢¨ âãàë
#FE - WR_BRD - ¯®àâ ¡®à¤îà 
#7FFD - ¯®àâ à áè¨à¥­¨ï ZX-Spectrum 128k
#1FFD - ¯®àâ à áè¨à¥­¨ï Scorpion ZS-256
#1F,#0F - RD_KEMPS - ¯®àâ ¤¦®©á⨪ . ‚ ª®­ä¨£ãà æ¨¨ Sprinter-1 ¯®àâ
#1F  ¯¯ à â­® ¯¥à¥ ¤à¥áã¥âáï ­  ¯®àâ #0F
#BFFD,#FFFD - AY-PORTS - ¯®àâë AY-á®¯à®æ¥áá®à  (ZX-Spectrum-256/AY)
¥ ᮢᥬ áâ ­¤ àâ­ë¥ ¯®àâë.
#FB,#4F - ¯®àâ COVOX- .
„®¯®«­¨â¥«ì­ë¥ 8-¡¨â­ë¥ ¯®àâë Sprinter- .
#82 - PAGE0 - áâà ­¨æ  އ“, ¯®¤ª«îç ¥¬ ï ¢¬¥áâ® ‡“ ç¥à¥§ ¯®àâ #1FFD
#A2 - PAGE1 - áâà ­¨æ  އ“, ¯®¤ª«î祭­ ï ¯®  ¤à¥áã #4000
#C2 - PAGE2 - áâà ­¨æ  އ“, ¯®¤ª«î祭­ ï ¯®  ¤à¥áã #8000
#E2 - PAGE2 - áâà ­¨æ  އ“, ¯®¤ª«î祭­ ï ¯®  ¤à¥áã #C000
‡¤¥áì ­ ¤® ®â¬¥â¨âì ®á®¡®, ç¥à¥§ ¯®àâ #E2 ¬®¦­® ¨§¬¥­¨âì «î¡ãî ¨§
16-⨠áâà ­¨æ ᪮௨®­®¢áª®£® à á¯à¥¤¥«¥­¨ï ¯ ¬ïâ¨.
#89 - PORT_Y - ¢¥à⨪ «ì­ ï ª®®à¤¨­ â  â®çª¨ ­  £à ä¨ç¥áª®¬ íªà ­¥
¨«¨ áâà ­¨æ  VIDEO-RAM ¤«ï ᯥªâà㬮¢áª®£® ०¨¬ 
#C9 - RGMOD - ¯®àâ ०¨¬  íªà ­ . ¥à¥ª«îç ¥â áâà ­¨æë ०¨¬  íªà ­ .
#3C,#7C - SYS_PORT - á¨á⥬­ë© ¯®àâ âண âì ­¥ ४®¬¥­¤ã¥âáï
#10..#1F,#EE,#EF,#F0,#F1,#F4 - ¢­ãâ७­¨¥ ¯®àâë Z84C15
®àâë áâà ­¨æ އ“ ®âªàëâë ª ª ­  § ¯¨áì, â ª ¨ ­  ç⥭¨¥. â®
¯®§¢®«ï¥â «¥£ª® ¢ë¯®«­ïâì ¯à®£à ¬¬ë, ¨á¯®«ì§ãî騥 ¯¥à¥ª«î祭¨¥ áâà ­¨æ,  
§ â¥¬ ¢®§¢à é âì í⨠áâà ­¨æë ­ § ¤. ਠࠡ®â¥ BIOS-  ¢á¥ áâà ­¨æë
á®åà ­ïîâáï.
„®¯®«­¨â¥«ì­ë¥ 16-⨡¨â­ë¥ ¯®àâë Sprinter- .
#xx50..#xx55 - ¯®àâë HDD - ¨á¯®«ì§®¢ âì ¢­¥è­¨¬¨ ¯à®£à ¬¬ ¬¨ ­¥
४®¬¥­¤ã¥âáï. ”㭪樨 à ¡®âë á HDD § ¯¨á ­ë ¢ ‡“.
‘ªàëâë¥ ¯®àâë Sprinter- .
‘ªàëâ묨 ïîâáï ¯®àâë ª®â®àë¥ ­¤®áâã¯­ë ¢ ª®­ªà¥â­ë© ¬®¬¥­â
¢à¥¬¥­¨, ­® ¬®£ãâ áâ âì ¤®áâ㯭묨 ¯®á«¥ ¯à®¢¥¤¥­¨ï ¨§¬¥­¥­¨© ¢ ª à⥠¯®à⮢.
ˆå  ¤à¥á  ­¥ 㪠§ë¢ îâáï, â ª ª ª ®­¨ ¬®£ãâ ¡ëâì ¢ëáâ ¢«¥­ë ¢ «î¡®¥ ¬¥áâ®.
®àâ ‡“ BASIC48
®àâ ‡“ BASIC128
®àâ ‡“ TR-DOS
®àâ ‡“ EXPANSION
®àâ ‡“ SYSTEM
—¥à¥§ í⨠¯®àâë ¬®¦­® ãáâ ­®¢¨âì ­®¢ë¥ ¯à®è¨¢ª¨ ‡“. „«ï í⮣® ¨å
¤®áâ â®ç­® § ¯¨á âì ¢ އ“ á ­®¬¥à ¬¨ áâà ­¨æ ¬¥­ìè¥ #80 ¨ § ¯¨á âì ¢
ᮮ⢥âáâ¢ãî騩 ¯®àâ ­®¬¥à í⮩ áâà ­¨æë. ਠ⠪®¬ ¯®¤ª«î祭¨¨ áâà ­¨æë
⨠áâà ­¨æë ¡ã¤ãâ § é¨é¥­ë ®â § ¯¨á¨.
— áâ¨ç­® áªàëâ묨, â ª ¦¥ ïîâáï ¨ ¯®àâë #7FFD,#1FFD ¢ ®¡ëç­®¬
á®áâ®ï­¨¨ ®­¨ ¤®áâ㯭ë ⮫쪮 ­  § ¯¨áì, ­® §­ ç¥­¨ï, § ¯¨á뢠¥¬ë¥ ¢ íâ¨
¯®àâë ¬®¦­® ¯à®ç¨â âì, ®âªàë¢ á®®â¢¥âáâ¢ãî騥 ¯®àâë ­  ç⥭¨¥.
‚ ¤àã£¨å ª®­ä¨£ãà æ¨ïå ¬®¦¥â ®âáãâá⢮¢ âì ç áâì ¯®à⮢ ¨«¨
¯à¨áãâá⢮¢ âì ­®¢ë¥ ¯®àâë.
Žà£ ­¨§ æ¨ï ¢¨¤¥®¯ ¬ï⨠¨ ¢¨¤¥®à¥¦¨¬®¢.
‚¨¤¥®-އ“ Sprinter-  á®áâ ¢«ï¥â 256 ª¨«®¡ ©â. ‚ ¤ «ì­¥©è¥¬
¯à¥¤¯®« £ ¥âáï ¥£® à áè¨à¥­¨¥ ¤® 512 ª¨«®¡ ©â, ¤«ï ¯®«ã祭¨ï ¡®«¥¥
¢ë᮪¨å ०¨¬®¢ à §à¥è¥­¨ï.
‚ ०¨¬¥ Spectrum-®¢áª®£® íªà ­  ¢áï ®à£ ­¨§ æ¨ï â ª ï ¦¥ ª ª ¢
áâ ­¤ àâ­®¬ ZX-Spectrum. ‚ ®áâ «ì­ëå ०¨¬ å ¢ª«îç ¥âáï Sprinter-®¢áª¨©
íªà ­, áâàãªâãà  ª®â®à®£® ¢ª«î砥⠢ á¥¡ï ‘¯¥ªâà㬮¢áª¨© íªà ­ ª ª ç áâì
á奬ë.
“áâனá⢮ íªà ­ .
‚¥áì íªà ­ à §¡¨â ­  ª¢ ¤à âë, à §¬¥à®¬ ¢ áâ ­¤ àâ­®¥
‘¯¥ªâà㬮¢áª®¥ §­ ª®¬¥áâ®. „«ï ª ¦¤®£® ª¢ ¤à â  ãáâ ­ ¢«¨¢ ¥âáï ᢮©
ᮡá⢥­­ë© ०¨¬ ¢ë¢®¤ ,   â ª ¦¥  ¤à¥á ¢¨¤¥®-އ“, ®âªã¤  ¯à®¨§¢®¤¨âáï
¢ë¢®¤ ¢ íâ®â ª¢ ¤à â.
‚ ª ¦¤®¬ §­ ª®¬¥á⥠¬®¦¥â ¡ëâì § ¤ ­ ᢮© ᮡá⢥­­ë© ०¨¬ ¢ë¢®¤ .
‚ ¤ ­­ë© ¬®¬¥­â ¬®¦­® ãáâ ­ ¢«¨¢ âì â ª¨¥ ०¨¬ë:
ZX-40 - ®¡ëç­ë© ᯥªâà㬮¢áª¨© ०¨¬ á ®¤­¨¬ ¡¨â¯« ­®¬ ¨
®¤­¨¬  âਡã⮬ ­  §­ ª®¬¥áâ®.
ZX-80 - ¥¦¨¬, ¯®å®¦¨© ­  ᯥªâà㬮¢áª¨© ¯® áâ஥­¨î
ᨬ¢®«®¢, ­® ¢ ª ¦¤®¬ §­ ª®¬¥á⥠®ª §ë¢ ¥âáï ¤¢  ᨬ¢®« , ᦠâë¥ ¯®
£®à¨§®­â «¨.
G256-8 - ƒà ä¨ç¥áª¨© ०¨¬. Š¢ ¤à â ¯à¥¤áâ ¢«ï¥â ᮡ®© ¬ áᨢ 8x8
â®ç¥ª. ‚ ª ¦¤®© â®çª¥ § ¤ ¥âáï ®¤¨­ ¨§ 256-⨠梥⮢, ¢ë¡¨à ¥¬ëå ¨§ ¯ «¨âàë
16 ¬¨««¨®­®¢ 梥⮢. Š¢ ¤à âë ¬®£ãâ ¨¬¥âì à §­ë¥ ¯ «¨âàë. ’ ª¨å ¯ «¨âà ¤«ï
०¨¬  G256-8 - ç¥âëà¥.
G16-16 - ƒà ä¨ç¥áª¨© ०¨¬. Š¢ ¤à â ¯à¥¤áâ ¢«ï¥â ᮡ®© ¬ áᨢ
16x8 â®ç¥ª. Š ¦¤ ï â®çª  ¨¬¥¥â ®¤¨­ ¨§ 16 梥⮢, ¢ë¡¨à ¥¬ëå ¨§ ¯ «¨âàë 16
¬¨««¨®­®¢ 梥⮢. ’ ª ¦¥, ª ª ¨ G256-8 ¢ ª¢ ¤à â¥ ¬®¦¥â ¡ëâì ãáâ ­®¢«¥­ 
®¤­  ¨§ 4-å ¯ «¨âà.  «¨âàë £à ä¨ç¥áª¨å ०¨¬®¢ ¯¥à¥á¥ª îâáï ¤àã£ á ¤à㣮¬.
 «¨âà  16-â¨æ¢¥â­®£® ०¨¬  íâ® ¯¥à¢ë¥ 16 梥⮢ ¨§ ¯ «¨âàë 256-â¨æ¢¥â­®£®.
BORDER - ‚ ª¢ ¤à â ¢ë¢®¤¨âáï æ¢¥â ¡®à¤¥à .
BLANK - Š¢ ¤à â £ á¨âáï - áâ ­®¢¨âáï ç¥à­ë¬.
Ž¡ê¥¬ ¤ ­­ëå ०¨¬  ª¢ ¤à â  á®áâ ¢«ï¥â 2 ¡ ©â ,
¯®í⮬㠨§¬¥­¥­¨¥ ०¨¬  ¢á¥£® íªà ­  ᢮¤¨âáï ª ¯¥à¥§ ¯¨á¨ 2.5 ª¨«®¡ ©â
¤ ­­ëå ¢ ¢¨¤¥®-އ“.
®¤®¡­ ï áâàãªâãà  íªà ­  ¯®§¢®«ï¥â «¥£ª® ¯à®¨§¢®¤¨âì áªà®««¨­£¨
ª ª ¢á¥£®, â ª ¨ ç á⥩ íªà ­  ¯® §­ ª®¬¥áâ ¬.
¥¦¨¬ íªà ­  ãáâ ­ ¢«¨¢ ¥âáï ¯à¨ ¢ª«î祭¨¨,   â ª ¦¥ á ¯®¬®éìî
ä㭪権 ¡¨®á . ”㭪樨 ¡¨®á  ¯®§¢®«ïîâ ®âªà뢠âì ­  íªà ­¥ £à ä¨ç¥áª¨¥ ¨
⥪áâ®¢ë¥ ®ª­  ¢ ­ã¦­ëå ¬¥áâ å ¨ ­ã¦­®£® à §¬¥à .
‚ ¡¨®á¥ ¨¬¥îâáï ä㭪樨 ®âªàëâ¨ï £à ä¨ç¥áª®£® íªà ­  ­  ¢¥áì íªà ­
320x256 â®ç¥ª. ®á«¥ ®âªàëâ¨ï í⮣® ०¨¬  íªà ­ ¯à¥¤áâ ¢«ï¥â ᮡ®©.
­ ¡®à ¨§ 256-⨠«¨­¨©, ¤«¨­®© ¯® 320 ¡ ©â. ‘®á¥¤­¨¥ â®çª¨ ¢ «¨­¨¨ - íâ®
á®á¥¤­¨¥ ¡ ©âë. ¥à¥ª«î祭¨¥ «¨­¨© ¯à®¨§¢®¤¨âáï ç¥à¥§ PORT_Y, ¢ ª®â®à®¬
ãáâ ­ ¢«¨¢ ¥âáï ­®¬¥à «¨­¨¨, ¢ë¢®¤¨¬®© ­  íªà ­. ®¬¥à  «¨­¨© áç¨â îâáï
ᢥàåã íªà ­ , ­ ç¨­ ï á ­ã«¥¢®©.
„«ï ¢ë¢®¤  ¢ £à ä¨ç¥áª¨© íªà ­ â ª ¦¥ âॡã¥âáï ®âªàëâì
ᮮ⢥âáâ¢ãîéãî áâà ­¨æã ®á­®¢­®£® އ“. ‚ í⮩ áâà ­¨æ¥ ¡ã¤¥â ᮤ¥à¦ âìáï
ª®¯¨ï ¢¨¤¥®¨§®¡à ¦¥­¨ï.
‚¨¤¥®-އ“ ï¥âáï ⥭¥¢ë¬ އ“, ¯®í⮬㠨­ä®à¬ æ¨ï, ­ å®¤ïé ïáï ¢
®á­®¢­®¬ އ“, ¯®¤ ª®â®àë¬ ­ å®¤¨âáï ¢¨¤¥®-އ“ ­¥ ®¡ï§ â¥«ì­® ¡ã¤¥â
ᮢ¯ ¤ âì á ¨­ä®à¬ æ¨¥©, ­ å®¤ï饩áï ¢ í⮬ ¢¨¤¥®-އ“. ‡ ¯¨áì ¢¨¤¥®-¤ ­­ëå
¬®¦¥â ¯à®¨§¢®¤¨âìáï ¨ ¡¥§ ¯¥à¥§ ¯¨á¨ ¤ ­­ëå ¢ ®á­¢­®¬ އ“, çâ® ®ª §ë¢ ¥âáï
¯®«¥§­ë¬ ¯à¨ à ¡®â¥, ­ ¯à¨¬¥à, á® á¯à ©â ¬¨. „«ï à ¡®âë á® á¯à ©â ¬¨ â ª ¦¥
¯à¥¤ãᬮâ७ ०¨¬ § ¯¨á¨ ¢ ¢¨¤¥®-އ“ á ¯à®§à ç­ë¬ 梥⮬. ‚ í⮬ ०¨¬¥
¨­ä®à¬ æ¨ï, ¯¥à¥¤ ¢ ¥¬ ï ¢ ¢¨¤¥®-އ“ ¯à®¢¥àï¥âáï ­  ­ «¨ç¨¥ ¡ ©â  #FF. …᫨
íâ®â ¡ ©â ®¡­ à㦨¢ ¥âáï, ⮠横« § ¯¨á¨ ¯à®¯ã᪠¥âáï ¨ ­  íªà ­¥ ¢ í⮬
¬¥á⥠®áâ ¥âáï ⥠¤ ­­ë¥, ª ª¨¥ ¡ë«¨ à ­¥¥. ’ ª¨¬ ®¡à §®¬ ­  íªà ­¥ ¬®¦­®
¡ëáâà® ¯à®à¨á®¢ë¢ âì á¯à ©âë, ¯à¥¤áâ ¢«ïî騥 ¨§ á¥¡ï ¯àאַ㣮«ì­ë¥ ª à⨭ª¨
á "¯à®§à ç­ë¬¨" 梥⠬¨.
ਬ¥à ¯à®£à ¬¬ë ¢ë¢®¤  ¯àאַ㣮«ì­®© ª à⨭ª¨ ­  íªà ­:
PAGE3 EQU #E2
RGADR EQU #89
LD A,#50 ; áâà ­¨æ  £à ä¨ç¥áª®£® ¢¨¤¥®íªà ­ 
OUT (PAGE3),A ; ãáâ ­®¢¨âì ¢ PAGE3
LD HL,Pucture ;  ¤à¥á ª à⨭ª¨ (àï¬ë¥ „ ­­ë¥)
LD DE,#C040+HorPlace ; ¯®«®¦¥­¨¥ ª à⨭ª¨ ­  íªà ­¥ ¯® £®à¨§®­â «¨
LD A,VerPlace ; ¯®«®¦¥­¨¥ ª à⨭ª¨ ­  íªà ­¥ ¯® ¢¥à⨪ «¨
OUT (RGADR),A
LD B,VerSize ; ¢ëá®â  ª à⨭ª¨
LOOP: PUSH DE ; § ¯®¬­¨âì ¯®«®¦¥­¨¥ ­  «¨­¨¨
PUSH BC ; § ¯®¬­¨âì áç¥â稪 ¢ëá®âë
LD BC,HorSize ; ¤«¨­  ª à⨭ª¨
LDIR ; ª®¯¨à®¢ âì «¨­¨î
POP BC
POP DE
INC A ; á«¥¤ãîé ï ª®®à¤¨­ â  ¯® Y
OUT (RGADR),A
DJNZ LOOP ; ¯®¢â®àïâì ­ã¦­®¥ ª®«¨ç¥á⢮ à §
“¯à ¢«¥­¨¥ ०¨¬®¬ ¢ë¢®¤  ­  íªà ­ (¢ª«î祭¨¥ ¢ë¢®¤  á ¯à®§à ç­ë¬¨
梥⠬¨, ®âª«î祭¨¥ ª®¯¨à®¢ ­¨ï ¢ ®á­®¢­®¥ އ“) ®áãé¥á⢫ï¥âáï ç¥à¥§
¬« ¤è¨¥ ¡¨âë ¯®àâ  áâà ­¨æë £à ä¨ç¥áª®£® íªà ­ .
€ªá¥«¥à â®à ®¯¥à æ¨© á Ž‡“.
€ªá¥«¥à â®à ®¯¥à æ¨© á Ž‡“ ¯à¥¤­ §­ ç¥­ ¤«ï ã᪮७¨ï ®¯¥à æ¨©
¯® ¯¥à¥á뫪¥ ¤ ­­ëå ¨«¨ ¯® § ¯®«­¥­¨î އ“ ®¤­¨¬ ¡ ©â®¬. €ªá¥«¥à â®à
¯à¨áãâáâ¢ã¥â ¢ ç¨áâ® Sprinter-®¢áª¨å ª®­ä¨£ãà æ¨ïå ¨ ¯®í⮬㠭¨ª ª ­¥
¬¥è ¥â à ¡®â¥ ®¡ëç­ëå Spectrum-®¢áª¨å ¯à®£à ¬¬.
Žá­®¢®©  ªá¥«¥à â®à  ï¥âáï ¡ëáâ஥ ¢­ãâ७­¥¥ އ“ ¢ ‹Œ.
ޝ¥à æ¨¨ ¯® ¯¥à¥á뫪¥ ¤ ­­ëå ¯à®¨§¢®¤ïâáï ¯ã⥬ § ¯¨á¨ ¡«®ª  ¤ ­­ëå ¢ íâ®
¢­ãâ७­¥¥ އ“,   § â¥¬ ª®¯¨à®¢ ­¨¨ ¥£® ¢ ­ã¦­®¥ ¬¥áâ® ¯ ¬ï⨠¨§ í⮣® އ“.
®á«¥ ®¤­®© § ¯¨á¨ ª®¯¨à®¢ ­¨¥ ¬®¦¥â ¯à®¨§¢®¤¨âìáï ­¥áª®«ìª® à § ¨ â ª¨¬
®¡à §®¬ ¬®¦­® ¯à®¨§¢®¤¨âì § ¯®«­¥­¨¥ íªà ­  ⥪áâãà ¬¨.
„«ï § ¯®«­¥­¨ï íªà ­  ®¤­¨¬ 梥⮬ ¨á¯®«ì§ã¥âáï ¤à㣮© ०¨¬
 ªá¥«¥à â®à . ‚ ­¥¬ ¢¬¥áâ® ª®¯¨à㥬®£® ¡«®ª  ¤ ­­ëå ¨§ ¢­ãâ७­¥£® އ“
¯à®¨§¢®¤¨âáï § ¯¨áì ¤ ­­ëå á è¨­ë ¯à®æ¥áá®à , ª®â®àë¥ ¢ íâ®â ¬®¬¥­â ­¥
¨§¬¥­ïîâáï.
«®ª ¤ ­­ëå, § ¯¨á뢠¥¬ë© ¢ އ“  ªá¥«¥à â®à  ¬®¦¥â ¨¬¥âì à §«¨ç­ãî
¤«¨­­ã ¨§ ¤¨ ¯ §®­  1..256 ¡ ©â.
“¯à ¢«¥­¨¥  ªá¥«¥à â®à®¬ ¯à®¨§¢®¤¨âáï ­¥¯®á।á⢥­­® ¨§ ¯à®£à ¬¬ë.
„«ï í⮣® ¨§¯®«ì§ãîâáï ª®¬ ­¤ë ¯à®æ¥áá®à , ª®â®àë¥ ä ªâ¨ç¥áª¨ ïîâáï
®¯¥à æ¨ï¬¨ ⨯  NOP.
â® ª®¬ ­¤ë LD A,A; LD B,B; LD C,C; LD D,D; LD E,E; LD H,H, LD L,L
 §­ ç¥­¨¥ ª®¬ ­¤ á«¥¤ãî饥:
LD B,B - ¢ëª«îç¨âì  ªá¥«¥â à®à.
LD D,D - ¢ª«îç¨âì  ªá¥«¥à â®à ¢ ०¨¬ ¯à¨¥¬  ¡ ©â  à §¬¥à  ¡«®ª 
¤ «¥¥ á«¥¤ã¥â ª®¬ ­¤  ⨯  LD A,dat, £¤¥ dat ¨ ¡ã¤¥â ­®¢ë¬
à §¬¥à®¬ ¡«®ª . …᫨ à §¬¥à ¡«®ª  ¡ë« ãáâ ­®¢«¥­ à ­¥¥,
¥£® ¬®¦­® ­¥ ãáâ ­ ¢«¨¢ âì.
LD C,C - ޝ¥à æ¨ï Fill - § ¯®«­¥­¨¥ ®¤­¨¬ ¡ ©â®¬. ®á«¥¤ãîé ï
ª®¬ ­¤  ⨯  LD (HL),A ¯à¨¢¥¤¥â ª § ¯®«­¥­¨î 㪠§ ­­®£®
à ­¥¥ ª®«¨ç¥á⢠ ¡ ©â §­ ç¥­¨¥¬ A
LD E,E - ޝ¥à æ¨ï Fill ¤«ï £à ä¨ç¥áª®£® íªà ­  - § ¯®«­¥­¨¥
¢¥à⨪ «ì­ëå «¨­¨©.
LD H,H - rezerved
LD L,L - ª®¯¨à®¢ ­¨¥ ¡«®ª . ®á«¥¤ãîé ï ª®¬ ­¤  ⨯  LD A,(HL)
¯à¨¢¥¤¥â ª § ¯®«­¥­¨î އ“  ªá¥«¥à â®à  ¤ ­­ë¬¨ ¨§  ¤à¥á  (HL),
  ª®¬ ­¤  ⨯  LD (DE),A ¯à¨¢¥¤¥â ª ¯¥à¥§ ¯¨á¨ ¤ ­­ëå ¨§ އ“
 ªá¥«¥à â®à  ¢ ®á­®¢­®¥ ¨«¨ ¢¨¤¥®-އ“.
LD A,A - ª®¯¨à®¢ ­¨¥ ¡«®ª  ¤«ï £à ä¨ç¥áª®£® íªà ­  ¯®¤®¡­  ª®¬ ­¤¥
LD L,L, ­® à ¡®â ¥â á ¢¥à⨪ «ì­ë¬¨ «¨­¨ï¬¨ íªà ­ .
ਬ¥à ¨á¯®«ì§®¢ ­¨ï  ªá¥«¥à â®à :
; ‘ç¨â ¥¬, çâ® íªà ­­ ï áâà ­¨æ  㦥 ®âªàëâ  ¯®  ¤à¥áã #C000
LD HL,#C040 ;  ¤à¥á ­ ç «  «¨­¨¨ ¯¥à¢®£® íªà ­ 
LD DE,#C180 ;  ¤à¥á ­ ç «  «¨­¨¨ ¢â®à®£® íªà ­ 
LD BC,#140 ; ¤«¨­  íªà ­  ¯® £®à¨§®­â «¨
DI ; § ¯à¥â¨âì ¯à¥à뢠­¨ï ¤«ï à ¡®âë á  ªá¥«¥à â®à®¬
LD D,D ; ¢ª«îç¨âì  ªá¥«¥à â®à ­  ãáâ ­®¢ªã à §¬¥à  ¡«®ª 
LD A,0 ; ãáâ ­®¢¨âì à §¬¥à ¡«®ª  - 256 ¡ ©â
LD A,A ; ãáâ ­®¢¨âì  ªá¥«¥à â®à ­  ª®¯¨à®¢ ­¨¥
; ¢¥à⨪ «ì­ëå «¨­¨©.
LDIR ; ª®¯¨à®¢ âì !
LD B,B ; ¢ëª«îç¨âì  ªá¥«¥à â®à
EI ; ¢ª«îç¨âì ¯à¥à뢠­¨ï
â®â ®â१®ª ¯à®£à ¬¬ë ¯à®¨§¢¥¤¥â ª®¯¨à®¢ ­¨¥ ¢á¥£® íªà ­  á ®¤­®£®
íªà ­  ­  ¤à㣮©. ‚à¥¬ï ¥£® ¨á¯®«¥­¨ï á®áâ ¢«ï¥â ¯à¨¬¥à­® 1.2 ¨­â .
„®¯®«­¨â¥«ì­ë¥ ä㭪樨  ªá¥«¥à â®à  ¯®ï¢«ïî騥áï ¢ ª®­ä¨£ãà æ¨¨
Sprinter-3 à ¡®â îâ ¯®¤®¡­ë¬ ¦¥ ®¡à §®¬. „«ï ¢ë¯®«­¥­¨ï «®£¨ç¥áª¨å ä㭪権
¨á¯®«ì§ãîâáï ª®¬ ­¤ë XOR (HL); OR (HL); AND (HL).
ਬ¥à ªá®àª¨ ¡«®ª  ¢ 256 ¡ ©â.
LD HL,ADRES_1
LD DE,XOR_DAT
DI
LD D,D
LD A,0 ; ç¨á«® ¡ ©â, ª®â®àë¥ ­ ¤® ¯à®ªá®à¨âì
LD L,L
LD A,(DE) ; ‚§ïâì ¡«®ª ¢ އ“  ªá¥«¥à â®à 
XOR (HL) ; ¯à®¨§¢¥á⨠®¯¥à æ¨î XOR á ¤ ­­ë¬¨  ªá¥«¥à â®à 
LD (HL),A ; § ¯®¬­¨âì ¢ އ“ १ã«ìâ â ®¯¥à æ¨¨
LD B,B
EI
‘ª®à®áâì à ¡®âë  ªá¥«¥à â®à  ®£à ­¨ç¨¢ ¥âáï ⮫쪮 䨧¨ç¥áª®©
᪮à®áâìî à ¡®âë ®á­®¢­®£® އ“. Ž¯à¥¤¥«¨âì ¢à¥¬ï à ¡®âë ª®¬ ­¤ë á
 ªá¥«¥à â®à®¬ ¬®¦­® ¯® â ª®© ¯à¨¬¥à­®© ä®à¬ã«¥:
‚६ï à ¡®âë = ¢à¥¬ï à ¡®âë ª®¬ ­¤ë ¡¥§  ªá¥«¥à â®à  + ¢à¥¬ï
à ¡®âë  ªá¥«¥à â®à 
‚६ï à ¡®âë  ªá¥«¥à â®à  = ç¨á«® ¯¥à¥áë« ¥¬ëå ¡ ©â /7000000 (ᥪ㭤)
Žâª«î祭¨¥ ¯à¥à뢠­¨© ¢® ¢à¥¬ï à ¡®âë  ªá¥«¥à â®à  ­¥®¡å®¤¨¬®, â ª
ª ª ¢ íâ®â ¬®¬¥­â ç áâ¨ç­® ¬¥­ï¥âáï á¨á⥬  ª®¬ ­¤ ¯à®æ¥áá®à  ¨ ¯à®£à ¬¬ 
­  ¯à¥à뢠­¨¨ ­¥ ᬮ¦¥â à ¡®â âì ­®à¬ «ì­®.
‡ ª«î祭¨¥.
 ¡®â  ­ ¤ Sprinter-®¬ ¯à®¤®«¦ ¥âáï. ‘®¢¥à襭áâ¢ã¥âáï ¦¥«¥§® ¨
¡¨®á. ¨è¥âáï á®äâ, ¯®¤¤¥à¦¨¢ î騩 à áè¨à¥­­ë¥ ०¨¬ë à ¡®âë ª®¬¯ìîâ¥à .
® ¢á¥¬ ª®¬¬¥àç¥áª¨¬ ¢®¯à®á ¬ á¢ï§ ­­ë¬ á ¯à¨®¡à¥â¥­¨¥¬ ª®¬¯ìîâ¥à 
¬®¦­® ®¡à é âìáï ¢ ä¨à¬ã "¥â¥àá":
Adress: ‘ ­ªâ-¥â¥à¡ãà£, ã«. ‚®ááâ ­¨ï, ¤. 35, ®ä. 31.
Phone: (812)-327-35-31
E-mail: peters@atlant.ru
® â¥å­¨ç¥áª¨¬ ¢®¯à®á ¬ ®¡à é âìáï ª® ¬­¥:
Fido: Ivan Mak (2:5030/529.24)
E-mail: ivan_mak@yahoo.com (¢à¥¬¥­­® § ªàëâ)
File diff suppressed because it is too large Load Diff
+272
View File
@@ -0,0 +1,272 @@
# 1. Архитектура компьютера Sprinter Sp2000
## 1.1 Общие сведения
ZX Sprinter — универсальный компьютер на базе 8-битного процессора Z80. Основой является перепрограммируемая логическая матрица (ППЛМ/CPLD/FPGA), что обеспечивает гибкую изменяемую архитектуру — конфигурация схемы может меняться непосредственно во время работы.
Материнская плата — Sp2000 (разработана в конце 2000 г.).
| Параметр | Значение |
|---|---|
| Процессор | Z84C15 (Z80-совместимый, внутренние PIO/SIO/CTC) |
| Тактовая частота | 21 МГц (turbo) / 3.5 МГц (slow) |
| ОЗУ (main) | 4 МБ (72-pin SIMM) |
| Быстрое ОЗУ (КЭШ-ОЗУ) | 64 КБ (SRAM, без wait states) |
| ПЗУ | 256 КБ (8 страниц по 32 КБ) |
| Видео-ОЗУ | 256 КБ |
| Контроллер дисков | КР1818ВГ93 (аналог WD1793) |
| Поддержка НЖМД | IDE/AT |
| Контроллер клавиатуры | AT-совместимая (101 key), PS/2 |
| Контроллер мыши | Serial MS-Mouse (RS-232 через Z84C15 SIO) |
| Слоты расширения | 2 × ISA-8 |
| Звук | AY-3-8910 (в ППЛМ), 16-бит ЦАП TDA1543 (COVOX + AY) |
| COVOX-Blaster (CBL) | 16-bit с буферным ОЗУ 256 байт, 15/22 кГц |
| CMOS-часы | Dallas DS12887A (опционально, эмулируется при отсутствии) |
| Видеовыход | Аналоговый CGA-монитор, RGB, TV (SCART) |
## 1.2 Системная архитектура
Упрощённая структура:
```
┌─────────────┐
┌──────────┐ │ ISA-8 │
│ Принтер │ │ слот 1..2 │
│ Мышь │ └──────┬──────┘
│ Джойстик │ │
└─────┬────┘ ┌─────┴──────┐
│ │ Буферы и │
┌─────┴──────┐ │ дешифраторы│
│ Z84C15 │ └──────┬─────┘
│ (CPU + │◄─────────┤
│ PIO/SIO/ ├──────────┤
│ CTC) ├──────────┤
└─────┬──────┘ │
│ ┌────┴──────────┐
┌─────┴──────┐ │ EP1K30QC208 │
│ ROM 256K │◄───►│ (CPLD/FPGA) │◄───► VRAM 256K
│ Cache 64K │ │ │◄───► Main RAM
└────────────┘ │ │
│ AY-3-8910 │
│ COVOX/CBL │
│ Accel. │
└──────┬────────┘
┌───┴───┐
│TDA1543│
│ ЦАП │
└───────┘
```
Периферия (FDD, HDD, Kempston, клавиатура AT) подключается через ППЛМ. Вспомогательная ППЛМ (EPM7064 на Sp2000) обеспечивает синхронизацию и начальный запуск. Дешифрация адресов портов выполняется через ППЛМ, что позволяет перепрограммировать адреса портов.
## 1.3 ППЛМ и загрузка конфигураций
### Механизм конфигурирования
При включении или RESET информация в ППЛМ стирается. ППЛМ переходит в режим ожидания загрузки блока данных конфигурации. Процессор отключён от периферии, в его адресное пространство включено ПЗУ и возможно КЭШ-ОЗУ. Любая запись процессора в адресное пространство в этот момент записывает данные в ППЛМ.
Программа загрузчика в ПЗУ:
1. Проверяет флаг в КЭШ-ОЗУ по смещению `#80` (последняя страница КЭШа)
2. Если флаг (строка `ACEX_30K_LOADING`) установлен → загружает конфигурацию из КЭШ-ОЗУ (смещение `#100`)
3. Если флаг сброшен → загружает конфигурацию из ПЗУ
### Смена конфигурации программно
1. Загрузить файл прошивки в последнюю страницу КЭШ-ОЗУ (смещение `#100`)
2. Записать флаг `ACEX_30K_LOADING` по смещению `#80`
3. Выполнить программный сброс записью в страницу RESET_PAGE (`#A0`),
4. После сброса загрузчик находит флаг, загружает прошивку в ППЛМ и стирает флаг
При аппаратном RESET флаг отсутствует — загружается начальная конфигурация из ПЗУ.
### Ограничения
- Внутренний формат данных ППЛМ — закрытая информация Altera
- Программа разводки схем — MAX+Plus II — не работает на ZX-Spectrum/Sprinter (требуется PC)
## 1.4 Конфигурации ППЛМ
### Sprinter-1
Максимально совместима с ZX-Spectrum. Включает:
- Режимы Spectrum-128/Scorpion-256/Pentagon-512
- Расширенная память до 4 МБ
- Расширенный экран: Spectrum, Text-80×32, Graf-320×256×256
- Контроллер дисковода (ВГ93), контроллер IDE
- AT-клавиатура, подключённая как ZX-Keyboard (через порт `#FE`)
- COVOX 8-bit
- AY-3-8910 (доступен)
### Sprinter-2
Требования к совместимости жёстче. Добавляет:
- Акселератор операций с ОЗУ (fill, copy, AND, OR, XOR)
- AT-клавиатура через внутренний последовательный порт Z84C15 (сканкоды, не ZX-матрица)
### ZX-Spectrum+AY
Максимальное приближение к ZX-Spectrum-128/256. AY-3-8910 (3-я версия, в ППЛМ): 3 голоса, шум, амплитуда, огибающая (обнаружена ошибка в формирователе огибающей [IvanMak.txt:224229]).
### Game-1
На базе Sprinter-2. Акселератор без логических функций. COVOX-Blaster (15 кГц).
### DooM
Развитие Game-1. Акселератор с аппаратным растяжением/сжатием вертикальных и горизонтальных линий.
### Video
Похожа на Game-1, добавлена возможность передачи данных с HDD прямо в видео-память. Режим `GR-256-4×4` — 160×128 с аппаратным удвоением пикселя.
### Плата Sp2000
Конфигурации Sprinter-1, Sprinter-2 и ZX+AY объединены в одну прошивку. Переключение — через системный порт. Game-1, DooM, Video также планируется свести в одну.
## 1.5 Система памяти (обзор)
Адресное пространство Z80 (64 КБ) разделено на 4 окна по 16 КБ:
| Окно | Адреса | Название | Назначение (по умолчанию) |
|---|---|---|---|
| W0 | `#0000..#3FFF` | PAGE0 | ПЗУ (системное) |
| W1 | `#4000..#7FFF` | PAGE1 | ОЗУ, страница 5 |
| W2 | `#8000..#BFFF` | PAGE2 | ОЗУ, страница 2 |
| W3 | `#C000..#FFFF` | PAGE3 | ОЗУ, любая страница (0..N) |
Основная память — 4..64 МБ — делится на блоки по 16 КБ. Управление через порты страниц (`#82`, `#A2`, `#C2`, `#E2` для окон 0..3). ПЗУ: `#E0..#EF`. КЭШ-ОЗУ: `#F0..#FF`.
Детально — `04-memory.md`.
## 1.6 Видеосистема (обзор)
Основа — ППЛМ + 256 КБ видео-ОЗУ. Два режима адресации VRAM:
- **Спектрумовский** — экран 32 блока по 8 КБ, адрес через RGADR
- **Графический** — 256 строк × 1024 байта, линейная адресация; страницы `#50..#5F`
Режимы вывода (задаются для каждого квадратика 8×8):
- ZX-40 — текстовый 40×32 (Spectrum-совместимый)
- ZX-80 — текстовый 80×32, до 36 знакогенераторов
- GR-256-8 — графический 320×256×256 цветов
- GR-16-16 — графический 640×256×16 цветов
Палитра: 8 палитр по 256 цветов из 16 млн. Цвет: 3 байта RGB (BGR) на цвет.
четыре из этих восьми палитр используются для графических режимов и оставшиеся четыре для текстовой палитры — 4 текстовые палитры (paper, ink, flash-paper, flash-ink) по адресам `#03F0..#03FE`.
Детально — `05-graphics.md`.
## 1.7 Акселератор (обзор)
Акселератор — быстрое внутреннее ОЗУ в ППЛМ. Присутствует в Sprinter-2 и выше. Управляется через NOP-команды процессора (`LD D,D`, `LD L,L`, `LD C,C` и др.), которые ППЛМ распознаёт как инструкции акселератора.
Операции: fill, copy, AND, OR, XOR.
**время копирования полного экрана.** - «~1.2 инта» (~24 мс при 50 Гц)
**формула скорости.**
«Время работы акселератора = число пересылаемых байт / 7000000 (секунд)»
**акселератор и прерывания.** требуется DI/EI (акселератор сильно меняет систему команд).
Детально — `06-accel.md`.
## 1.8 Быстрое ОЗУ (КЭШ-ОЗУ)
64 КБ SRAM с доступом без wait states на частоте 21 МГц. Физические страницы `#F0..#FF`, реально 4 страницы по 16 КБ.
Подключается через порт `#FB` (стандартный Pentagon-овский), чтение `IN A,(#FB)` — включает, `IN A,(#7B)` — выключает.
Ограничения:
- Несовместимо с акселератором
- Не сохраняется между процессами
- Конфликт с COVOX по порту `#FB`
- На Sp2000 используется для загрузки прошивок ППЛМ и как временное хранилище
Детально — `04-memory.md`.
## 1.9 ISA-слоты
Два 8-битных ISA-слота.
Возможны два способа доступа к ISA — вероятно, разные конфигурации ППЛМ:
- Через страницы памяти `#D0..#DF` [IvanMak.txt:855858]: «Бит 1 номера означает выбор доступа к порту или памяти ISA, а бит 2 определяет к какому из двух слотов осуществляется доступ.»
- Через управляющие порты [Parinov.txt:798857]: (1) запись `#10` в порт `1FFDh`, (2) запись управляющего байта в порт `0E2h` (бит D2=слот, D1=порт/память), (3) использование порта `9FBDh` для старших адресов.
## 1.10 Звук (обзор)
COVOX: ЦАП TDA1543 — 16-битный стерео, COVOX — 8-битный, реально используется 10 бит для одновременного вывода COVOX и AY.
**порт CBL.**
«Порт управления: 004Eh (16-bit port!!!, писать только через OUT (C),reg)» — 16-бит, требуется `OUT (C),A`.
Компоненты звукового тракта:
- **16-битный ЦАП TDA1543** (реально 10 бит) — подключён к ППЛМ
- **AY-3-8910** — эмуляция в ППЛМ (3-я версия: 3 голоса + шум + огибающая)
- **COVOX 8-bit** — порты `#FB` / `#4F`, через TDA1543
- **Бипер** — бит 3 порта `#FE`
- **COVOX-Blaster (CBL)** — COVOX с буферным ОЗУ 256 байт, 15/22 кГц. Управление порт `#4E`
Детально — `08-io.md`.
## 1.11 Клавиатура (обзор)
В Sprinter-1 — ZX-клавиатурная матрица через порт `#FE`. В Sprinter-2 и выше — AT-клавиатура через внутренний SIO Z84C15 (порты `#18`/`#19`). Сканкоды напрямую, FIFO на 3 байта.
Детально — `08-io.md`.
## 1.12 Мышь
Microsoft Mouse (2 кнопки) через последовательный порт Z84C15. Порт команд: `#1B`, порт данных: `#1A`.
Детально — `08-io.md`.
## 1.13 Дисковая подсистема
- **FDD**: КР1818ВГ93 (WD1793). Порт `#1F` перенаправляется на `#0F` в ПЗУ. Поддержка 720 КБ / 1.44 МБ.
- **HDD**: IDE/AT. Порты `#XX50..#XX55`, регистры `#20..#29`.
- **CMOS Dallas DS12887A**: порты `#FFBD` (read), `#BFBD` (write), `#DFBD` (address).
Детально — `08-io.md`.
## 1.14 Система прерываний (обзор)
Поддерживаются IM1 и IM2. Генерация INT — через бит 0 порта `#FE`. CTC Z84C15 — таймер, SIO — клавиатура. ISA-слоты — IRQ через PIO порт B (`#1F`).
Детально — `07-irq.md`.
## 1.15 Сброс и старт машины
Программный сброс (без перезагрузки ППЛМ) [IvanMak.txt:13851394]:
```
DI
LD A, 16
LD BC, 1FFDh
OUT (C), A
LD A, 0A0h
OUT (PAGE3), A ; PAGE3 = #E2
LD (0C000h), A ; в этот момент происходит RESET
DI
HALT
```
Сброс с перезагрузкой ППЛМ — через функции BIOS (`02-bios.md`). Аппаратный RESET — начальная конфигурация из ПЗУ.
## 1.16 Плата Sp2000 — особенности
- Конфигурации объединены в две прошивки ППЛМ (Sprinter-1+Sprinter-2+ZX+AY — одна; Game-1+DooM+Video — другая)
- AY-сопроцессор доступен и в Sprinter-1, и в Sprinter-2
- ОЗУ: 72-pin SIMM, от 4 до 64 МБ
- Внутренние порты Z84C15: `#10..#1F`, `#EE`, `#EF`, `#F0`, `#F1`, `#F4` — их адреса вне ППЛМ
- Обнаружена ошибка в формирователе огибающей AY (3-я версия)
## 1.17 Кросс-ссылки
- BIOS: `02-bios.md`
- DSS/ESTEX: `03-dss.md`
- Память, режимы, банки: `04-memory.md`
- Видео, палитра: `05-graphics.md`
- Акселератор: `06-accel.md`
- Прерывания: `07-irq.md`
- Диски, джойстик, принтер, ISA: `08-io.md`
- Клавиатура, мышь: `09-input.md`
- Звук: `10-sound.md`
- Карта портов: `11-ports.md`
- Баги: `12-bugs.md`
+1234
View File
File diff suppressed because it is too large Load Diff
+1082
View File
File diff suppressed because it is too large Load Diff
+387
View File
@@ -0,0 +1,387 @@
# 4. Управление памятью Sprinter Sp2000
## 4.1 Аппаратная модель памяти
Z80 видит 64 КБ, разбитые на **четыре окна (window) по 16 КБ**. Каждое окно независимо маппится на физическую страницу (page) ОЗУ или ПЗУ через порт-регистр страницы:
| Окно | Адреса | Порт страницы | Назначение |
|------|--------|---------------|------------|
| W0 | `#0000..#3FFF` | `#82` (PAGE0, ROM.SLOT0) | RST-обработчики, BIOS/DSS ядро |
| W1 | `#4000..#7FFF` | `#A2` (SLOT1, PAGE1) | Приложение |
| W2 | `#8000..#BFFF` | `#C2` (SLOT2, PAGE2) | **Стек — обязательно здесь** |
| W3 | `#C000..#FFFF` | `#E2` (SLOT3, PAGE3) | Разделяемые страницы DSS, графика, резидентный код |
- Запись в порт `#82`/`#A2`/`#C2`/`#E2` меняет физическую страницу окна; чтение возвращает текущую.
- Для совместимости со старыми моделями (ZX-Spectrum 128, Scorpion, Pentagon) работают также порты `#7FFD`, `#1FFD`, `#DFFD`, `#EFF7`:
| Порт | Описание |
|------|----------|
| `#7FFD` | Биты 0-2: страница W3; бит 3: выбор ПЗУ (0=DOS, 1=Basic/48) |
| `#1FFD` | Биты 0-2: страница W0; бит 3: дополнительная память; бит 4: турбо |
| `#DFFD` | Страница W1 (Pentagon, когда бит 5 порта `#7FFD`=0) |
| `#EFF7` | Страница W2 (Pentagon) |
> **Страница `#FF`:** если окно не выделено программе (образ меньше 16/32 КБ), DSS маппит его на специальную страницу `#FF`. Чтение даёт `#FF`, запись игнорируется. Это ключевая причина «молчаливой» порчи данных — см. §4.9.
> **Физические страницы:** порты `#82`/`#A2`/`#C2`/`#E2` адресуют физические 16-КБ страницы в адресном пространстве Sprinter. Диапазон страниц зависит от установленной памяти (обычно 0..127 для 2 МБ, 0..255 для 4 МБ). Старшие страницы заняты видео-ОЗУ и ПЗУ.
---
## 4.2 Окно W0 (#0000..#3FFF) — системное
W0 — критическое окно: в нём живут обработчики `RST 08h` (BIOS), `RST 10h` (DSS/ESTEX) и `RST 18h` (BIOS-EXP). Пока в W0 стоит системная страница, вызовы доступны.
**ROM/RAM switching:**
| Действие | Код |
|----------|-----|
| Включить ПЗУ в W0 | `OUT (#7C),A` (SYS_PORT.ROM) |
| Выключить ПЗУ, вернуть ОЗУ | `OUT (#3C),A` (SYS_PORT.RAM) |
При включённом ПЗУ в W0 отображается системная страница BIOS. Для вызова RST-функций W0 должен быть в ПЗУ — BIOS сам переключает его при входе через `RST 08h`.
**Требования к прерываниям:**
Sprinter работает в режиме **IM1** — вектор прерывания фиксирован на `#0038` (всегда в ПЗУ/ОЗУ W0). Обработчик EXP.asm по адресу `#0038`:
1. Переключает W3 на SYS_PAGE.
2. Проверяет флаг `INT_ID` = `#AA`.
3. Если есть пользовательский обработчик — вызывает его (адрес из SYS_PAGE).
4. Восстанавливает W3, `EI`, `RETI`.
Регистр `I` инициализирован в `#3F` (наследие ZX-Spectrum), но при IM1 не используется для диспетчеризации. Если программа переключается в **IM2**`I` и расположение таблицы векторов определяются программой произвольно, стандартного расположения нет.
**DSS и W0:** при вызове `RST 10h` DSS переключает W0 на свою рабочую страницу (COREPAGE = 4), выполняет функцию и восстанавливает W0. Если в W0 до вызова была ОЗУ, DSS восстановит её; если ПЗУ — вернёт ПЗУ.
**Практические рекомендации:**
- Для вызова системных функций держите W0 в ПЗУ (или не заботьтесь — RST 08h и RST 10h его переключат сами).
- При IM1 (режим по умолчанию) прерывание идёт на `#0038` — это ПЗУ, переключение W0 не требуется.
- При IM2 программа сама управляет таблицей векторов — не забывайте про `DI`/`EI` при переключении W0.
**Размещение своей RAM-страницы в W0:**
Если программе нужно дополнительное окно (например, для атласов спрайтов или кода,
не требующего системных вызовов), можно временно маппить свою страницу в W0. Для
безопасной работы страница должна содержать корректную таблицу RST-векторов в
первые `#40` байт:
| Адрес | Инструкция | Назначение |
|-------|-----------|------------|
| `#0000` | `JP boot` или `RST 00h` (обычно не используется) | |
| `#0008` | `JP rst08_stub` | RST 08h — BIOS |
| `#0010` | `JP rst10_stub` | RST 10h — ESTEX/DSS |
| `#0018` | `JP rst18_stub` | RST 18h — BIOS-EXP |
| `#0020..#0030` | `JP _w0_unused_stub` | RST 20h-30h — не используются |
| `#0038` | `JP isr_stub` | IM1 (RST 38h) |
| `#0066` | `RETN` или `JP nmi_stub` | NMI |
Каждый стаб (в этой же странице, выше `#40`) выполняет одну задачу: сохранить
текущий номер страницы W0, переключить W0 обратно на ПЗУ (`OUT (#7C),A`
SYS_PORT.ROM), выполнить настоящий системный вызов, после чего восстановить
страницу программы и вернуться к исходному caller'у. Типовой паттерн для ESTEX
(`RST 10h`):
```asm
rst10_stub:
IN A, (#82) ; сохранить свою страницу W0
PUSH AF
OUT (#7C), A ; включить ПЗУ в W0 (SYS_PORT.ROM)
; теперь в W0 — системная страница, RST 10h будет обработан корректно
RST #10 ; вызвать настоящий ESTEX (DSS сам переключит W0
; на COREPAGE и восстановит ПЗУ на выходе)
POP BC
LD A, B
OUT (#82), A ; вернуть свою страницу в W0
RET ; возврат к исходному caller'у
```
Такой же паттерн для RST 08h и RST 18h. Для IM1 (`RST 38h`) — аналогично, но
прерывание может прийти в любой момент, поэтому критические секции (своя
страница в W0) обязаны быть обёрнуты в `DI`/`EI` (или проверять вложенность
через счётчик), иначе повторное прерывание при уже замапленной странице
попадёт в стаб, а не в EXP.asm.
**Важно:** пока в W0 стоит ваша страница, системные вызовы (`RST 08h`/`10h`/`18h`)
проходят через стабы и работают корректно, но с накладными расходами
(~10+ тактов на каждый вызов). Код на странице не должен вызывать DSS/BIOS
напрямую — только через RST. При этом сам стаб не должен использовать
RST-инструкции, так как они адресуют W0, который в момент вызова стаба
всё ещё содержит вашу страницу, а не ПЗУ — сначала переключите ПЗУ через
`OUT (#7C),A`.
Перед первым маппингом своей страницы в W0 сохраните текущее значение порта
`#82` (`IN A,(#82)` — оно даёт номер системной/ПЗУ-страницы). Эта страница
понадобится стабам для восстановления после вызова во время прерываний,
когда ПЗУ уже может быть в W0, а стаб не успел его переключить.
Подтверждённая реализация: `tests/w0page` (см. `sprite-api-design.md §9в`).
---
## 4.3 Окно W1 (#4000..#7FFF) — приложение
W1 — основное окно для кода и данных приложения. По умолчанию содержит страницу 5 (RAM, инициализируется BIOS).
**Использование BIOS/DSS:**
BIOS и DSS могут **временно** переключать W1 на свою рабочую страницу. Это происходит:
- При файловых операциях DSS: чтении FAT, загрузке секторов — DSS маппит одну из страниц разделяемого пула в W1 (DIRPAGE, FATPAGE, TXTPAGE, DRVPAGE).
- При графических операциях BIOS: `PIC_FN2`/`PIC_FN3` (блоковые копии) могут переключать W1 на страницу видео-ОЗУ.
- **Важно:** перед возвратом из вызова BIOS/DSS **восстанавливает** предыдущую страницу W1. Типовой паттерн в исходниках DSS:
```asm
IN A,(SLOT1) ; сохранить текущую страницу W1
PUSH AF
... работа с разделяемым буфером ...
POP BC
LD C,SLOT1
OUT (C),B ; восстановить W1
```
Для вызывающей программы переключение W1 полностью прозрачно — после возврата из любой функции DSS/BIOS содержимое W1 идентично тому, что было до вызова.
**Практические рекомендации:**
- Размещайте код и данные в W1, рассчитывая, что он остаётся стабильным между вызовами.
- При длительных файловых операциях (последовательный `READ` больших объёмов) W1 может быть затронут только в моменты внутреннего обращения DSS к FAT/буферам, но не во время собственно чтения данных в буфер программы.
- Если нужно гарантированно сохранить данные через вызов DSS — используйте W2, который BIOS/DSS **никогда не трогают**.
---
## 4.4 Окно W2 (#8000..#BFFF) — стек (критично)
W2 — **единственное окно, которое BIOS и DSS гарантированно не трогают**. Поэтому стек ОБЯЗАН находиться здесь:
- **SP ≤ #BFFF** при вызовах DSS (`RST 10h`).
- **SP ≥ #8000** при вызовах BIOS (`RST 08h`).
- Пересечение → стек в `#8000..#BFFF`.
- По умолчанию SP инициализируется в `#BFFE` (значение из EXE-заголовка, §4.7).
**Почему W2 — единственное стабильное окно:**
| Окно | Может быть переключено BIOS/DSS | Почему |
|------|--------------------------------|--------|
| W0 | Да | DSS переключает на COREPAGE при `RST 10h`; BIOS переключает на ПЗУ |
| W1 | Да, временно | DSS маппит разделяемые буферы для FAT/директорий; BIOS при графических операциях — и **восстанавливает** перед возвратом |
| W2 | **Нет** | **Никогда. Стек должен быть доступен всегда.** |
| W3 | Да, временно | DSS маппит разделяемые буферы; BIOS при графике переключает на видео-ОЗУ; оба **восстанавливают** исходную страницу перед возвратом |
**EXEC и W2:** при загрузке новой программы (`EXEC`, функция 40h) DSS сохраняет страницу W2 в EXSTACK (вместе с W1 и W3). После завершения программы (`EXIT`, функция 41h) W2 восстанавливается.
**Практические рекомендации:**
- Размещайте стек строго в W2. Стандартное значение `SP = #BFFE` — начало стека с запасом ~14 КБ до `#8000`. Можно уменьшить, если программа неглубокая.
- W1 и W3 при вызовах DSS и BIOS **сохраняются и восстанавливаются** (см. §4.3, §4.5), но W2 — единственное окно, которое **никогда не трогается** ни DSS, ни BIOS.
- Если программе нужно больше памяти, чем даёт W2 (например, для хранения больших массивов), выделяйте блоки через DSS `GETMEM` (функция 3Dh) и мапьте их в W1 или W3.
---
## 4.5 Окно W3 (#C000..#FFFF) — разделяемые страницы
W3 — окно, в которое DSS временно маппит страницы своего разделяемого пула для дисковых буферов и служебных данных (адрес `#C000`):
| Страница | Назначение | Адрес в W3 |
|----------|------------|-------------|
| DIRPAGE (0) | Буфер директории | `#C000` |
| FATPAGE (1) | Кеш FAT | `#C000` |
| TXTPAGE / ENVPAGE (2) | Буфер строки/окружения | `#C000..` (PATH_PNT_ARRAY `#FC80`, ENVTEMP `#FE00`) |
| DRVPAGE (3) | Страница драйвера | `#C000` |
| COREPAGE (4) | Ядро DSS (маппится в W0 при `RST 10h`) | — |
**DSS СОХРАНЯЕТ и ВОССТАНАВЛИВАЕТ W3** после каждой операции. Типовой паттерн в исходниках:
```asm
IN A,(SLOT3) ; сохранить текущую страницу W3
PUSH AF
... работа с разделяемым буфером ...
POP BC
LD C,SLOT3
OUT (C),B ; восстановить W3
```
Это означает, что для вызывающей программы переключение W3 полностью прозрачно — после возврата из любой функции DSS содержимое W3 идентично тому, что было до вызова.
**Какие функции трогают W3:**
Функции, обращающиеся к файловой системе, временно маппят разделяемые страницы в W3: поиск файла (`F_FIRST`/`F_NEXT`), чтение FAT (`OPEN`, `READ`, `WRITE`), работа с каталогами (`CHDIR`, `MKDIR`), буферы драйвера диска. Функции без дисковой активности (`VERSION`, `CURDISK`, `WAITKEY`, `LOCATE`, `SYSTIME`, `ENVIRON` и т.п.) W3 не трогают вообще.
BIOS при графических операциях также временно переключает W3 на страницы видео-ОЗУ (например, `PIC_SET_PAL`, `PIC_FN2`) — и тоже восстанавливает.
**Практические рекомендации:**
- W3 можно использовать для данных программы — после возврата из любой функции DSS содержимое W3 не меняется.
- Единственное исключение — `EXEC` (функция 40h): она загружает новую программу, и W3 получает страницы загруженного образа. Это ожидаемое поведение.
- Если программа не вызывает дисковых и графических функций — W3 полностью стабилен.
- **Стек нельзя размещать в W3** — не потому что W3 «теряется», а потому что переключение W3 происходит ВО ВРЕМЯ вызова. Если `SP` указывает на W3, то в момент, когда DSS временно маппит свой буфер, все push/pop внутри DSS будут обращаться к буферной странице, а не к данным программы. Кроме того, при прерывании IM1 обработчик EXP.asm сам переключает W3 на SYS_PAGE — что также сломает стек, если он в W3.
---
## 4.6 Физическая память и страницы
Физическая память Sprinter — не сплошной массив RAM. Разные области адресного
пространства зарезервированы под видео-ОЗУ, ПЗУ и кеш. Номер страницы — это
значение, которое записывается в порт окна (`#82`/`#A2`/`#C2`/`#E2`);
8-битный порт даёт **256 значений** (`#00..#FF`).
**Фиксированная карта страниц:**
| Диапазон | Страниц | Назначение |
|----------|---------|------------|
| `#00..#4F` (0..79) | 80 (1,25 МБ) | RAM общего назначения |
| `#50..#5F` (80..95) | **16 (256 КБ)** | **Видео-ОЗУ (VRAM) — фиксировано в железе** |
| `#60..#DF` (96..223) | 128 (2 МБ) | RAM общего назначения (верхний диапазон) |
| `#E0..#EF` (224..239) | **16 (256 КБ)** | **ПЗУ: BIOS + EXP + ZX ROMs + bitstream — фиксировано** |
| `#F0..#FF` (240..255) | 16 (256 КБ) | **Fast RAM (кеш) / системные страницы** |
**Выделенные страницы:**
| Страница | Назначение |
|----------|------------|
| `4` | **COREPAGE** — ядро DSS (маппится в W0 при `RST 10h`) |
| `5` | Стандартная страница приложения W1 (по умолчанию) |
| `#41` (65) | **Spec_Page** — сохранение состояния при soft-reset [EXP.asm:859,1019] |
| `#FE` (254) | **SYS_PAGE** — системные данные BIOS (INT_ID, INT_ADRESS, буферы) [MAIN.asm:58] |
| `#FF` (255) | **Dummy-страница**: чтение → `#FF`, запись игнорируется |
**Ключевые моменты:**
- **VRAM (`#50..#5F`) фиксирована аппаратно**, независимо от объёма RAM. Эти
16 страниц не являются частью RAM SIMM — это отдельная микросхема 256 КБ.
Биты 2-3 номера страницы кодируют режим записи: `#50` normal, `#54` без
ОЗУ-тени, `#58` прозрачный (байт `#FF` не пишется), `#5C` оба режима.
- **ПЗУ (`#E0..#EF`)** — 256 КБ флеш-памяти с BIOS, EXP, ZX Spectrum 48/128 ROM,
TR-DOS, логотипом и битстримом для CPLD.
- **Fast RAM (`#F0..#FF`)** — до 512 КБ быстрого SRAM (0 wait-states),
доступна через порт `#FB`. `#FE` (SYS_PAGE) и `#FF` (dummy) — часть этого
диапазона. При включённом кеше порт `#FB` конфликтует с CBL-звуком.
- Для 2 МБ RAM: `#60..` заполнены до `#7F` (32 стр. = 512 КБ); остаток
`#80..#DF` — неиспользуемые страницы (отображаются как `#FF`).
- Для 4 МБ RAM: `#60..#DF` целиком заполнены RAM (128 стр. = 2 МБ).
> **Нумерация:** порты `#82`/`#A2`/`#C2`/`#E2` дают прямой доступ по
> физическому номеру (#00..#FF). Порты `#7FFD`/`#1FFD` (совместимость с
> ZX-Spectrum 128) используют сквозную нумерацию: номер в `#7FFD` (0..7)
> маппится на физические страницы видеоОЗУ `#50..#5F` младшими 3 битами;
> для работы с произвольными страницами используйте порты `#82`/`#A2`/`#C2`/`#E2`.
---
## 4.7 EXE-файл: формат и загрузка
Загрузка исполняемых файлов выполняется функцией DSS `EXEC` (40h). Формат EXE-файла:
**Заголовок (512 байт):**
| Смещение | Размер | Поле | Описание |
|----------|--------|------|----------|
| +0 | 3 | `EXE_EXT` | Сигнатура `"EXE"` |
| +3 | 1 | `VERSION` | Минимальная версия DSS (1 = v1.xx, 0 = без пути/аргументов) |
| +4 | 2 | `OFFCOD1` | Младшее слово смещения образа в файле |
| +6 | 2 | `OFFCOD2` | Старшее слово смещения (OFFCOD2 << 16 + OFFCOD1 = offset) |
| +8 | 2 | `LOADER` | Размер первичного загрузчика (0 = весь образ сразу) |
| +10 | 6 | `RESERVED` | Зарезервировано |
| +16 | 2 | `LD_ADDR` | Адрес загрузки (`#4100..#FFFF`, старший байт маскирован `#3F`) |
| +18 | 2 | `PC_REG` | Точка входа (entry point) |
| +20 | 2 | `SP_REG` | Начальный SP (по умолчанию `#BFFE`) |
| +22 | 1 | `UnUsedPoint` | Не используется |
| +23 | 489 | `RESERVED2` | Зарезервировано (обнуляется; используется как временный стек EXEC) |
**Процесс загрузки (EXEC, функция 40h):**
1. Открыть файл на чтение.
2. Считать 512-байтный заголовок в буфер ядра.
3. Проверить сигнатуру `"EXE"` и версию (≥ минимальной 1).
4. Если `LOADER=0`: seek на смещение `OFFCOD2:OFFCOD1`, считать весь образ по адресу `LD_ADDR`.
5. Если `LOADER>0`: считать только первичный загрузчик по адресу `LD_ADDR` (он дочитает остальные сегменты).
6. Выделить блок памяти через `GETMEM` (функция 3Dh), зарегистрировать в таблице RAM.
7. Сохранить текущие страницы окон (SLOT1-3) в EXSTACK.
8. Определить, сколько страниц нужно, и замаппить их через `SETWIN1`/`SETWIN2`/`SETWIN3`:
- Если `LD_ADDR ≥ #C000`: маппится только W3.
- Если `LD_ADDR ≥ #8000`: маппятся W2 и W3.
- Иначе: маппятся W1, W2 и W3.
9. Построить **PSP** (Program Segment Prefix) — блок данных сразу ниже `LD_ADDR`:
- `LD_ADDR-3`: файловый манипулятор (file handle).
- `LD_ADDR-2`: идентификатор блока памяти.
- `LD_ADDR-1`: номер задачи.
- `LD_ADDR+0`: размер CLP (командной строки).
- `LD_ADDR+1..+128`: CLP-буфер.
- После CLP: строка пути `"A:\DIR\FILE.EXE",0`.
10. Установить SP из заголовка (`SP_REG`), сохранить IX → адрес PSP.
11. Если `VERSION=0` — установить текущий каталог из пути PSP.
12. Затолкать в стек адрес возврата (RETFAR к DSS), **EI**, JP на точку входа.
**Multi-bank EXE:**
При наличии нескольких банков (`LOADER>0`) файл устроен так:
```
[512-байт заголовок] [HOME-сегмент] [Банк 1 (16 КБ)] [Банк 2 (16 КБ)] ...
```
- HOME-сегмент: образ, загружаемый DSS по `LD_ADDR`.
- Банки: 16-КБ блоки, каждый на своей физической странице.
- `LOADER` = размер HOME-сегмента (DSS загружает только его; первичный загрузчик сам дочитывает банки через `READ` из оставшегося открытым файла).
---
## 4.8 Прерывания и память
**Обработчик IM1 (`RST 38h`):**
Вектор фиксирован на `#0038` (W0). Реализация в EXP.asm:
1. Переключает W3 на SYS_PAGE (BIOS).
2. Проверяет флаг `INT_ID` = `#AA` (установлен при инициализации BIOS).
3. Если флаг совпадает — вызывает пользовательский обработчик, адрес которого хранится в SYS_PAGE (`INT_ADDRESS`, `INT_PAGE`).
4. После возврата восстанавливает W3 и выполняет `EI; RETI`.
Это позволяет пользовательским программам устанавливать свои обработчики INT без полного перехвата вектора.
**Обработчик IM1 (системный):**
При возникновении прерывания Z80 исполняет `RST 38h` → вызов по адресу `#0038`. Реализация в EXP.asm (всегда доступна, т.к. `#0038` в W0):
1. Переключает W3 на SYS_PAGE (BIOS).
2. Проверяет флаг `INT_ID` = `#AA` (установлен при инициализации BIOS).
3. Если флаг совпадает — вызывает пользовательский обработчик, адрес и страница которого хранятся в SYS_PAGE (`INT_ADDRESS`, `INT_PAGE`). Это позволяет программам устанавливать свои ISR без полного перехвата вектора.
4. После возврата восстанавливает W3 и выполняет `EI; RETI`.
**Обработчик IM2 (опционально, для продвинутых программ):**
Sprinter по умолчанию не использует IM2. Исходники содержат шаблон `IM2_INT.asm` для программ, желающих переключиться на IM2:
1. Сохраняет AF, BC, DE, HL, IX, IY и теневые регистры.
2. Включает ПЗУ (`OUT (#7C),A`) — KEYSCAN требует ПЗУ в W0.
3. Вызывает KEYSCAN (опрос AT-клавиатуры).
4. Восстанавливает все регистры, `EI`, `RETI`.
При переходе на IM2 программа сама выбирает значение `I` и размещает таблицу векторов в соответствующем диапазоне памяти.
**Рекомендации:**
- Если программа не использует прерывания — держите W0 в ПЗУ.
- Если программа использует IM1 — можно переопределить обработчик через структуру в SYS_PAGE (флаг `INT_ID`, поля `INT_ADDRESS`/`INT_PAGE`).
- Если программа использует IM2 — переключение полностью на ответственности программы; ядро Sprinter не предоставляет стандартного расположения таблицы векторов.
---
## 4.9 Типовые грабли
- **Данные читаются как `#FF` / не сохраняются** — код или данные попали в незамапленное окно (страница `#FF`). Причина: образ программы меньше 16 КБ, DSS выделил только одну страницу, а код/данные распределены линкером в незамапленные окна. Лечение: убедитесь, что код и данные укладываются в одно окно, или явно выделяйте и мапьте остальные окна через `GETMEM`/`SETWIN1`-`SETWIN3`.
- **Крэш при вызове RST при нестандартном W0** — если перед вызовом W0 содержал произвольную страницу ОЗУ, DSS при `RST 10h` переключит его, но может не восстановить корректно. Решение: перед вызовом RST включите ПЗУ (`OUT (#7C),A`), если не уверены в состоянии W0.
- **Стек в W3 (не-рабочий вариант)** — если стек размещён в W3, при любом дисковом вызове W3 будет переключён на разделяемый буфер DSS, и стековые данные будут забиты. Результат: мгновенное зависание при возврате из функции. Единственное рабочее место для стека — W2.
- **CBL не работает при включённом кеше** — порт `#FB` используется как кеш-память (Fast RAM) и как порт CBL-звука. Если кеш включён, запись в `#FB` уходит в кеш, а не в CBL. Детали: `11-ports.md`, `12-bugs.md`.
- **Прерывание уходит не туда при IM2** — если программа переключилась в IM2 с неинициализированной таблицей векторов, любое прерывание приведёт к исполнению мусора. Решение: используйте IM1 (режим по умолчанию) или инициализируйте таблицу перед переключением.
- **Не путать W3 с «теряется после вызова»** — многие источники утверждают, что DSS сбрасывает W3. На самом деле DSS **сохраняет и восстанавливает** W3 после каждой операции. Стек всё равно нельзя размещать в W3 (см. §4.5), но для данных W3 полностью стабилен между вызовами. Если ваша программа полагается на старый миф — проверьте код.
---
## 4.10 Кросс-ссылки
- Порты страниц и детали регистров: `11-ports.md`
- BIOS (графика, окна): `02-bios.md`
- DSS/ESTEX (EXEC, GETMEM, SETWIN): `03-dss.md`
- Прерывания: `07-irq.md`
- Баги (CBL vs кеш, порт #FB): `12-bugs.md`
- EXE-формат и PSР: `memory/exe-format.md`
+279
View File
@@ -0,0 +1,279 @@
# 5. Графика и видеосистема
## 5.1 Общие сведения
Видеосистема Sprinter Sp2000 реализована в ППЛМ. Видео-ОЗУ — 256 КБ
(512 КБ на некоторых платах [Architecture.txt:17]).
| Параметр | Значение |
|---|---|
| VRAM | 256 КБ, независимая микросхема (не часть RAM SIMM) |
| Физические страницы | `#50..#5F` (16 страниц × 16 КБ), фиксировано в железе |
| Видеорежимы | ZX-40, ZX-80, GR-256-8, GR-16-16 |
| Палитра | 8 палитр × 256 цветов из 16 млн (RGB, BGR) |
| Видеовыход | CGA-монитор, RGB, TV (SCART) |
**Теневая память (Shadow RAM):** Видео-ОЗУ Спринтера является теневой памятью
(§5.4). Программа управляет режимом записи через номер подключаемой страницы
(§5.3): банк `0x50` пишет одновременно в VRAM и в основное ОЗУ; банк `0x54`
пишет только в VRAM, не трогая ОЗУ. На экране **всегда** отображается
содержимое VRAM, независимо от режима записи [IvanMak.txt:317322].
---
## 5.2 Режимы адресации видео-ОЗУ
Видео-ОЗУ может адресоваться двумя способами — **спектрумовским** и
**графическим** [IvanMak.txt:296300]. Спектрумовский режим используется для
Spectrum-совместимого вывода и загрузки знакогенераторов; графический — для
всех остальных видеорежимов (320×256×256, 640×256×16, текст 80×32).
### 5.2.1 Спектрумовский режим адресации
В этом режиме VRAM разбивается на **32 блока по 8 КБ**. Адрес блока задаётся
через порт `RGADR` (`PORT_Y`, `#89`):
| Бит | Назначение |
|-----|-----------|
| 4..0 | Номер блока (0..31) |
| 5 | Не используется |
| 6 | Запрет вывода (1 = отключить спектрумовский вывод) |
| 7 | Разрешение 16-КБ страницы (1 = два блока в `#4000..#7FFF`) |
Бит 0 RGADR вместе с битом 1 порта `#7FFD` определяет чётность подключаемого
блока VRAM: чётный RGADR → блок N в `#4000..#5FFF`, блок N+1 в `#C000..#DFFF`;
нечётный → наоборот [IvanMak.txt:333339].
Для записи в определённую пару спектрумовских блоков:
1. Записать номер блока в `RGADR` (`OUT (#89),A`).
2. Убедиться, что в окне (`#4000` или `#C000`) стоит подходящая страница
основного ОЗУ (любая, кроме `#50..#5F`).
3. Чтение/запись по спектрумовским адресам (`#4000..#5FFF`,
`#C000..#DFFF`) попадает в VRAM через текущий блок.
**Выключение спектрумовского вывода:** Если программа не использует
Spectrum-совместимую графику, `RGADR` рекомендуется установить в `#C0..#FF`
(бит 6 = 1). В этом случае вывод в VRAM через спектрумовский режим не
производится [IvanMak.txt:346348].
### 5.2.2 Графический режим адресации
В графическом режиме видео-ОЗУ организовано как матрица **256 строк
(rows) × 1024 байта** [IvanMak.txt:357358]. Адресация:
```
VRAM_адрес = (RGADR << 10) | (Z80_A[9:0])
где RGADR[7:0] = Y (номер строки, 0..255)
Z80_A[9:0] = X (смещение в строке, 0..1023)
```
Страницы `#50..#5F` при маппинге в любое окно Z80 включают графическую
адресацию. При этом младшие 4 бита номера страницы не влияют на адрес
памяти, а задают подрежим вывода (§5.3).
**Важная особенность:** Z80-адрес внутри окна (биты A[13:10] для окна W3)
**игнорируется** — весь 16-КБ диапазон окна отображает **одну и ту же
строку**, выбранную `RGADR`. Доступ к другим строкам — только через смену
`RGADR`. Это означает, что утверждение из SprinterGraphics programming.txt
о доступе к строкам 18..31 через адреса `#C400..#FC00` **неверно**.
**Структура 1-КБ строки (1024 байта):**
| Смещение в строке | Назначение |
|-------------------|-----------|
| `#000..#13F` (0..319) | Экранная страница 0 (первые 320 байт) |
| `#140..#27F` (320..639) | Экранная страница 1 (следующие 320 байт) |
| `#280..#3FF` (640..1023) | Не используется / данные палитры |
Две экранные страницы (0 и 1) переключаются битом 0 порта `RGMOD` [IvanMak.txt:409].
**Работа с адресацией из программы:**
```asm
; Установить страницу VRAM (0x50) в W3
IN A, (#E2) ; сохранить текущую W3
LD (old_page), A
LD A, #50
OUT (#E2), A ; W3 = VRAM страница 0x50
; Выбрать строку Y
LD A, Y ; Y = 0..255
OUT (#89), A ; RGADR = Y
; Чтение/запись пикселя (X,Y) для экранной страницы 0
LD HL, #C000 + X ; X = 0..319
LD (HL), colour ; запись байта пикселя
; Восстановить страницу
LD A, (old_page)
OUT (#E2), A
```
---
## 5.3 Подрежимы вывода (страницы `#50..#5F`)
Биты 2 и 3 номера страницы (из диапазона `#50..#5F`) задают подрежимы вывода
[IvanMak.txt:364386]:
| Бит | Страницы | Эффект |
|-----|----------|--------|
| 3 | `#58..#5F` | **Прозрачный цвет** — запись байта `#FF` игнорируется (для спрайтов) |
| 2 | `#54..#57`, `#5C..#5F` | **Без тени** — запись только в VRAM, не в основное ОЗУ (для курсора мыши) |
Биты 0 и 1 должны быть 0 для совместимости с будущими прошивками
[IvanMak.txt:384386].
---
## 5.4 Теневая память (Shadow RAM) и двойная запись
Видео-ОЗУ Спринтера является теневой памятью по отношению к основному ОЗУ
[IvanMak.txt:317322]. Видеоконтроллер **всегда** читает изображение из VRAM
для вывода на экран; основное ОЗУ в формировании изображения не участвует.
Однако при записи через графические банки `#50..#5F` поведение зависит от
выбранного подрежима:
- **Банк `0x50` (normal):** запись идёт **одновременно** в VRAM и в
соответствующую область основного ОЗУ. Чтение из того же Z80-адреса
возвращает данные из основного ОЗУ, а не из VRAM — VRAM для процессора
на чтение не видна.
- **Банк `0x54` (noshadow):** запись — только в VRAM, основное ОЗУ не
изменяется. Чтение — из основного ОЗУ (там хранится «фон»).
- **Банк `0x58` (transparent):** как normal, но байт `#FF` не пишется.
- **Банк `0x5C` (sprite):** transparent + noshadow.
- **Обычные банки (не `#50..#5F`):** никакого доступа к VRAM нет,
чтение/запись идут напрямую в основное ОЗУ.
**Зачем это нужно:**
1. **Восстановление после переключения видеорежима:** данные в основном ОЗУ
остаются нетронутыми, так что при возврате в графический режим экран можно
восстановить без перерисовки [IvanMak.txt:325].
2. **Heal спрайтов** (libbgi): фон, на который был выведен спрайт в банке
`GFX_BANK_SPRITE` (`0x5C`, без тени), остался в основном ОЗУ. После
перемещения спрайта фон копируется из основного ОЗУ обратно в VRAM
(операция heal), стирая спрайт.
3. **Курсор мыши** без сохранения/восстановления: временный вывод через
`GFX_BANK_NOSHADOW` (`0x5C`) — в основном ОЗУ данные под курсором не
портятся, достаточно при следующем обновлении просто перерисовать фон.
**Режимы записи (см. §5.3):**
| Режим | Пишет в VRAM | Пишет в осн. ОЗУ | Применение |
|-------|:---:|:---:|-----------|
| `0x50` (normal) | Да | Да | Обычный вывод |
| `0x54` (noshadow) | Да | **Нет** | временные эффекты |
| `0x58` (transparent) | Да (кроме `#FF`) | Да | Спрайты с прозрачностью без heal |
| `0x5C` (sprite) | Да (кроме `#FF`) | **Нет** | Курсор, спрайты (прозрачность + heal) |
---
## 5.5 Видеорежимы
Система поддерживает независимую установку режима для каждого квадратика
8×8 (или 16×8 для 640-режимов) на экране [IvanMak.txt:405469].
### Режимы вывода
| Режим | Разрешение | Цветов | Описание |
|-------|-----------|--------|----------|
| ZX-40 | 320×256 | 16 | Текстовый 40×32, Spectrum-совместимый |
| ZX-80 | 640×256 | 16 | Текстовый 80×32, до 36 знакогенераторов |
| GR-256-8 | 320×256 | 256 | Графический, 1 байт/пиксель |
| GR-16-16 | 640×256 | 16 | Графический, 4 бита/пиксель |
### Формат пикселей
**GR-256-8 (320×256×256):** один байт = один пиксель. Строка содержит
320 байт для экранной страницы 0 (смещения `#000..#13F`) и 320 байт для
страницы 1 (`#140..#27F`). Полный экран: 320 × 256 = 81 920 байт на страницу.
**GR-16-16 (640×256×16):** один байт = два пикселя: младший полубайт —
левый/первый пиксель, старший — правый/второй. Строка содержит 320 байт на
экранную страницу, что даёт 640 пикселей (320 × 2). Структура строки та же:
320 байт на страницу 0, 320 на страницу 1.
### Установка режима
Режим задаётся 4 байтами `Mode0..Mode3` в области режимов VRAM
(`#0300..#039F`). Полное описание формата Modei — [IvanMak.txt:448469].
Для переключения видеорежима из программ используется функция DSS `SETVMOD`
(50h) [DiskSyscalls.txt:345349]:
| A (режим) | Описание |
|-----------|----------|
| 02h | Текстовый 40×32×16 |
| 03h | Текстовый 80×32×16 |
| 81h | Графический 320×256×256 |
| 82h | Графический 640×256×16 |
B — страница экрана (0/1). Вызов: `RST 10h` с C=50h. Флаг C = ошибка
(например, режим не поддерживается данным монитором).
---
## 5.6 Палитра
8 палитр по 256 цветов, каждая занимает 1 КБ в VRAM по адресам
`#03E0..#03FE` [IvanMak.txt:540568].
| Адреса | Палитра | Назначение |
|--------|---------|-----------|
| `#03E0..#03E2` | Граф. 0 | Графические режимы |
| `#03E4..#03E6` | Граф. 1 | —//— |
| `#03E8..#03EA` | Граф. 2 | —//— |
| `#03EC..#03EE` | Граф. 3 | —//— |
| `#03F0..#03F2` | Текст. 4 | Цвет бумаги |
| `#03F4..#03F6` | Текст. 5 | Цвет символа |
| `#03F8..#03FA` | Текст. 6 | Цвет мерцания бумаги |
| `#03FC..#03FE` | Текст. 7 | Цвет мерцания символа |
Каждый четвёртый байт в каждой палитре не используется — не может попасть
на ЦАП [IvanMak.txt:545547]. Выбор палитры для каждого квадратика — через
биты 7..6 байта Mode1 [BIOS_v3.txt:348].
> **Примечание:** Architecture.txt упоминает всего 5 палитр (4 графические +
> 1 текстовая), но IvanMak описывает все 8: 4 графические (0–3) и 4 текстовые
> (4–7: бумага, символ, мерцание бумаги, мерцание символа)
> [IvanMak.txt:547548, 561568].
---
## 5.7 Структура VRAM в терминах BIOS
При использовании BIOS распределение VRAM [IvanMak.txt:387404]:
| Адреса (линии) | Назначение |
|----------------|-----------|
| `#0000..#003F` | Спектрумовский экран (блоки 0..1) |
| `#0040..#017F` | Первый графический экран (блоки 2..11) |
| `#0180..#02BF` | Второй графический экран (блоки 12..21) |
| `#02C0..#02FF` | Знакогенераторы текстового режима |
| `#0300..#039F` | Область описания режимов экрана |
| `#03A0..#03DF` | Зарезервировано |
| `#03E0..#03FF` | Палитра |
---
## 5.8 Заблуждения и неподтверждённое
**Миф о строках 18–31:** В документе SprinterGraphics programming.txt
утверждается, что после выбора строки Y через RGADR, по адресам
`#C400..#FC00` доступны строки Y+1..Y+15 (с шагом 1 КБ). В эмуляторе MAME
это **не работает** — весь 16-КБ диапазон страницы `#50..#5F` отображает
только строку Y, независимо от бит A[13:10] адреса Z80. Требуется проверка
на реальном Sprinter Sp2000.
---
## 5.9 Кросс-ссылки
- Палитра и видеорежимы BIOS: `02-bios.md §2.7`
- SETVMOD (DSS): `03-dss.md §3.10`
- Акселератор: `06-accel.md`
- Быстрое ОЗУ и конфликт с акселератором: `04-memory.md §4.6`
- Порты RGADR/RGMOD: `11-ports.md`
- Баги акселератора: `12-bugs.md`
- Проектные документы: `sprite-api-design.md`, `accel-fill-budget.md`
+221
View File
@@ -0,0 +1,221 @@
# 6. Акселератор
## 6.1 Общие сведения
Акселератор — внутреннее устройство, реализованное в ППЛМ. Присутствует почти
во всех конфигурациях Sprinter (Sprinter-2 и выше). Предназначен для ускорения
пересылки блоков данных между RAM и VRAM (до физического предела скорости ОЗУ).
Не поддерживает ПЗУ и Fast RAM [accelerator_doc.txt:5].
**Возможности:**
- Быстрая заливка горизонтальной или вертикальной линии экрана (1..256 пикселей)
одним цветом; в режиме 640×256 — линия 1..512 пикселей.
- Быстрое копирование горизонтальной или вертикальной линии (1..256 пикселей).
- Логические операции AND, OR, XOR с блоками данных.
**Внутренняя память:** 256 байт в ППЛМ. Данные загружаются в эту память,
затем копируются в выбранный участок RAM/VRAM. Операция копирования может
повторяться многократно — это позволяет заполнять экран текстурой без
перезагрузки данных.
**Автоматический инкремент адреса:**
- **Горизонтальные** операции (`LD L,L` — копирование, `LD C,C` — заливка):
акселератор автоматически инкрементирует регистр HL (адрес приёмника) на
каждом шаге. Для копирования источник (DE) также инкрементируется.
- **Вертикальные** операции (`LD A,A` — копирование, `LD E,E` — заливка):
акселератор автоматически меняет порт `RGADR` (`#89`) — координату Y.
После завершения операции `RGADR` содержит новое значение
(Y + размер_блока, если не было переполнения).
- **Комбинированный** режим (горизонтальный источник + вертикальный приёмник):
сначала загружается байт из последовательных данных, затем выполняется
вертикальная запись. `RGADR` инкрементируется; регистр-источник (DE)
тоже инкрементируется — можно последовательно читать спрайт и рисовать
его вертикальными строками (§6.3, пример «Спрайт»).
## 6.2 Команды
Акселератор управляется специальными инструкциями Z80, которые выполняются
как NOP обычным процессором, но распознаются ППЛМ [IvanMak.txt:810848].
| Инструкция | Код | Действие |
|-----------|:---:|----------|
| `LD B,B` | `#40` | **Выключить** акселератор |
| `LD D,D` | `#52` | **Включить** + режим «задать размер блока» |
| `LD A,size` | `#3E size` | Установить размер блока (сразу после `LD D,D`) |
| `LD C,C` | `#4F` | **Горизонтальная заливка** одним байтом |
| `LD E,E` | `#5B` | **Вертикальная заливка** одним байтом |
| `LD L,L` | `#6D` | **Горизонтальное копирование** блока |
| `LD A,A` | `#7F` | **Вертикальное копирование** блока |
| `LD H,H` | `#64` | Зарезервировано |
**Логические операции** (AND, OR, XOR) выполняются командами
`AND (HL)`, `OR (HL)`, `XOR (HL)` после загрузки блока в память акселератора.
## 6.3 Примеры
### Копирование экрана (страница 0 → страница 1)
```asm
; страница VRAM уже открыта по адресу #C000
LD HL, #C000 ; адрес начала линии первого экрана
LD DE, #C140 ; адрес начала линии второго экрана
LD BC, #140 ; длина строки по горизонтали (320)
DI ; запретить прерывания
LD D,D ; включить акселератор: режим размера блока
LD A, 0 ; размер блока = 256 байт (0 = 256)
LD A,A ; вертикальное копирование
LDIR ; копировать
LD B,B ; выключить акселератор
EI ; разрешить прерывания
```
Время исполнения: ~1.2 прерывания (~24–26 мс на полный экран)
[IvanMak.txt:822823], [accelerator_doc.txt:37].
### Заливка блока одним цветом
```asm
LD DE, #C000 + X ; X — смещение по горизонтали
LD A, Y
OUT (#89), A ; RGADR = Y
DI
LD D,D ; режим размера блока
LD A, width ; ширина блока
LD B,B ; стоп
LD A, colour ; цвет заливки
LD C,C ; горизонтальная заливка
LD (DE), A ; залить
LD B,B ; стоп
EI
```
### XOR блока данных
```asm
LD HL, addr_1
LD DE, xor_data
DI
LD D,D
LD A, 0 ; 256 байт
LD L,L ; горизонтальное копирование
LD A, (DE) ; загрузить блок в память акселератора
XOR (HL) ; XOR с данными в RAM
LD (HL), A ; сохранить результат
LD B,B ; стоп
EI
```
### Копирование вертикальной линии с разделением load/write
Загрузка байта в буфер акселератора и запись из буфера в VRAM разнесены —
между ними можно выполнять произвольный код (например, сменить Y).
Буфер акселератора и размер блока **сохраняются** между включениями и
выключениями (`LD B,B`), что позволяет гибко разделять чтение
и запись.
```asm
LD HL, #C000 + X1 ; источник
LD DE, #C000 + X2 ; приёмник
DI
LD D,D ; акселератор вкл, режим размера
LD A, size ; размер блока
LD B,B ; выключить (размер запомнен)
LD A, Y1
OUT (#89), A ; RGADR = Y1
LD A,A ; вертикальное копирование
LD A, (HL) ; загрузить байт из (HL) в буфер акселератора
LD B,B ; выключить (буфер запомнен)
LD A, Y2
OUT (#89), A ; RGADR = Y2 (смена Y между load и write)
LD A,A ; вертикальное копирование
LD (DE), A ; записать буфер в (DE) — акселератор пишет
; вертикальную линию size пикселей
LD B,B ; выключить
EI
```
### Спрайт вертикальными строками из последовательных данных
Спрайт хранится как последовательность байт вертикальных линий. Для каждой
колонки спрайта: загружается байт из последовательных данных, затем
акселератор пишет его вертикально (автоинкремент `RGADR`). После завершения
колонки — сдвиг по X (`INC HL`) и повтор.
```asm
LD DE, sprite_data ; DE → последовательные данные спрайта
LD HL, #C000 + X_COORD ; HL → начальная позиция на экране
LD B, sprite_width ; ширина спрайта в колонках
LD D,D ; акселератор вкл, режим размера
LD A, sprite_height ; высота одной вертикальной линии
LD B,B ; акселератор выключили (размер акселератор запомнил)
row:
LD A, Y_COORD
OUT (#89), A ; RGADR = стартовая Y
DI
LD L,L ; режим «загрузить из последовательных данных»
LD A, (DE) ; загрузить байт спрайта в буфер акселератора
LD A,A ; вертикальное копирование
LD (HL), A ; записать — акселератор копирует байт
; вертикально, RGADR++ на каждом шаге
LD B,B ; выключить акселератор
EI
INC HL ; следующая колонка по X
DJNZ row
```
## 6.4 Скорость
Время работы акселератора ограничено только физической скоростью ОЗУ
[IvanMak.txt:840843]:
```
Время ≈ время команды без акселератора + число_байт / 7 000 000 (сек)
```
## 6.5 Комбинированный режим: общая схема
Общий паттерн для работы с акселератором в комбинированном режиме
(горизонтальный источник + вертикальный приёмник):
```
LD D,D ; 1. Включить акселератор, режим размера
LD A, size ; 2. Задать размер блока (1..256)
LD L,L ; 3. Режим «горизонтальный источник»
<чтение байта> ; 4. Загрузить байт в буфер акселератора (LD A,(DE) и т.п.)
LD A,A ; 5. Режим «вертикальный приёмник»
<запись байта> ; 6. Записать — акселератор делает вертикальное копирование
; с автоинкрементом RGADR и приёмника
LD B,B ; 7. Выключить акселератор
```
После шага 6 `RGADR` содержит Y + size, HL — X + 1 (если был `INC HL`).
## 6.6 Прерывания
**Старая прошивка:** DI обязателен на время работы акселератора — система
команд Z80 сильно меняется, и ISR не сможет корректно выполниться
[IvanMak.txt:844846].
**Новая прошивка:** акселератор может работать с EI. По приходу прерывания
он отключается, а по `RETI` включается обратно [IvanMak.txt:846848].
Использовать этот режим следует с осторожностью — без проверки на реальном
железе неизвестно, какая версия прошивки установлена.
---
## 6.7 Кросс-ссылки
- Баги акселератора: `12-bugs.md`
- Использование акселератора в libbgi: `sprite-api-design.md`
- Ограничение скорости: `accel-fill-budget.md`
- Fast RAM и конфликт с портом CBL: `04-memory.md §4.6`
+92
View File
@@ -0,0 +1,92 @@
# 7. Прерывания (IRQ)
## 7.1 Общие сведения
Sprinter Sp2000 поддерживает режимы прерываний IM1 и IM2.
### Источники прерываний
| Источник | Происхождение | Описание |
|----------|---------------|----------|
| Кадровые (INT) | Видеоконтроллер | Квадратик экрана в 8-й линии |
| CTC | Z84C15 | Таймерные прерывания |
| SIO | Z84C15 | AT-клавиатура |
| PIO | Z84C15 (бит 0 порта B, `#1F`) | ISA-слоты |
| CBL | COVOX-Blaster | Запрос данных |
### Различение источников
Кадровые и клавиатурные прерывания приходят с вектором `0FFh` [Parinov.txt:956]. Способ различения:
- Клавиатура выставляет бит 0 в порте `19h` — признак приёма байта [Parinov.txt:1049]
- Если бит 0 порта `19h` не установлен — прерывание кадровое
> **Примечание:** [Parinov.txt:956] описывает альтернативный метод — «отличать по биту приема байта в порте клавиатуры». Оба метода сводятся к проверке бита 0 в порте `19h`.
### Выбор режима прерываний (IM1 vs IM2)
| Режим | Контекст | Источник |
|-------|----------|----------|
| IM2 | Рекомендован для работы с BIOS через RST | IvanMak.txt:14691473 |
| IM1 | Используется DSS для своих обработчиков | — |
| IM1 | Fast-RAM секция предполагает обработчик по `#0038` | Parinov.txt:601 |
| IM2 | Рекомендован при выставленных прерываниях от CBL | Parinov.txt:762763 |
> **Примечание:** разные подсистемы рекомендуют разные режимы. IM2 предпочтителен при интенсивной работе с прерываниями (CBL, BIOS). IM1 используется DSS по умолчанию.
## 7.2 Кадровые прерывания (INT)
Генерируются в момент прохождения 8-й строки квадратика (настраивается через бит 0 порта `#FE`). Положение INT подстраивается под стандарт Pentagon (320 строк) или Scorpion (312 строк).
> **Мышь — есть ли аппаратные прерывания?** [Parinov.txt:956] утверждает: «От мыши прерывания не приходят. Сделать можно, но сейчас их нет.» [ProgrammerManual.txt:17841786] описывает драйвер мыши, где «каждое нажатие и отпускание клавиш или перемещение мыши вызывает прерывание», и документирует функцию «80h MOUSE HARDWARE INTERRUPT» [ProgrammerManual.txt:19301937]. Parinov (разработчик драйвера) отрицает их наличие — возможно, ProgrammerManual описывает планируемую функциональность.
## 7.3 CTC (Z84C15)
Таймер CTC используется для:
- Генерации периодических прерываний
- Задания частоты CBL (COVOX-Blaster)
- Синхронизации звука
## 7.4 SIO (Z84C15)
Внутренний SIO Z84C15 обслуживает:
- AT-клавиатуру (порты `#18`/`#19`)
- RS-232 (для мыши и других последовательных устройств)
## 7.5 IM1 — вектор #0038
Стандартный Z80-режим. Все INT ведут на адрес `#0038`. Используется DSS для своих обработчиков.
## 7.6 IM2 — таблица векторов
IM2 использует таблицу векторов (256 байт) в фиксированной странице (обычно W3). Вектор прерывания — `0FFh`.
Для работы IM2 требуется:
1. Таблица векторов в резиденте (W3)
2. Регистр I = старший байт адреса таблицы
3. Каждый вектор — адрес обработчика (2 байта)
## 7.7 Акселератор и прерывания
При работе акселератора система команд Z80 сильно меняется.
| Режим | Описание | Источник |
|-------|----------|----------|
| Старый | DI обязателен | IvanMak.txt:844846, Parinov.txt:954 |
| Новый | EI/RETI: по INT акселератор отключается, по RETI включается | IvanMak.txt:846848 |
> **Примечание:** IvanMak описывает два режима (старый — DI, новая прошивка — EI/RETI). Parinov знает только старый. Без тестирования на железе неизвестно, какая версия прошивки установлена.
## 7.8 Цепочка обработчиков
TODO (проектный `im2_isr_design.md`): цепочка irq_install/remove, FPS-делитель, обработчики клавиатуры.
## 7.9 Кросс-ссылки
- Порты прерываний: `11-ports.md`
- Проектный документ по IM2/ISR: `im2_isr_design.md`
- Клавиатура: `09-input.md §9.1`
- CBL (прерывания): `10-sound.md §9.4.6`
+197
View File
@@ -0,0 +1,197 @@
# 8. Ввод-вывод
## 8.1 Клавиатура и мышь
Клавиатура и мышь вынесены в отдельный документ: `09-input.md`.
Сводная информация по портам и прерываниям — `09-input.md §§9.19.6`.
## 8.2 Звук
Звуковая подсистема (AY-3-8910, COVOX, COVOX-Blaster, бипер) вынесена
в отдельный документ: `10-sound.md`.
Сводная карта звуковых портов: `11-ports.md §11.6`.
## 8.3 Дисковая подсистема
### 8.3.1 FDD (WD1793 / КР1818ВГ93)
Контроллер дисковода — стандартный Beta Disk Interface (WD1793).
Аппаратное перенаправление `#1F → #0F` (см. §8.4).
**Регистры (по данным MAME sprinter.cpp):**
| Z80-адрес | Регистр |
|-----------|---------|
| `#0F` | Status (чт) / Command (зп) |
| `#1F` | —//— (аппаратный ремап на `#0F`) |
| `#3F` | Track |
| `#5F` | Sector |
| `#7F` | Data |
| `#FF` | Drive Control (выбор дисковода) |
**Противоречие: адресация регистров ВГ93.**
> - [IvanMak.txt:12701274]: 4 регистра + `#FF` — управление дисководом.
> - [Parinov.txt:963]: 3 регистра (data-регистр `#7F` пропущен).
>
> MAME реализует полный набор по IvanMak: Status/Command (`#0F`), Track (`#3F`),
> Sector (`#5F`), Data (`#7F`). Data-регистр важен — через него читаются/пишутся
> сектора. Parinov, вероятно, упустил его.
**Turbo-режим FDD (DCP 0x16/0x17, биты):**
- Бит 0 = скорость (0=норм, 1=турбо)
- Бит 1 = отключение FDD [sprinter.cpp:914920]
### 8.3.2 HDD (IDE/ATA)
Два ATA-интерфейса: первичный и вторичный. Доступ — через DCP-декодер
(внутренние коды 0x20–0x2b).
**Регистры ATA CS0 (по sprinter.cpp):**
| DCP код | Z80-адрес (старш.) | Регистр |
|---------|-------------------|---------|
| 0x20 | `#xx50` | Data (16-bit через защёлку байтов) |
| 0x21 | `#xx51` | Error (чт) / Features (зп) |
| 0x22 | `#xx52` | Sector Count |
| 0x23 | `#xx53` | Sector Number |
| 0x24 | `#xx54` | Cylinder Low |
| 0x25 | `#xx55` | Cylinder High |
| 0x26 | `#xx56` | Device/Head |
| 0x27 | `#xx57` | Status (чт) / Command (зп) |
| 0x28 | `#xx58` | Alt Status (чт) / Device Control (зп) (CS1) |
| 0x2a | HDD1 select (вторичный) |
| 0x2b | HDD2 select (первичный) |
**16-битный data-порт:** MAME реализует защёлку байтов: чтение `#xx50`
возвращает младший байт (bit8=0), затем старший (bit8=1) [sprinter.cpp:958972].
**Противоречие: HDD — разные адреса для чтения и записи.**
> - [IvanMak.txt:1366]: кратко: «#xx50..#xx55 порты HDD»
> - [Parinov.txt:958959]: таблица с разными адресами для R/W:
> `0050h` (чт) / `0150h` (зп) — data, `4053h` (чт) / `4153h` (зп) — status/command.
>
> MAME использует единую карту DCP-кодов (0x20–0x28) без разделения R/W.
> Parinov описывает реальное поведение на Sprinter-2, где адресная линия A8
> управляет направлением — это внешняя особенность конкретной ППЛМ-прошивки.
> IvanMak упрощает до базовых DCP-кодов.
Доступ к IDE открыт в режиме Sprinter-ZX, в режимах Pentagon/Scorpion — закрыт.
### 8.3.3 CMOS (Dallas DS12887A)
Микросхема DS12887A (RTC + 114 байт NV RAM). Совместима с MC146818A.
Доступ через DCP-коды 0x1c0x1e.
| Z80-адрес | DCP код | Функция |
|-----------|---------|---------|
| `#DFBD` | 0x1d | Запись адреса регистра CMOS |
| `#FFBD` | 0x1c | Чтение данных из выбранного регистра |
| `#BFBD` | 0x1e | Запись данных в выбранный регистр |
При отсутствии микросхемы CMOS эмулируется BIOS [BIOS_v3.txt:308310].
**Карта регистров RTC (совместимо с MC146818A):**
| Рег. | Назначение | Формат |
|------|-----------|--------|
| 0x00 | Секунды | BCD |
| 0x01 | Секунды (будильник) | BCD |
| 0x02 | Минуты | BCD |
| 0x03 | Минуты (будильник) | BCD |
| 0x04 | Часы | BCD |
| 0x05 | Часы (будильник) | BCD |
| 0x06 | День недели (1=воскресенье) | BCD |
| 0x07 | Число | BCD |
| 0x08 | Месяц | BCD |
| 0x09 | Год | BCD |
| 0x0a | Регистр A (UIP, divider, rate) | биты |
| 0x0b | Регистр B (SET, PIE, AIE, UIE, SQWE, DM, 24/12, DSE) | биты |
| 0x0c | Регистр C (IRQF, PF, AF, UF) | биты (чт) |
| 0x0d | Регистр D (VRT) | биты (чт) |
| 0x0e0x7f | 114 байт NV RAM | пользовательские |
---
## 8.4 Джойстик
**Два Kempston-совместимых джойстика** [sprinter.cpp:11061175]:
- **JOY1** — через CIO_DTRB (DCP 0x15, совмещён с Beta state при чтении)
- **JOY2** — через PIO PB
**Формат данных (Kempston):**
| Бит | Кнопка |
|:---:|--------|
| 0 | Вправо |
| 1 | Влево |
| 2 | Вниз |
| 3 | Вверх |
| 4 | Fire |
| 5 | — |
| 6 | — |
| 7 | — |
**Противоречие: джойстик #1F vs #0F.**
> - [IvanMak.txt:1344]: «#1F,#0F — RD_KEMPS — порт джойстика.
> В Sprinter-1 порт #1F аппаратно переадресуется на порт #0F
> - [IvanMak.txt:861868]: команды `OUT (#1F),A` не срабатывают
> из-за перенаправления. Надо использовать `LD BC,#1F : OUT (C),A`.
>
> В Sprinter-1 включено аппаратное перенаправление `#1F → #0F`,
> из-за чего `IN A,(#1F)` не читает джойстик. MAME подтверждает:
> на Sp2000 (`m_cnf` bit 0) перенаправление отключается
> [sprinter.cpp:1106]. Ремап действует только на запись: при OUT
> порт `#1F` маппится на `#0F` через DCP [sprinter.cpp:1080].
JOY2 читается через PIO port A [sprinter.cpp:11361140].
---
## 8.5 Параллельный порт (принтер)
Centronics-совместимый через ППЛМ. BIOS-функции печати: 082h–08Ch
(см. `02-bios.md`).
---
## 8.6 Шина ISA
Два 8-битных ISA-слота на частоте X_SP/5 (~7 МГц). Доступ — через
DCP-декодер и страницы памяти.
**Управляющие порты ISA (DCP 0xD00xDF, 0xF80xFF):**
| Бит | Назначение |
|:---:|-----------|
| 2 | 0 = ISA memory access, 1 = ISA I/O access |
| 1 | Выбор слота (0 = slot 0, 1 = slot 1) |
Адресное расширение: `m_isa_addr_ext` (запись через DCP 0x1b) — биты
расширения адреса для ISA-циклов [sprinter.cpp:10321039].
**Memory-маппинг ISA:** При pg3 & 0xF9 == 0xD0 (бит 10 окна W3 = 1,
BANK_ISA_MASK) обращения к окну W3 (`#C000#FFFF`) направляются на ISA-шину
вместо RAM [sprinter.cpp:178181, 530532]. Длина — 16 КБ.
**I/O-доступ к ISA:** через тот же DCP-декодер. Устройства устанавливают
сигнал `m_io_input_wait` = true при совпадении адреса.
> **Примечание:** В MAME есть TODO: «ISA memory slots» — ISA memory-циклы
> пока не эмулируются [sprinter.cpp:576]. На реальном Sprinter поддержка
> зависит от прошивки ППЛМ.
Слот 0 обычно занят ZX-Bus-адаптером [sprinter.cpp:26].
---
## 8.7 Кросс-ссылки
- BIOS-функции: `02-bios.md`
- Клавиатура, мышь: `09-input.md`
- Звук: `10-sound.md`
- Порты: `11-ports.md`
- Акселератор: `06-accel.md`
- Прерывания: `07-irq.md`
+595
View File
@@ -0,0 +1,595 @@
# 9. Клавиатура и мышь
## 9.1 Общие сведения
Клавиатура Sprinter — AT-совместимая (101 key, PS/2). В Sprinter-1
дополнительно присутствует ZX-клавиатурная матрица через порт `#FE`
(скан-код через AT-контроллер преобразуется в ZX-матрицу). Sprinter-2+
использует AT-клавиатуру через внутренний SIO Z84C15 (канал A).
Мышь — Microsoft Serial Mouse (2 кнопки) через RS-232 на SIO-B (канал B
Z84C15).
### Порты SIO
| Порт | Назначение |
|------|-----------|
| `#18` | SIO-A data — клавиатура |
| `#19` | SIO-A control — статус/управление |
| `#1A` | SIO-B data — мышь |
| `#1B` | SIO-B control — мышь |
Бит 0 порта `#19` — признак прерывания от клавиатуры (используется в IM2
для различения источников с общим вектором `#FF`).
### Прерывания
Клавиатура и мышь работают в IM2, общий вектор `#FF` (совместно с
кадровым и CBL). Различение источника — по портам SIO и флаговым битам
(`07-irq.md §7.2`).
---
## 9.2 Клавиатура: BIOS и ESTEX
### FN_KBD_OUT (BIOS $EA)
Отправляет байт непосредственно на AT-клавиатуру [BIOS_v3.txt:0EAh].
```
Вход: C = $EA
A = байт команды/данных для AT-клавиатуры
Выход: нет
```
Используется для низкоуровневой настройки клавиатуры (LED-индикаторы,
повтор, задержка).
### ESTEX: функции клавиатуры (30h–37h)
Через `RST 10h` с C=30h37h [DiskSyscalls.txt:30h37h].
**WAITKEY (30h):** ждёт нажатия, возвращает код.
```
Вход: C = 30h
Выход: A = код символа
D = скан-код
E = ASCII-код (0 для функциональных клавиш)
```
**SCANKEY (31h):** опрос без ожидания.
```
Вход: C = 31h
Выход: A = код символа (0 если нажатий нет)
D = скан-код
E = ASCII-код
```
**ECHOKEY (32h):** ждёт + эхо-вывод.
```
Вход: C = 32h
Выход: A = код символа
D = скан-код
E = ASCII-код
```
**CTRLKEY (33h):** состояние модификаторов и режимов. libc: `kbd_mod_state()`.
```
Вход: C = 33h
Выход: C = mode (биты режимов — см. ниже)
B = shift (биты зажатых модификаторов)
```
| Бит C | Режим |
|-------|-------|
| 0 | РУС/ЛАТ (0=ЛАТ, 1=РУС) |
| 1 | NumLock |
| 2 | ScrollLock |
| 3 | CapsLock |
| 4 | Insert |
| Бит B | Модификатор |
|-------|------------|
| 0 | Left Shift |
| 1 | Right Shift |
| 2 | Ctrl (любой) |
| 3 | Alt (любой) |
| 4 | Left Ctrl |
| 5 | Left Alt |
| 6 | Right Ctrl |
| 7 | Right Alt |
**K_CLEAR (35h):** сбросить буфер клавиатуры.
```
Вход: C = 35h
```
**K_SETUP (36h):** настройка раскладки. [DiskSyscalls.txt:36h]
```
Вход: C = 36h
A = 0 — получить текущий номер раскладки
A = 1 — установить раскладку по номеру из B
A = 2 — получить имя текущей раскладки (адрес HL)
Выход: при A=0: A = номер раскладки
при A=2: HL = адрес строки с именем
```
| Номер | Раскладка |
|-------|----------|
| 0 | Английская (US) |
| 1 | Русская |
| 2 | Английская (UK) |
| 3 | Украинская |
Переключение раскладки по Ctrl+Space (если не переназначено).
**TESTKEY (37h):** тест на нажатие (без извлечения из буфера).
```
Вход: C = 37h
Выход: A = код символа (0 если нет)
D = скан-код
E = ASCII-код
```
---
## 9.3 Клавиатура: необработанный (raw) доступ
Штатный DSS (WAITKEY/SCANKEY/CTRLKEY) даёт событийный интерфейс —
нажатия, а не состояния клавиш. Для игр и real-time приложений требуется
чтение **зажатых клавиш в каждый момент**. Это реализуется через
перехват SIO-A напрямую в обработчике IM2, минуя DSS.
### 9.3.1 Принцип
1. Установить свой обработчик IM2 (общий вектор `#FF`).
2. В обработчике читать байты с SIO-A (порт `#18`), декодировать
PS/2 Scan Code Set 2, обновлять битовую карту held-состояний.
3. Основной код по кадровому прерыванию (или раз в кадр) читает карту
опросом — без ожидания.
4. DSS не получает байт с клавиатуры, пока обработчик их забирает.
Для восстановления нормального ввода — временно отключить перехват.
### 9.3.2 SIO-A и прерывания
SIO-A (порт данных `#18`, управление `#19`) работает в IM2.
**Инициализация SIO-A** (выполняется BIOS при загрузке, повторно не требуется):
| WR | Значение | Эффект |
|:--|:---------|--------|
| WR0 | `0x10` | Сброс RR1 (ошибка) |
| WR1 | `0x07` | Прерывания по Rx готовности |
| WR3 | `0xC1` | Rx 8 бит, без CRC |
| WR4 | `0x44` | ×1 клок, 1 стоп-бит, без паритета |
| WR5 | `0xEA` | Tx 8 бит, DTR+RTS=1 |
**Различение в IM2:** при входе в обработчик проверить бит 0 порта `#19`.
Если 0 — прерывание не от SIO-A (кадровое, CBL — пропустить).
### 9.3.3 PS/2 Scan Code Set 2 — протокол
SIO-A передаёт скан-коды PS/2 Set 2. Каждый байт с порта `#18`
один байт протокола. Размер сообщения:
| Последовательность | Значение |
|:------------------|:---------|
| `<code>` | Make — клавиша нажата (код < 0xF0) |
| `0xF0 <code>` | Break — клавиша отпущена |
| `0xE0 <code>` | Extended — расширенная клавиша (стрелки, RAlt, RCtrl) |
| `0xE0 0xF0 <code>` | Extended break |
Make-байт устанавливает бит клавиши в held-карте.
Break-байт сбрасывает.
**FSM декодирования (2 состояния):**
```
PEND_MAKE:
получить байт B
if B == 0xF0 → переход PEND_BREAK
if B == 0xE0 → переход PEND_EXT, Bзап = B
иначе → make(B)
PEND_BREAK:
получить байт B
переход PEND_MAKE
if (ext_flag) → break_ext(B); ext_flag = 0
иначе → break(B)
PEND_EXT:
получить байт B
if B == 0xF0 → ext_flag = 1, переход PEND_BREAK_EXT
иначе → make_ext(B); переход PEND_MAKE
PEND_BREAK_EXT:
получить байт B
ext_flag = 0
break_ext(B)
переход PEND_MAKE
```
### 9.3.4 Битовая карта held-состояний
Массив 128 байт (1024 бита для кодов 0..1023, расширенные — с битом
`0x0100`).
Простая реализация:
```asm
; HL = code (0..0x1FF)
; IX = base адреса карты
LD A, H
AND A, 0x07 ; номер бита 8..10
LD D, A
LD A, L
RRCA ; HL/8 (3 сдвига)
RRCA
RRCA
AND A, 0x1F
LD L, A
LD A, H
AND A, 0x07
ADD A, A ; +8*...
ADD A, A
ADD A, A
ADD A, L
LD L, A
LD H, 0x00
ADD IX, HL ; IX = &bitmap[code / 8]
LD A, D
INC A
LD B, A ; B = номер бита в байте + 1
XOR A
SCF ; carry=1 для make, 0 для break
RL A
DJNZ $-2 ; A = 1 << (code & 7)
; make: OR (IX), A ; break: CPL + AND (IX), A
```
### 9.3.5 Overrun recovery
SIO FIFO глубиной 3 байта. Если обработчик прерывания не успевает
забрать байты (длинная DI-секция, акселератор), FIFO переполняется —
RR1 bit5 = 1. С этого момента цепочка make+break нарушена, возможны
залипшие клавиши.
**Алгоритм восстановления:**
1. Обнаружить overrun (читать SIO RR1, бит 5).
2. Сбросить held-карту **всех клавиш, кроме**:
| Код PS/2 | Клавиша | Почему |
|:--------:|:--------|:-------|
| `0x12` | Left Shift | PS/2 автоповтор — только последняя |
| `0x59` | Right Shift | нажатая клавиша. Если сбросить |
| `0x14` | Left Ctrl | модификатор, он не восстановится до |
| `0x11` | Left Alt | физического отпускания. Игра «теряет» |
| `0xE014` | Right Ctrl | шифт/контрол/альт при каждом overrun. |
| `0xE011` | Right Alt | |
3. Взвести флаг «был overrun» — основной код может проигнорировать
held-состояние на этот кадр.
### 9.3.6 Координация с DSS
Пока обработчик забирает байты с SIO-A, FIFO пуст — DSS не видит
клавиатуру. Для вызова DSS-функций (консоль, диалоговые окна):
1. Переключить флаг «raw active = 0» в IM2-обработчике.
2. Обработчик начинает пропускать байты в DSS (JP `0038h` или
через штатный трамплин).
3. После завершения ввода — переключить флаг обратно.
**Внимание:** если обработчик просто перестаёт читать SIO-A, но не
возвращает управление DSS, порт SIO-A перестанет генерировать
прерывания (FIFO полон, Rx готов = 0). Для корректной передачи
управления нужно разрешить DSS-обработчику читать SIO-A.
### 9.3.7 Пример: минимальный raw-обработчик
```asm
; Флаги: raw_active = 1 — перехватывать, 0 — пропускать в DSS
; Карта: kbd_held — 128 байт, занулена при старте
; FSM: kbd_state — 0=PEND_MAKE, 1=PEND_BREAK, 2=PEND_EXT, 3=PEND_BREAK_EXT
; kbd_ext — флаг extended (0/1)
KBD_ISR:
; Проверить, что прерывание от SIO-A
IN A, (#19) ; SIO-A RR0
BIT 0, A ; бит 0 = прерывание от SIO-A?
RET Z ; нет — пропустить
IN A, (#18) ; прочитать байт скан-кода
BIT raw_active ; перехват активен?
JP Z, DSS_IRQ ; нет — пусть DSS обработает
; FSM: текущее состояние в kbd_state
LD HL, kbd_state
LD A, (HL)
AND A, 3
JP Z, .pend_make
DEC A
JP Z, .pend_break
DEC A
JP Z, .pend_ext
; .pend_break_ext
LD (HL), 0 ; → PEND_MAKE
LD A, B ; код клавиши
CALL break_ext
EI
RETI
.pend_make:
LD A, B ; байт с SIO-A (уже в B из IN)
CP 0xF0
JR Z, .set_break
CP 0xE0
JR Z, .set_ext
CALL make ; обычный make
LD (HL), 0 ; остаёмся PEND_MAKE
EI
RETI
.set_break:
LD (HL), 1 ; → PEND_BREAK
EI
RETI
.set_ext:
LD (HL), 2 ; → PEND_EXT
EI
RETI
.pend_break:
LD (HL), 0 ; → PEND_MAKE
CALL break
EI
RETI
.pend_ext:
LD A, B
CP 0xF0
JR Z, .set_ext_break
CALL make_ext
LD (HL), 0
EI
RETI
.set_ext_break:
LD (HL), 3 ; → PEND_BREAK_EXT
EI
RETI
```
Размер кода — ~60 байт.
---
## 9.4 Мышь
Драйвер мыши установлен в системном shell Sprinter и доступен через
SST-вызов `RST 30h`.
### 9.4.1 SST-функции мыши
Вызов: `RST 30h` с A = номер функции. Выход в зависимости от функции
(см. таблицу).
| № | Назначение | Вход | Выход |
|:-:|:-----------|:-----|:------|
| `$00` | Инициализация | A=$00 | — |
| `$01` | Показать курсор | A=$01 | — |
| `$02` | Спрятать курсор | A=$02 | — |
| `$03` | Читать состояние | A=$03 | DE=X, HL=Y, A=buttons (b0=left, b1=right) |
| `$04` | Переместить курсор | A=$04, DE=X, HL=Y | — |
| `$05` | Установить границы X | A=$05, DE=min, HL=max | — |
| `$06` | Установить границы Y | A=$06, DE=min, HL=max | — |
| `$07` | Вид курсора (текст) | A=$07, DE=sym_and:sym_xor, HL=attr_and:attr_xor | — |
| `$09` | Загрузить курсор (граф.) | A=$09, IX=pointer | — |
| `$0B` | Прочитать курсор | A=$0B | IX=pointer (копия) |
| `$0C` | Чувствительность X | A=$0C, D=value (1..255) | — |
| `$0D` | Чувствительность Y | A=$0D, D=value (1..255) | — |
| `$0E` | Прочитать чувств. X | A=$0E | D=value |
| `$0F` | Прочитать чувств. Y | A=$0F | D=value |
| `$11` | Уведомить о смене режима | A=$11, D=режим (0=текст, 1=граф-256, 2=граф-16) | — |
**Пример: прочитать состояние мыши в asm:**
```asm
LD A, $03 ; READ
RST 30h
; DE = X, HL = Y, A = buttons
LD (mouse_x), DE
LD (mouse_y), HL
AND A, 3
LD (mouse_btn), A
```
### 9.4.2 Чувствительность
Значение — **делитель**: драйвер считает N raw-шагов мыши, прежде чем
сдвинуть курсор на 1 пиксель. **Меньше = быстрее** (чувствительнее).
Рекомендуемое начальное значение: 2 по обеим осям.
```asm
LD A, $0C ; SET_SENS_H
LD D, 2
RST 30h
LD A, $0D ; SET_SENS_V
LD D, 2
RST 30h
```
### 9.4.3 Порядок инициализации
После загрузки драйвер мыши уже инициализирован shell. Если программа
начинает «с чистого листа» (без shell), инициализация обязательна:
```asm
LD A, $00 ; INIT — инициализировать драйвер
RST 30h
LD A, $05 ; BOUNDS_X: границы экрана
LD DE, 0
LD HL, 319 ; для 320×256
RST 30h
LD A, $06 ; BOUNDS_Y
LD DE, 0
LD HL, 255
RST 30h
LD A, $01 ; SHOW — показать курсор
RST 30h
```
### 9.4.4 Смена видеорежима
После переключения видеорежима (графический → текстовый и обратно)
обязательно вызвать `$11`:
```asm
LD A, $11
LD D, 1 ; 0=текст, 1=граф-256, 2=граф-16
RST 30h
```
Иначе драйвер применяет старые координаты, и курсор рисуется
неправильно.
### 9.4.5 Прямой доступ к SIO-B (raw mouse)
Мышь подключена через SIO-B (порты `#1A`/`#1B`), Microsoft Serial Mouse,
1200 бод 7E1. Если программа хочет читать мышь напрямую, минуя
SST-драйвер (например для нестандартного протокола или экономии на
SST), SIO-B нужно инициализировать самостоятельно:
**Инициализация SIO-B (1200 7E1):**
```asm
LD HL, .sio_init
LD B, 6
LD C, #1B ; SIO-B control
OTIR
JR .done
.sio_init:
DB #10 ; WR0: сброс RR1
DB #04 ; WR1: прерывания выкл
DB #44 ; WR4: ×1 клок, 1 стоп, без паритета
DB #C1 ; WR3: Rx 8 бит
DB #EA ; WR5: Tx 8 бит, DTR+RTS=1
DB #15 ; WR0: сброс ошибки + выбран RR1
.done:
```
**Чтение байта с мыши (опрос, без прерываний):**
```asm
IN A, (#1B) ; SIO-B RR0
BIT 0, A ; бит 0 = Rx готов?
JR Z, .no_data
IN A, (#1A) ; прочитать байт
; обработать ...
```
**Формат пакета Microsoft Serial Mouse:**
Длина: 3 байта.
| Байт | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|:----:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 0 | 1 | 0 | 0 | 0 | L | R | Y7 | Y6 |
| 1 | 0 | X6 | X5 | X4 | X3 | X2 | X1 | X0 |
| 2 | 0 | Y5 | Y4 | Y3 | Y2 | Y1 | Y0 | X7 |
- Координаты X/Y — **относительные** (приращения с последнего пакета), знаковые.
- `X7` — старший бит X (знак), `X6..X0` — младшие.
- `Y7..Y6` — старшие биты Y, `Y5..Y0` — младшие.
- `L` — левая кнопка (1 = нажата), `R` — правая.
**Декодирование:**
```asm
; B = байт 0, C = байт 1, D = байт 2
; X:
LD A, C ; байт 1: X6..X0
LD E, A
LD A, D ; байт 2: X7
RLCA
RLCA
AND A, 0x80
OR A, E ; A = X (7 бит + знак)
; знаковое расширение в HL
LD L, A
RLCA
SBC A, A
LD H, A ; HL = X (знаковое 16-бит)
; Y:
LD A, B ; байт 0: Y7..Y6
RLCA
RLCA ; A[1:0] = Y7..Y6
AND A, 0xC0
LD E, A
LD A, D ; байт 2: Y5..Y0
RLCA
RLCA ; A[7:2] = Y5..Y0
AND A, 0xFC
OR A, E ; A = Y (7 бит + знак)
; знаковое расширение в DE
LD E, A
RLCA
SBC A, A
LD D, A ; DE = Y (знаковое 16-бит)
; Кнопки:
LD A, B
AND A, 0x30 ; биты L (4) и R (5)
RRCA ; A = 0..3
RRCA
RRCA
RRCA
LD (buttons), A
```
---
## 9.5 Особенности игровой клавиатуры
Документ: `kbd-games.md`. Ниже — ключевые паттерны для реализации.
- **Held-state vs edge-detect:** DSS — событийный (сообщает только момент
нажатия). Raw-канал (§9.3) — state-based (зажата/не зажата прямо сейчас).
Играм нужен второй.
- **Sync once per frame:** раз в кадр (по кадровому прерыванию) проверять
held-карту. Между кадрами карта обновляется только в IM2-обработчике.
- **Edge-detect:** для одноразовых действий (прыжок, выстрел) — запоминать
предыдущее held-состояние и сравнивать:
```
pressed = held & ~prev_held
prev_held = held
```
- **Типоматик:** игнорировать повторные make, пока не придёт break.
Реализация: при make — установить бит только если он ещё не был
установлен; при break — сбросить.
- **Автоотмена (reject):** если за кадр нажато больше N клавиш (например
4) — игнорировать все (защита от баунса и мусора).
- **Recovery:** при overrun — очистить held-карту всех клавиш, кроме
модификаторов (LShift 0x12, RShift 0x59, LCtrl 0x14, LAlt 0x11,
RCtrl 0xE014, RAlt 0xE011).
---
## 9.6 Кросс-ссылки
- Прерывания (IM2, вектор #FF): `07-irq.md §7.2`
- DSS-функции клавиатуры: `03-dss.md §3.6`
- BIOS FN_KBD_OUT: `02-bios.md §2.7`
- Порт клавиатуры `#FE`: `11-ports.md §11.3`
- Игровая клавиатура: `kbd-games.md`
- Баги: `12-bugs.md`
- SIO и порты прерываний: `11-ports.md §11.2`
+377
View File
@@ -0,0 +1,377 @@
# 10. Звук
## 10.1 Общие сведения
> Документ описывает звуковую подсистему платы **Sp2000** и более новых моделей.
> Информация о Sprinter-97 не рассматривается.
Звуковая подсистема Sprinter Sp2000 включает три компонента:
| Компонент | Тип | Описание |
|-----------|-----|----------|
| GM80C760 (AY-3-8910 совм.) | Музыкальный сопроцессор | 3 голоса + шум + огибающая, эмуляция в ППЛМ |
| COVOX | 8-битный ЦАП | Прямой вывод сэмплов через порт `#FB`/`#4F` |
| CBL (COVOX-Blaster) | COVOX с буфером | 256 байт буфера, прерывания, разные режимы |
Весь звук выводится через **16-битный ЦАП TDA1543** (двухканальный, стерео).
Реально используется 10 бит для одновременного смешивания 8-bit COVOX и AY
[IvanMak.txt:632634].
**На Sp2000 все три компонента присутствуют в основной прошивке ППЛМ.**
CBL включается через порт `#4E` (бит 7 = 1). При выключенном CBL (бит 7 = 0)
работает обычный 8-bit COVOX [IvanMak.txt:662666].
## 10.2 GM80C760 (AY-3-8910)
### 10.2.1 Реализация
AY-функция реализована на микросхеме **GM80C760** (ППЛМ ALTERA EP1K30),
AY-3-8910/8912 совместимая. Это не отдельная дискретная микросхема
[IvanMak.txt:636637].
На EP1K30 (Sp2000) реализована **3-я версия** AY. Включает три голоса,
шум и генератор огибающей (envelope). В формирователе огибающей обнаружена
небольшая ошибка, детали не документированы [IvanMak.txt:224229],
[12-bugs.md §11.2].
### 10.2.2 Порты
| Порт | Назначение |
|------|-----------|
| `#BFFD` | AY-8910 — запись номера регистра (address) |
| `#FFFD` | AY-8910 — чтение/запись данных регистра (data) |
Внутренние номера в карте дешифратора ППЛМ: `90h` (`#BFFD`), `91h` (`#FFFD`)
[IvanMak.txt:12981299].
### 10.2.3 Программирование
Программирование — **стандартное для AY-3-8910/8912**
[IvanMak.txt:636637]:
```asm
; Установить регистр AY
LD BC, #BFFD
OUT (C), A ; A = номер регистра (0..15)
LD BC, #FFFD
OUT (C), A ; A = значение
; Прочитать регистр AY (3-я версия)
LD BC, #BFFD
OUT (C), A ; A = номер регистра
LD BC, #FFFD
IN A, (C) ; читать данные
```
**Регистры AY-3-8910** (стандартные):
| № | Назначение |
|:-:|-----------|
| 0 | Частота канала A (младший байт) |
| 1 | Частота канала A (старшие 4 бита) |
| 2 | Частота канала B (младший байт) |
| 3 | Частота канала B (старшие 4 бита) |
| 4 | Частота канала C (младший байт) |
| 5 | Частота канала C (старшие 4 бита) |
| 6 | Период шума |
| 7 | Микшер (включение каналов и шума) |
| 8 | Громкость A |
| 9 | Громкость B |
| 10 | Громкость C |
| 11 | Период огибающей (младший байт) |
| 12 | Период огибающей (старшие 8 бит) |
| 13 | Форма огибающей |
| 14 | Порт I/O A (не используется на Sprinter) |
| 15 | Порт I/O B (не используется на Sprinter) |
**Стерео:** AY имеет два выходных канала, но в стандартной конфигурации
Sprinter оба канала получают монофонический сигнал.
---
## 10.3 COVOX (8-бит)
### 10.3.1 Порты
| Порт | Назначение |
|------|-----------|
| `#FB` | COVOX data (он же порт включения КЭШ-ОЗУ по IN) |
| `#4F` | COVOX data (альтернативный адрес) |
[IvanMak.txt:642, 1347]
### 10.3.2 Программирование
Простейший вывод сэмплов — последовательная запись байтов в порт `#FB`
или `#4F`:
```asm
; Цикл вывода сэмплов (8 бит, моно)
LD HL, sample_data
LD BC, sample_length
loop:
LD A, (HL)
OUT (#FB), A
INC HL
DEC BC
LD A, B
OR C
JR NZ, loop
```
### 10.3.3 Конфликт с Fast RAM (КЭШ-ОЗУ)
Порт `#FB` используется **для двух целей**:
- `OUT (#FB), A` — запись в COVOX
- `IN A, (#FB)` — включение КЭШ-ОЗУ
Если КЭШ-ОЗУ включено, запись в `#FB` уходит в кэш, а не в COVOX.
Перед работой с COVOX кэш нужно отключать: `IN A, (#7B)`
[IvanMak.txt:850851], [12-bugs.md §11.4].
---
## 10.4 COVOX-Blaster (CBL)
### 10.4.1 Общее описание
**CBL (COVOX-Blaster)** — COVOX с буферным ОЗУ на **256 байт**. Позволяет
выводить звук поблочно, освобождая процессор для другой работы
[IvanMak.txt:647], [Parinov.txt:688].
### 10.4.2 Порт управления `#4E`
**Порт `#4E` — 16-битный! Только через `OUT (C),A`** (с `LD BC,004Eh`)
[Parinov.txt:692693].
> **Примечание:** IvanMak.txt упоминает его как 8-битный, но Parinov.txt явно
> указывает 16-битный доступ. Современный код использует `OUT (C),A`.
**Биты порта `#4E`** [Parinov.txt:695698]:
| Бит | Мнемоника | Назначение |
|-----|-----------|-----------|
| 7 | **CBL_ON** | 1 = CBL включён, 0 = обычный COVOX |
| 6 | **STEREO** | 1 = стерео, 0 = моно |
| 5 | **16BIT** | 1 = 16-битные сэмплы, 0 = 8-битные |
| 4 | **IRQ_EN** | 1 = включить прерывания от CBL |
| 30 | **FREQ** | Частота дискретизации (см. таблицу) |
### 10.4.3 Частоты дискретизации
[Parinov.txt:700718]:
| Код | Частота | Примечание |
|:---:|---------|-----------|
| 0 | 16 kHz | старые режимы, **НЕ ИСПОЛЬЗОВАТЬ** |
| 1 | 22 kHz | старые режимы, **НЕ ИСПОЛЬЗОВАТЬ** |
| 2–7 | — | зарезервировано |
| **8** | **7.8125 kHz** | mono/stereo, 8/16-bit |
| **9** | **10.9375 kHz** | mono/stereo, 8/16-bit |
| **A** | **15.625 kHz** | mono/stereo, 8/16-bit |
| **B** | **21.875 kHz** | mono/stereo, 8/16-bit |
| **C** | **31.25 kHz** | mono/stereo, 8/16-bit |
| **D** | **43.75 kHz** | mono/stereo, 8/16-bit |
| **E** | **54.6875 kHz** | mono/stereo, 8/16-bit |
| **F** | **109.375 kHz** | mono/stereo, 8/16-bit |
> **Важно:** коды 0 и 1 — старые режимы из первых прошивок, несовместимы с
> новыми режимами (8–F). Использовать только коды 8–F.
### 10.4.4 Режимы и формат данных
[Parinov.txt:767783]:
| Режим | Нулевой уровень | Размер блока | Формат данных |
|-------|:---------------:|:------------:|--------------|
| mono 8-bit | `80h` | 128 байт | `DB 80h, 81h, 7Fh, ...` |
| mono 16-bit | `0000h` | 256 байт | `DW 0, 1000, -1000, ...` |
| stereo 8-bit | `80h,80h` | 128 байт | `DB 80h,80h, 81h,80h, ...` (L, R чередуются) |
| stereo 16-bit | `0000h,0000h` | 256 байт | `DW 0,0, 1000,0, ...` (L, R чередуются) |
Формат данных выбран так, чтобы WAV-файлы можно было пересылать в CBL
простой `OTIR` [Parinov.txt:791].
### 10.4.5 Буфер CBL и механизм банок
CBL имеет буферное ОЗУ на **256 байт**, организованное как кольцевой буфер
[Parinov.txt:758760]:
- Счётчик CBL считает **«назад»** — из-за особенности команды `OUTI`, где `B`
уменьшается и попадает на A15..A8.
- Для 8-битных режимов буфер условно разбит на **две банки по 128 байт**.
- Для 16-битного режима блок = **256 байт** (весь буфер).
**Механизм работы:**
1. Процессор записывает блок данных (128 байт для 8-бит, 256 байт для 16-бит)
в буфер CBL.
2. Аппаратный счётчик CBL автоматически считывает данные из буфера и
отправляет в ЦАП на заданной частоте.
3. Бит 7 порта `#FE` указывает, какая банка сейчас выводится в ЦАП.
4. Когда банка переключается — CBL запрашивает следующую порцию данных
(через прерывание или polling).
5. Запрос данных возникает для **каждых 128 байт (256 в 16-битном режиме)**.
### 10.4.6 Порт статуса `#FE`
**Бит 7 порта `#FE`** — запрос данных для CBL [Parinov.txt:720724]:
| Бит | Назначение |
|-----|-----------|
| 7 | **CBL data request** — 1 = CBL запрашивает новую порцию данных |
| 5 | **Frame sync** — кадровый импульс (4 мс длиной, 20 мс период) |
> **Примечание:** В MAME при выключенном CBL бит 7 порта #FE всегда = 1.
> Это следует учитывать при разработке обработчика прерываний
> [`im2_isr_design.md:2631`].
**Противоречие** [08-io.md §8.3]:
- IvanMak.txt описывает бит 7 как старший бит счётчика CBL для polling
(определение, какая половина буфера выводится).
- Parinov.txt описывает его как запрос прерывания.
- Оба описывают одну физическую линию, но в разных режимах (polling vs interrupt).
### 10.4.7 Прерывания и IM2
- При включённых прерываниях CBL (бит 4 порта `#4E` = 1) необходим **режим IM 2**.
- Если остаться на IM1, DOS-процедура прерываний будет вызываться слишком часто,
что вызовет тормоза на высоких частотах [Parinov.txt:762764].
- **Вектор прерывания CBL — `#FF`** (как и у клавиатуры, и у кадрового).
Отличать — по биту 7 порта `#FE` [`sprinterIntLib.asm:2426`].
**Обработчик прерываний на IM2:**
```asm
; Проверка источника
IN A, (#FE)
RLCA ; бит 7 → CF
JR NC, not_cbl ; не CBL — на другой обработчик
; CBL запрашивает данные
LD BC, 804Fh ; B = 128 (счётчик), C = 4Fh (порт CBL data)
LD HL, next_block
OTIR ; вывести 128 байт в буфер CBL
...
```
### 10.4.8 Запись данных в CBL
**Способ 1: OTIR/OUTI через порт `#4F`**
```asm
LD BC, 804Fh ; B = 128 (счётчик), C = #4F (CBL data)
LD HL, data_block
OTIR ; вывести 128 байт
```
**Способ 2: через страницу ОЗУ `#FD` с акселератором**
Страница `#FD`, отображённая в окно `#C000`, аппаратно связана с буфером CBL.
Для 8-битного режима — записать 128 байт; для 16-битного — 256 байт
[Parinov.txt:727731].
```asm
; Запись блока данных в CBL через страницу #FD с акселератором
IN A, (#E2) ; сохранить текущую страницу W3
LD (.save_page), A
LD A, #FD
OUT (#E2), A ; W3 = страница CBL
LD DE, #C000 ; приёмник (CBL buffer)
LD B, 0 ; B = 0 → 256 байт (или 128 для 8-bit)
LD D,D ; ACC_ON: включить акселератор
LD L,L ; ACC_CopyBlock_Horizontal
LD A, (HL) ; загрузить байт в буфер акселератора
LD (DE), A ; записать в CBL
LD B,B ; ACC_OFF: выключить акселератор
LD A, (.save_page)
OUT (#E2), A ; восстановить страницу
```
### 10.4.9 Полный пример
Из `docs/samples/Пример для CBL.asm` [sprinterIntLib.asm]:
```asm
; Инициализация IM2
LD A, #BE
LD I, A ; таблица векторов по #BE00
IM 2
; Вектор прерывания CBL = #BEFF
; (Interrupt_Vector OR 0FFh)
; Включение CBL
LD BC, #4E
LD A, %10011000b ; bit7=1 CBL on, bit4=1 IRQ en, bits3-0=1000 = 7.8125 kHz
OUT (C), A
; В ISR:
; IN A, (#FE)
; RLCA
; JR NC, .NoSound
; ... копировать 128 байт через страницу #FD с акселератором
; После проигрывания:
; Установить NumberPage=2, подождать HALT
; Выключение CBL:
LD BC, #4E
LD A, 0
OUT (C), A
```
### 10.4.10 Известные проблемы
1. **CBL vs Fast RAM:** порт `#FB` используется и для COVOX/CBL, и для
включения КЭШ-ОЗУ (см. §10.3.3).
2. **Щелчок перед первым звуком:** известная проблема при старте CBL
[`TODO.md:263`].
3. **Помехи при движении мыши:** часть тиков прерываний, обслуживающих
CBL-насос, уходит на обслуживание мыши [`TODO.md:270277`].
4. **Порт #4E — 8-бит vs 16-бит:** IvanMak подразумевает 8-битный,
Parinov требует 16-битный `OUT (C),A` (см. §10.4.2).
5. **MAME: бит 7 порта #FE = 1 при выключенном CBL:** может вызвать
ложные срабатывания обработчика (см. §10.4.6).
---
## 10.5 Бипер
Стандартный Spectrum-бипер — бит 3 (в некоторых конфигурациях бит 5)
порта `#FE`. Выведен через ту же схему TDA1543, что COVOX и AY
[IvanMak.txt:639640].
```asm
; Включить бипер
LD A, %00001000 ; бит 3 = 1
OUT (#FE), A
; Выключить бипер
LD A, %00000000 ; бит 3 = 0
OUT (#FE), A
```
---
## 10.6 SSC (Sprinter Sound Card)
Разрабатывалась, но **не реализована** ни в одной прошивке Sp2000
из-за большого объёма ПЛМ [IvanMak.txt:763772].
Параметры проекта:
- 2 канала
- 16 восьмибитных голосов
- 256-байтные Wave-таблицы для каждого голоса
- 8-битный регулятор амплитуды
---
## 10.7 Кросс-ссылки
- Порты звука: `11-ports.md`
- Баги AY и CBL: `12-bugs.md`
- Fast RAM и конфликт с COVOX: `04-memory.md §4.6`
- 08-io.md (остальной ввод-вывод): `08-io.md`
+103
View File
@@ -0,0 +1,103 @@
# 11. Карта портов
## 11.1 Системные порты Z84C15 (внутренние)
Эти адреса изменить невозможно — находятся вне ППЛМ [IvanMak.txt:869870].
| Порт | Назначение | Доступ |
|------|-----------|--------|
| `#10` | SIO A data / CTC channel 0 | R/W |
| `#11` | SIO A control / CTC channel 1 | R/W |
| `#12` | SIO B data / CTC channel 2 | R/W |
| `#13` | SIO B control / CTC channel 3 | R/W |
| `#14` | PIO A data | R/W |
| `#15` | PIO A control | R/W |
| `#16` | PIO B data | R/W |
| `#17` | PIO B control | R/W |
| `#18` | SIO data channel A (клавиатура) | R/W |
| `#19` | SIO control channel A (статус клавиатуры) | R/W |
| `#1A` | SIO data channel B (мышь) | R/W |
| `#1B` | SIO control channel B (мышь) | R/W |
| `#1E` | PIO B бит 0 — IRQ от ISA | R |
| `#1F` | PIO B + джойстик (Kempston) | R/W |
| `#EE` | CTC channel 2 (альтернативный) | R/W |
| `#EF` | CTC channel 3 (альтернативный) | R/W |
| `#F0` | CTC channel 0 (альтернативный) | R/W |
| `#F1` | CTC channel 1 (альтернативный) | R/W |
| `#F4` | CTC — альтернативный доступ | |
## 11.2 Управление памятью
| Порт | Назначение | Источник |
|------|-----------|----------|
| `#7FFD` | Основной: W3 page (02), RAM/ROM select, lock | IvanMak.txt:1343 |
| `#1FFD` | Расширенный: W0 page (02), turbo, extended RAM, VRAM segment | IvanMak.txt:1345 |
| `#DFFD` | W1 page select (Pentagon-512) | IvanMak.txt:1346 |
| `#EFF7` | W2 page select (Pentagon-512) | IvanMak.txt:1346 |
| `#82` | W0 page (PAGE0) — всегда доступен | IvanMak.txt:1348 |
| `#A2` | W1 page (PAGE1) — всегда доступен | IvanMak.txt:1348 |
| `#C2` | W2 page (PAGE2) — всегда доступен | IvanMak.txt:1348 |
| `#E2` | W3 page (PAGE3) — всегда доступен | IvanMak.txt:1348 |
## 11.3 Видео
| Порт | Назначение | Источник |
|------|-----------|----------|
| `#89` | RGADR (PORT_Y) — номер строки/блока видео-ОЗУ | IvanMak.txt:1349 |
| `#C9` | RGMOD — страница режима экрана (бит 0: 0/1) | IvanMak.txt:1350 |
## 11.4 Управление конфигурацией/прошивкой
| Порт | Назначение | Источник |
|------|-----------|----------|
| `#FB` | Включение КЭШ-ОЗУ (IN), COVOX data | IvanMak.txt:1351 |
| `#7B` | Выключение КЭШ-ОЗУ (IN) | Parinov.txt:598 |
## 11.5 Дисковая подсистема
| Порт | Назначение | Источник |
|------|-----------|----------|
| `#0F` | ВГ93 Command/Status (после ремапинга #1F#0F) | IvanMak.txt:1270 |
| `#1F` | ВГ93 Command/Status (оригинал, ремапится) | IvanMak.txt:1344 |
| `#3F` | ВГ93 Track register | IvanMak.txt:1271 |
| `#5F` | ВГ93 Sector register | IvanMak.txt:1272 |
| `#7F` | ВГ93 Data register | IvanMak.txt:1273 |
| `#FF` | ВГ93 Drive Control (write); IRQ/джойстик (read) | IvanMak.txt:1274 |
| `#BD` | Переключение режима FDD (720K/1.44M) | IvanMak.txt:1347 |
| `xx50` | IDE Data | Parinov.txt:958 |
| `xx51` | IDE Error/Features | Parinov.txt:958 |
| `xx52` | IDE Sector Count | Parinov.txt:958 |
| `xx53` | IDE Sector Number | Parinov.txt:958 |
| `xx54` | IDE Cylinder Low | Parinov.txt:958 |
| `xx55` | IDE Cylinder High | Parinov.txt:958 |
| `4052h` (R) / `4152h` (W) | IDE Device/Head | Parinov.txt:959 |
| `4053h` (R) / `4153h` (W) | IDE Status/Command | Parinov.txt:959 |
| `FFBD` | CMOS data read | BIOS_v3.txt:308 |
| `BFBD` | CMOS data write | BIOS_v3.txt:308 |
| `DFBD` | CMOS address write | BIOS_v3.txt:308 |
## 11.6 Звук
| Порт | Назначение | Источник |
|------|-----------|----------|
| `#FB` | COVOX data (also КЭШ-ОЗУ enable) | IvanMak.txt:642 |
| `#4F` | COVOX/CBL data | IvanMak.txt:642 |
| `#4E` | CBL control (8/16-bit — см. `10-sound.md §9.4.2`) | IvanMak.txt:662, Parinov.txt:692 |
## 11.7 Джойстик и системные
| Порт | Назначение | Источник |
|------|-----------|----------|
| `#FE` | ZX-клавиатурная матрица, бипер, CBL статус | IvanMak.txt:1344 |
| `#1F` | Джойстик (Kempston) / PIO B | IvanMak.txt:1344 |
## 11.8 Кросс-ссылки
- BIOS-функции: `02-bios.md`
- DSS-функции: `03-dss.md`
- Управление памятью: `04-memory.md`
- Звук (AY, COVOX, CBL): `10-sound.md`
- Видео/палитра: `05-graphics.md`
- Прерывания: `07-irq.md`
- Детали I/O: `08-io.md`
- Баги: `12-bugs.md`
+54
View File
@@ -0,0 +1,54 @@
# 12. Баги BIOS, DSS и железа Sp2000
## 12.1 DRV_VERIFY (54h) не существует
Функция `54h DRV_VERIFY` описана во всей документации BIOS, но в реальности отсутствует — всегда возвращает CF=1.
> [bugs.txt:5859]: «Нет биосной функции "54h" (DRV_VERIFY) верификации секторов, описанной в документации. Поэтому она всегда возвращает установленный флаг "Carry".»
Источники, содержащие описание несуществующей функции:
- [BIOS_v3.txt:258261]
- [IvanMak.txt:21982210]
## 12.2 AY-3-8910 — ошибка в формирователе огибающей
Третья версия AY в ППЛМ Sp2000 содержит ошибку в схеме формирователя огибающей (envelope generator). Детали не документированы.
> [IvanMak.txt:224229]: «Третья версия схемы AY ... включает в себя ... генератор огибающей. ... В схеме формирователя огибающей обнаружена небольшая ошибка. ... В следующей версии AY предполагается данный недостаток исключить.»
## 12.3 Акселератор — конфликт с прерываниями
При работе акселератора система команд Z80 сильно меняется, что может приводить к сбоям в обработчиках прерываний.
> [IvanMak.txt:844846]: «Отключение прерываний во время работы акселератора необходимо, так как в этот момент сильно меняется система команд процессора и программа на прерывании не сможет работать нормально.»
Новая прошивка акселератора позволяет работать с прерываниями — при приходе INT акселератор отключается и включается обратно по RETI [IvanMak.txt:846848]. Без тестирования на реальном железе неизвестно, какая версия прошивки установлена.
## 12.4 Быстрое ОЗУ — конфликт с COVOX
Порт `#FB` используется как для включения КЭШ-ОЗУ (IN), так и для вывода данных в COVOX (OUT). Если КЭШ-ОЗУ включено, запись в COVOX может давать неожиданные результаты.
> [IvanMak.txt:850851, 642]
Перед вызовом RST или выходом в DOS КЭШ-ОЗУ обязательно отключать (`IN A,(#7B)`).
## 12.5 STA_VID — потеря старшего байта (0A8h?)
> [bugs.txt:33]: «В БИОСе в функции STA_VID (возможно 0A8h) теряется старший байт параметра. В v2.12 функцию рекомендуется вызывать с учетом этого.»
Относится к BIOS v2.12. Не проверялось, исправлено ли в v3.00.
## 12.6 Несовместимость с реальным железом — только MAME
Многие перечисленные баги и квирки зафиксированы в документации, но не подтверждены на реальном Sprinter Sp2000. Все тесты тулчейна выполняются в MAME. Актуальность багов для реального железа неизвестна.
> [TODO.md]: «Проверка на реальном железе — в планах»
## 12.7 Кросс-ссылки
- BIOS v3.00: `02-bios.md`
- DSS/ESTEX: `03-dss.md`
- Акселератор: `06-accel.md`
- Fast RAM: `04-memory.md §4.6`
- Проектный TODO: `TODO.md`
- Проектный список багов: `converted/bugs.txt`
+169
View File
@@ -0,0 +1,169 @@
# 13. Информация из Telegram-чатов (Sp2022 и развитие Sprinter)
## 13.1 Источники
Данные извлечены из 319 HTML-файлов чатов Telegram, выгруженных из чата по Sprinter (n/w). Обработано 317 602 сообщения, отфильтровано технических — 72 307 (15 МБ текста).
Основные авторы технических сообщений: RomanRom2, KromosS, solegstar, nzeemin, holub.
## 13.2 BIOS 3.06 / DSS 1.71.57
KromosS (23 января 2026): «I am running the DSS 1.71.57 / Bios 3.06».
Зафиксированные версии BIOS:
- 3.05 — предыдущая стабильная
- 3.06 — текущая, 23.01.2026
- Прошивка ППЛМ и ROM собираются через Intel Quartus
BIOS 3.06 собрана из ROM-файла, загружаемого через загрузчик. Процесс сборки:
1. Конфигурация ППЛМ через Quartus
2. Сборка ROM-образа (IS28F020 — 256 КБ flash)
3. Программирование через специальный загрузчик
## 13.3 Эволюция аппаратных платформ
RomanRom2 (11 ноября 2025) подробно описал историю развития Sprinter в 10 пунктах:
| Этап | Платформа | Описание | Период |
|------|-----------|----------|--------|
| 1 | Sp2000 | Оригинальная плата, 8 DIP VRAM | 20002001 |
| 2 | Sp2000s | Баг в разводке ALTERA: ISA зеркалированы | ~2001 |
| 3 | Sp2000s Light | Баг фикс с MGTF, ISA распаяны не полностью | ~2002 |
| 4 | Sp2021s | Новая ревизия от solegstar | ~2021 |
| 5 | Sp2022s/d | Собственный дизайн (Zeal Hardware / RomanRom2) | 2022 |
| 6+ | Sp2024d/du | Планируется, с USB-контроллером | ~2024 |
### Детали:
**Sp2000 (оригинал)**
- Плата 2000–2001 года
- ПЗУ 256 КБ, VRAM 256 КБ (8 DIP-микросхем)
- ALTERA ACEX 1K EP1K30
**Sp2000s**
- ALTERA-баг: в оригинальной плате зеркально разведены ISA-слоты, на Sp2000s исправлено
- Новый баг разводки: ISA адреса «перевёрнуты» — при устанавке платы в слот слоты просто не видятся. В Sp2000s Light фикс с MGTF (соединительная плата), один ISA-слот не распаян
**Sp2022 (Zeal Hardware)**
- Новая разработка на современной элементной базе
- Варианты: Sp2022s (Sp2000 layout, SMD), Sp2022d (две платы, digitized)
- SMD-компоненты, технология 2022 года
- Расширенная память, улучшенное питание
- Sp2022du — вариант с USB-контроллером (планируется для Sp2024)
**Sp2024**
- Sp2024d — следующее поколение
- Sp2024du — с интегрированным USB для клавиатуры/мыши
- Планируется USB-контроллер
### Sp2022 — модификации
| Модификация | Описание |
|-------------|----------|
| sp2022s | SMD, layout аналогичен Sp2000 |
| sp2022d | Две платы (digitized), расширенная память |
| sp2022d-black | Чёрная текстолит |
| sp2022release | Готовая плата для пользователей |
| sp2022m | Мобильная версия (будущее) |
| sp2022i | ITX-формфактор |
| sp2022atx | ATX-формфактор |
| sp2022t | Новая ревизия |
| sp2022du | С USB-контроллером |
## 13.4 Изменения компонентов
### ПЗУ и загрузка
- ROM: IS28F020 (256 КБ Flash, 5V)
- Загрузка через Quartus → ROM-образ → загрузчик
- ROM-файлы обсуждаются в чате
### VRAM
- Оригинал Sp2000: CY7C109D-10VXI (5V, 128K×8)
- Sp2022: CY7C1019DV33-10VXI (3.3V, 128K×8)
- Переход на 3.3V логику
### Video-DAC
- Sp2022: обсуждаются TDA8772 (трипл 8-бит video-DAC) или ADV7120/ADV7125
- Некоторые платы используют ADV7125 (трипл 10-бит) ???
### CMOS
- DS12887A (оригинал)
- На Sp2022 — замена на современный аналог
### КЭШ-ОЗУ
- W24512 (64K×8) — для Sp2022
### SDRAM
- Оригинал: 72-pin SIMM
- Sp2022: SDRAM (DDR) на плате
## 13.5 Аппаратные баги
### Sp2000s — ALTERA routing bug
При переразводке Sp2000 под Sp2000s допущена ошибка в разводке ALTERA (ACEХ 1K). ISA-адреса оказались «зеркальными» — при установке платы в слот половинка линий данных перевёрнута, из-за чего слоты не видятся CPU. Исправлено на Sp2000s Light с помощью MGTF (мезонинная плата-переходник).
### Sp2000s Light — ISA unsoldered
На Sp2000s Light один ISA-слот не распаян, второй — через MGTF.
### IDE active short
В некоторых ревизиях — короткое замыкание на линиях IDE при активном доступе. Требует подтягивающих резисторов.
### FDISK CHS-LBA
Типовые проблемы с разметкой дисков — ошибки пересчёта CHS в LBA в утилитах FDISK для Sprinter.
## 13.6 MAME-эмуляция
- holub разрабатывает форк MAME для Sprinter
- Timing issues: Z80 Z84C15 эмулируется не полностью (внутренние PIO/SIO/CTC)
- Работа над корректной эмуляцией Sp2022
## 13.7 Статистика по платформам
| Платформа | Упоминаний | Период |
|-----------|-----------|--------|
| sp2000 | 243 | 20002001 |
| sp2022 | 122 | 20222024 |
| sp2022d | 66 | 20222024 |
| sp2000s | 44 | 20012002 |
| sp2022s | 43 | 20222024 |
| sp2024d | 6 | 2024+ |
| sp2024du | 4 | 2024+ (план) |
| sp2022i | 3 | 20222024 |
| sp2022m | 1 | будущее |
## 13.8 Компонентная статистика
| Компонент | Упоминаний |
|-----------|-----------|
| Z80 | 1317 |
| USB | 800 |
| BIOS v3.xx | 813 |
| MAME | 496 |
| DDR | 172 |
| ACEX | 147 |
| ALTERA | 115 |
| CY7C | 82 |
| Z84C15 | 87 |
| TDA1543 | 55 |
| SDRAM | 48 |
| IS28F020 | 30+ |
| Quartus | упоминается |
## 13.9 Противоречия с docs/new/
### BIOS v3.06 / DSS 1.71.57
Основные источники (BIOS_v3.txt, IvanMak.txt) документируют BIOS 3.00, не 3.06. Версия 3.06 обнаружена только в Telegram. DSS 1.71.57 значительно новее, чем 1.60 в документации.
### Sp2022 — новое железо
Вся документация в docs/converted/, part2/ и reference/ описывает Sp2000 (20002001). Sp2022 — полностью новая платформа с современной элементной базой (SMD, 3.3V VRAM, USB, SDRAM). Документация отсутствует.
### Состав BIOS
Неизвестно, какие функции из IvanMak.txt (HDD, RAM-disk, конфигурационные, портовые) реализованы в BIOS 3.06, а какие нет. Также неизвестно, исправлены ли баги (DRV_VERIFY, AY envelope).
## 13.10 Кросс-ссылки
- Аппаратная архитектура Sp2000: `01-architecture.md`
- BIOS v3.00: `02-bios.md`
- Проектный TODO: `TODO.md`
- Сырые данные: `docs/tg/_messages.jsonl`, `docs/tg/_technical.txt`
- Фильтр: `docs/tg/_filter.py`
+112
View File
@@ -0,0 +1,112 @@
# INDEX — сводный указатель документации Sp2000
## Документы
| № | Файл | Содержание |
|---|------|-----------|
| 01 | `01-architecture.md` | Общая архитектура: процессор, ППЛМ, конфигурации, обзор памяти/видео/акселератора/звука/ISA/клавиатуры/мыши/дисков/прерываний |
| 02 | `02-bios.md` | BIOS v3.00: вызовы (RST 8/18h, CALL 3D13h), полная таблица функций, видео/палитра/диск/принтер |
| 03 | `03-dss.md` | DSS/ESTEX v1.60: файловые функции, диски, память, консоль, коды ошибок |
| 04 | `04-memory.md` | Память: 4 окна, страницы, порты (#7FFD/#1FFD/#DFFD/#EFF7), EXE-формат, Fast RAM |
| 05 | `05-graphics.md` | Графика: VRAM, адресация (спектрумовская/графическая), видеорежимы, палитра, shadow RAM |
| 06 | `06-accel.md` | Акселератор: команды, примеры, скорость, прерывания |
| 07 | `07-irq.md` | Прерывания: IM1/IM2, INT, CTC, SIO, CBL, цепочка обработчиков |
| 08 | `08-io.md` | Ввод-вывод: FDD, HDD, CMOS, джойстик, принтер, ISA, карта портов |
| 09 | `09-input.md` | Клавиатура (BIOS/DSS/raw) и мышь (RST 30h): API, протоколы, прерывания |
| 10 | `10-sound.md` | Звук: AY-3-8910, COVOX, COVOX-Blaster (CBL), бипер, SSC |
| 11 | `11-ports.md` | Сводная карта портов: Z84C15, память, видео, диски, звук, конфигурация |
| 12 | `12-bugs.md` | Баги: DRV_VERIFY, AY envelope, акселератор+IRQ, Fast RAM+COVOX |
| 13 | `13-telegram.md` | Telegram-чаты: BIOS 3.06, эволюция Sp2000→Sp2022, Sp2022 варианты, Sp2024, аппаратные баги, MAME |
## Противоречия — сводка
### Критические (меняют ABI)
| Тема | Файл | Источники |
|------|------|-----------|
| SETWIN2: 39h vs 3Ah | `03-dss.md` | DiskSyscalls.txt vs ProgrammerManual.txt |
| EXCMDLN subfunc 5: смещения | `03-dss.md` | Все источники дают неверные DE+3/DE+4 |
### Средние
| Тема | Файл | Источники |
|------|------|-----------|
| WIN_RESTORE_WIN: C=0B2h (опечатка) | `02-bios.md` | BIOS_v3.txt vs IvanMak.txt |
| WIN_MOVE_WIN: C=0B2h (опечатка) | `02-bios.md` | IvanMak.txt vs BIOS_v3.txt |
| WIN_GET_SYM: A=0 обязательно? | `02-bios.md` | Parinov.txt vs BIOS_v3.txt |
| PIC_SET_PAL: битфилд vs номер | `02-bios.md` | BIOS_v3.txt vs IvanMak.txt |
| LP_PRINT_SYM: 082h=(131) неверно | `02-bios.md` | Ошибка десятичной аннотации |
| FN_VERSION: значения BC | `02-bios.md` | BIOS_v3.txt vs IvanMak.txt |
### Низкие
| Тема | Файл | Источники |
|------|------|-----------|
| CBL порт 8/16-бит | `10-sound.md` | IvanMak vs Parinov |
| CBL bit7 #FE: статус vs IRQ | `10-sound.md` | IvanMak vs Parinov |
| Адресация ВГ93: #7F data reg | `08-io.md` | IvanMak vs Parinov; MAME подтверждает IvanMak |
| HDD: R/W разные адреса | `08-io.md` | IvanMak vs Parinov; MAME использует единую карту DCP |
| Джойстик #1F vs #0F | `08-io.md` | IvanMak: ремап #1F#0F; MAME на Sp2000 отключает |
## Кросс-ссылки между документами
```
01-architecture.md ← 02-bios.md (BIOS call conventions)
← 04-memory.md (memory overview)
← 05-graphics.md (video overview)
← 06-accel.md (accel overview)
← 07-irq.md (interrupt overview)
← 08-io.md (disk, joystick, printer, ISA overview)
← 09-input.md (keyboard, mouse overview)
← 10-sound.md (sound overview)
← 11-ports.md (ISA ports)
02-bios.md ← 05-graphics.md (PIC_SET_PAL, SET_MODE)
← 11-ports.md
← 12-bugs.md (DRV_VERIFY)
03-dss.md ← 04-memory.md (SETWIN/SETWIN1/SETWIN2)
← 11-ports.md
← 12-bugs.md
04-memory.md ← 06-accel.md (Fast RAM conflict with accel)
← 11-ports.md
← 03-dss.md (window functions)
05-graphics.md ← 02-bios.md (PIC_SET_PAL, SETVMOD)
← 06-accel.md (accelerator for fast pixel ops)
← 10-sound.md (CBL for video)
← 11-ports.md (RGADR, RGMOD)
07-irq.md ← 10-sound.md (CBL interrupt sources)
← 11-ports.md
← 08-io.md (disk I/O interrupt sources)
← 09-input.md (keyboard, mouse interrupt sources)
08-io.md ← 02-bios.md (printer functions)
← 09-input.md (keyboard, mouse moved here)
← 10-sound.md
← 11-ports.md
← 07-irq.md (mouse IRQ)
11-ports.md → все документы
```
## Проектные документы (не входят в docs/new/)
| Файл | Связь |
|------|-------|
| `memory-management.md` | C-specific memory models (legacy, перекрывается `04-memory.md`) |
| `fast_ram.md` | Детальный анализ Fast RAM — уточняет `04-memory.md §4.6` |
| `file-buffering-design.md` | FILE* дизайн — уточняет `03-dss.md` |
| `im2_isr_design.md` | IM2/ISR дизайн — уточняет `07-irq.md` |
| `sprite-api-design.md` | Спрайтовое расширение BGI |
| `kbd-games.md` | Клавиатура в играх — уточняет `09-input.md §9.5` |
| `libc-reference.md` | API libc |
| `libc-roadmap.md` | План работ по libc |
| `libc-split-asm-cases.md` | Правила сплита asm |
| `libc-headers.md` | Стратегия заголовков |
| `accel-fill-budget.md` | Бюджет тактов акселератора |
| `TODO.md` | Roadmap проекта |
| `bugs/` | Баг-репорт SDCC z80 |
Binary file not shown.
Binary file not shown.
+9 -3
View File
@@ -46,10 +46,16 @@ void gfx_scroll_h(const gfx_rect_t *area, int16_t dx, gfx_rect_t *dirty) {
* DI/EI-банды по 16 строк leaf делает сам (h: 0=256). Между бандами по * DI/EI-банды по 16 строк leaf делает сам (h: 0=256). Между бандами по
* ширине CPU-адрес двигаем на 256 (Port_Y выбирает строку). */ * ширине CPU-адрес двигаем на 256 (Port_Y выбирает строку). */
while (w) { while (w) {
uint8_t cw = (w > 256) ? 256 : (uint8_t)w; /* 0 => 256 */ // Закомментированный блок должен работать правильно но не работает
// почему-то при w > 256 второй проход мусорит
// TODO: разобраться
// uint8_t cw = (w > 256) ? 256 : (uint8_t)w; /* 0 => 256 */
// _bgi_scroll_rows_raw(src, dst, cw, h, (uint8_t)area->y);
// src += 256; dst += 256;
// w -= (w > 256) ? 256 : w;
uint8_t cw = (w > 255) ? 255 : (uint8_t)w; /* 0 => 256 */
_bgi_scroll_rows_raw(src, dst, cw, h, (uint8_t)area->y); _bgi_scroll_rows_raw(src, dst, cw, h, (uint8_t)area->y);
src += 256; dst += 256; src += cw; dst += cw; w -= cw;
w -= (w > 256) ? 256 : w;
} }
_bgi_end(); _bgi_end();