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>
This commit is contained in:
@@ -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: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].
|
||||
|
||||
Для записи в определённую пару спектрумовских блоков:
|
||||
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: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].
|
||||
|
||||
**Работа с адресацией из программы:**
|
||||
|
||||
```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: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 нет,
|
||||
чтение/запись идут напрямую в основное ОЗУ.
|
||||
|
||||
**Зачем это нужно:**
|
||||
|
||||
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: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`
|
||||
Reference in New Issue
Block a user