- 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>
16 KiB
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:317–322].
5.2 Режимы адресации видео-ОЗУ
Видео-ОЗУ может адресоваться двумя способами — спектрумовским и графическим [IvanMak.txt:296–300]. Спектрумовский режим используется для 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:333–339].
Для записи в определённую пару спектрумовских блоков:
- Записать номер блока в
RGADR(OUT (#89),A). - Убедиться, что в окне (
#4000или#C000) стоит подходящая страница основного ОЗУ (любая, кроме#50..#5F). - Чтение/запись по спектрумовским адресам (
#4000..#5FFF,#C000..#DFFF) попадает в VRAM через текущий блок.
Выключение спектрумовского вывода: Если программа не использует
Spectrum-совместимую графику, RGADR рекомендуется установить в #C0..#FF
(бит 6 = 1). В этом случае вывод в VRAM через спектрумовский режим не
производится [IvanMak.txt:346–348].
5.2.2 Графический режим адресации
В графическом режиме видео-ОЗУ организовано как матрица 256 строк (rows) × 1024 байта [IvanMak.txt:357–358]. Адресация:
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].
Работа с адресацией из программы:
; Установить страницу 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:364–386]:
| Бит | Страницы | Эффект |
|---|---|---|
| 3 | #58..#5F |
Прозрачный цвет — запись байта #FF игнорируется (для спрайтов) |
| 2 | #54..#57, #5C..#5F |
Без тени — запись только в VRAM, не в основное ОЗУ (для курсора мыши) |
Биты 0 и 1 должны быть 0 для совместимости с будущими прошивками [IvanMak.txt:384–386].
5.4 Теневая память (Shadow RAM) и двойная запись
Видео-ОЗУ Спринтера является теневой памятью по отношению к основному ОЗУ
[IvanMak.txt:317–322]. Видеоконтроллер всегда читает изображение из VRAM
для вывода на экран; основное ОЗУ в формировании изображения не участвует.
Однако при записи через графические банки #50..#5F поведение зависит от
выбранного подрежима:
- Банк
0x50(normal): запись идёт одновременно в VRAM и в соответствующую область основного ОЗУ. Чтение из того же Z80-адреса возвращает данные из основного ОЗУ, а не из VRAM — VRAM для процессора на чтение не видна. - Банк
0x54(noshadow): запись — только в VRAM, основное ОЗУ не изменяется. Чтение — из основного ОЗУ (там хранится «фон»). - Банк
0x58(transparent): как normal, но байт#FFне пишется. - Банк
0x5C(sprite): transparent + noshadow. - Обычные банки (не
#50..#5F): никакого доступа к VRAM нет, чтение/запись идут напрямую в основное ОЗУ.
Зачем это нужно:
- Восстановление после переключения видеорежима: данные в основном ОЗУ остаются нетронутыми, так что при возврате в графический режим экран можно восстановить без перерисовки [IvanMak.txt:325].
- Heal спрайтов (libbgi): фон, на который был выведен спрайт в банке
GFX_BANK_SPRITE(0x5C, без тени), остался в основном ОЗУ. После перемещения спрайта фон копируется из основного ОЗУ обратно в VRAM (операция heal), стирая спрайт. - Курсор мыши без сохранения/восстановления: временный вывод через
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:405–469].
Режимы вывода
| Режим | Разрешение | Цветов | Описание |
|---|---|---|---|
| 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:448–469].
Для переключения видеорежима из программ используется функция DSS SETVMOD
(50h) [DiskSyscalls.txt:345–349]:
| 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:540–568].
| Адреса | Палитра | Назначение |
|---|---|---|
#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:545–547]. Выбор палитры для каждого квадратика — через биты 7..6 байта Mode1 [BIOS_v3.txt:348].
Примечание: Architecture.txt упоминает всего 5 палитр (4 графические + 1 текстовая), но IvanMak описывает все 8: 4 графические (0–3) и 4 текстовые (4–7: бумага, символ, мерцание бумаги, мерцание символа) [IvanMak.txt:547–548, 561–568].
5.7 Структура VRAM в терминах BIOS
При использовании BIOS распределение VRAM [IvanMak.txt:387–404]:
| Адреса (линии) | Назначение |
|---|---|
#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