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

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

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

222 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`