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:
2026-07-29 18:26:31 +03:00
parent 1214785a56
commit 64ce6339eb
32 changed files with 23762 additions and 3 deletions
+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`