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,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:810–848].
|
||||
|
||||
| Инструкция | Код | Действие |
|
||||
|-----------|:---:|----------|
|
||||
| `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:822–823], [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:840–843]:
|
||||
|
||||
```
|
||||
Время ≈ время команды без акселератора + число_байт / 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:844–846].
|
||||
|
||||
**Новая прошивка:** акселератор может работать с EI. По приходу прерывания
|
||||
он отключается, а по `RETI` включается обратно [IvanMak.txt:846–848].
|
||||
Использовать этот режим следует с осторожностью — без проверки на реальном
|
||||
железе неизвестно, какая версия прошивки установлена.
|
||||
|
||||
---
|
||||
|
||||
## 6.7 Кросс-ссылки
|
||||
|
||||
- Баги акселератора: `12-bugs.md`
|
||||
- Использование акселератора в libbgi: `sprite-api-design.md`
|
||||
- Ограничение скорости: `accel-fill-budget.md`
|
||||
- Fast RAM и конфликт с портом CBL: `04-memory.md §4.6`
|
||||
Reference in New Issue
Block a user