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

12 KiB
Raw Blame History

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)

; страница 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].

Заливка блока одним цветом

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 блока данных

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), что позволяет гибко разделять чтение и запись.

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) и повтор.

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