- 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>
16 KiB
10. Звук
10.1 Общие сведения
Документ описывает звуковую подсистему платы Sp2000 и более новых моделей. Информация о Sprinter-97 не рассматривается.
Звуковая подсистема Sprinter Sp2000 включает три компонента:
| Компонент | Тип | Описание |
|---|---|---|
| GM80C760 (AY-3-8910 совм.) | Музыкальный сопроцессор | 3 голоса + шум + огибающая, эмуляция в ППЛМ |
| COVOX | 8-битный ЦАП | Прямой вывод сэмплов через порт #FB/#4F |
| CBL (COVOX-Blaster) | COVOX с буфером | 256 байт буфера, прерывания, разные режимы |
Весь звук выводится через 16-битный ЦАП TDA1543 (двухканальный, стерео). Реально используется 10 бит для одновременного смешивания 8-bit COVOX и AY [IvanMak.txt:632–634].
На Sp2000 все три компонента присутствуют в основной прошивке ППЛМ.
CBL включается через порт #4E (бит 7 = 1). При выключенном CBL (бит 7 = 0)
работает обычный 8-bit COVOX [IvanMak.txt:662–666].
10.2 GM80C760 (AY-3-8910)
10.2.1 Реализация
AY-функция реализована на микросхеме GM80C760 (ППЛМ ALTERA EP1K30), AY-3-8910/8912 совместимая. Это не отдельная дискретная микросхема [IvanMak.txt:636–637].
На EP1K30 (Sp2000) реализована 3-я версия AY. Включает три голоса, шум и генератор огибающей (envelope). В формирователе огибающей обнаружена небольшая ошибка, детали не документированы [IvanMak.txt:224–229], [12-bugs.md §11.2].
10.2.2 Порты
| Порт | Назначение |
|---|---|
#BFFD |
AY-8910 — запись номера регистра (address) |
#FFFD |
AY-8910 — чтение/запись данных регистра (data) |
Внутренние номера в карте дешифратора ППЛМ: 90h (#BFFD), 91h (#FFFD)
[IvanMak.txt:1298–1299].
10.2.3 Программирование
Программирование — стандартное для AY-3-8910/8912 [IvanMak.txt:636–637]:
; Установить регистр AY
LD BC, #BFFD
OUT (C), A ; A = номер регистра (0..15)
LD BC, #FFFD
OUT (C), A ; A = значение
; Прочитать регистр AY (3-я версия)
LD BC, #BFFD
OUT (C), A ; A = номер регистра
LD BC, #FFFD
IN A, (C) ; читать данные
Регистры AY-3-8910 (стандартные):
| № | Назначение |
|---|---|
| 0 | Частота канала A (младший байт) |
| 1 | Частота канала A (старшие 4 бита) |
| 2 | Частота канала B (младший байт) |
| 3 | Частота канала B (старшие 4 бита) |
| 4 | Частота канала C (младший байт) |
| 5 | Частота канала C (старшие 4 бита) |
| 6 | Период шума |
| 7 | Микшер (включение каналов и шума) |
| 8 | Громкость A |
| 9 | Громкость B |
| 10 | Громкость C |
| 11 | Период огибающей (младший байт) |
| 12 | Период огибающей (старшие 8 бит) |
| 13 | Форма огибающей |
| 14 | Порт I/O A (не используется на Sprinter) |
| 15 | Порт I/O B (не используется на Sprinter) |
Стерео: AY имеет два выходных канала, но в стандартной конфигурации Sprinter оба канала получают монофонический сигнал.
10.3 COVOX (8-бит)
10.3.1 Порты
| Порт | Назначение |
|---|---|
#FB |
COVOX data (он же порт включения КЭШ-ОЗУ по IN) |
#4F |
COVOX data (альтернативный адрес) |
[IvanMak.txt:642, 1347]
10.3.2 Программирование
Простейший вывод сэмплов — последовательная запись байтов в порт #FB
или #4F:
; Цикл вывода сэмплов (8 бит, моно)
LD HL, sample_data
LD BC, sample_length
loop:
LD A, (HL)
OUT (#FB), A
INC HL
DEC BC
LD A, B
OR C
JR NZ, loop
10.3.3 Конфликт с Fast RAM (КЭШ-ОЗУ)
Порт #FB используется для двух целей:
OUT (#FB), A— запись в COVOXIN A, (#FB)— включение КЭШ-ОЗУ
Если КЭШ-ОЗУ включено, запись в #FB уходит в кэш, а не в COVOX.
Перед работой с COVOX кэш нужно отключать: IN A, (#7B)
[IvanMak.txt:850–851], [12-bugs.md §11.4].
10.4 COVOX-Blaster (CBL)
10.4.1 Общее описание
CBL (COVOX-Blaster) — COVOX с буферным ОЗУ на 256 байт. Позволяет выводить звук поблочно, освобождая процессор для другой работы [IvanMak.txt:647], [Parinov.txt:688].
10.4.2 Порт управления #4E
Порт #4E — 16-битный! Только через OUT (C),A (с LD BC,004Eh)
[Parinov.txt:692–693].
Примечание: IvanMak.txt упоминает его как 8-битный, но Parinov.txt явно указывает 16-битный доступ. Современный код использует
OUT (C),A.
Биты порта #4E [Parinov.txt:695–698]:
| Бит | Мнемоника | Назначение |
|---|---|---|
| 7 | CBL_ON | 1 = CBL включён, 0 = обычный COVOX |
| 6 | STEREO | 1 = стерео, 0 = моно |
| 5 | 16BIT | 1 = 16-битные сэмплы, 0 = 8-битные |
| 4 | IRQ_EN | 1 = включить прерывания от CBL |
| 3–0 | FREQ | Частота дискретизации (см. таблицу) |
10.4.3 Частоты дискретизации
[Parinov.txt:700–718]:
| Код | Частота | Примечание |
|---|---|---|
| 0 | 16 kHz | старые режимы, НЕ ИСПОЛЬЗОВАТЬ |
| 1 | 22 kHz | старые режимы, НЕ ИСПОЛЬЗОВАТЬ |
| 2–7 | — | зарезервировано |
| 8 | 7.8125 kHz | mono/stereo, 8/16-bit |
| 9 | 10.9375 kHz | mono/stereo, 8/16-bit |
| A | 15.625 kHz | mono/stereo, 8/16-bit |
| B | 21.875 kHz | mono/stereo, 8/16-bit |
| C | 31.25 kHz | mono/stereo, 8/16-bit |
| D | 43.75 kHz | mono/stereo, 8/16-bit |
| E | 54.6875 kHz | mono/stereo, 8/16-bit |
| F | 109.375 kHz | mono/stereo, 8/16-bit |
Важно: коды 0 и 1 — старые режимы из первых прошивок, несовместимы с новыми режимами (8–F). Использовать только коды 8–F.
10.4.4 Режимы и формат данных
[Parinov.txt:767–783]:
| Режим | Нулевой уровень | Размер блока | Формат данных |
|---|---|---|---|
| mono 8-bit | 80h |
128 байт | DB 80h, 81h, 7Fh, ... |
| mono 16-bit | 0000h |
256 байт | DW 0, 1000, -1000, ... |
| stereo 8-bit | 80h,80h |
128 байт | DB 80h,80h, 81h,80h, ... (L, R чередуются) |
| stereo 16-bit | 0000h,0000h |
256 байт | DW 0,0, 1000,0, ... (L, R чередуются) |
Формат данных выбран так, чтобы WAV-файлы можно было пересылать в CBL
простой OTIR [Parinov.txt:791].
10.4.5 Буфер CBL и механизм банок
CBL имеет буферное ОЗУ на 256 байт, организованное как кольцевой буфер [Parinov.txt:758–760]:
- Счётчик CBL считает «назад» — из-за особенности команды
OUTI, гдеBуменьшается и попадает на A15..A8. - Для 8-битных режимов буфер условно разбит на две банки по 128 байт.
- Для 16-битного режима блок = 256 байт (весь буфер).
Механизм работы:
- Процессор записывает блок данных (128 байт для 8-бит, 256 байт для 16-бит) в буфер CBL.
- Аппаратный счётчик CBL автоматически считывает данные из буфера и отправляет в ЦАП на заданной частоте.
- Бит 7 порта
#FEуказывает, какая банка сейчас выводится в ЦАП. - Когда банка переключается — CBL запрашивает следующую порцию данных (через прерывание или polling).
- Запрос данных возникает для каждых 128 байт (256 в 16-битном режиме).
10.4.6 Порт статуса #FE
Бит 7 порта #FE — запрос данных для CBL [Parinov.txt:720–724]:
| Бит | Назначение |
|---|---|
| 7 | CBL data request — 1 = CBL запрашивает новую порцию данных |
| 5 | Frame sync — кадровый импульс (4 мс длиной, 20 мс период) |
Примечание: В MAME при выключенном CBL бит 7 порта #FE всегда = 1. Это следует учитывать при разработке обработчика прерываний [
im2_isr_design.md:26–31].
Противоречие [08-io.md §8.3]:
- IvanMak.txt описывает бит 7 как старший бит счётчика CBL для polling (определение, какая половина буфера выводится).
- Parinov.txt описывает его как запрос прерывания.
- Оба описывают одну физическую линию, но в разных режимах (polling vs interrupt).
10.4.7 Прерывания и IM2
- При включённых прерываниях CBL (бит 4 порта
#4E= 1) необходим режим IM 2. - Если остаться на IM1, DOS-процедура прерываний будет вызываться слишком часто, что вызовет тормоза на высоких частотах [Parinov.txt:762–764].
- Вектор прерывания CBL —
#FF(как и у клавиатуры, и у кадрового). Отличать — по биту 7 порта#FE[sprinterIntLib.asm:24–26].
Обработчик прерываний на IM2:
; Проверка источника
IN A, (#FE)
RLCA ; бит 7 → CF
JR NC, not_cbl ; не CBL — на другой обработчик
; CBL запрашивает данные
LD BC, 804Fh ; B = 128 (счётчик), C = 4Fh (порт CBL data)
LD HL, next_block
OTIR ; вывести 128 байт в буфер CBL
...
10.4.8 Запись данных в CBL
Способ 1: OTIR/OUTI через порт #4F
LD BC, 804Fh ; B = 128 (счётчик), C = #4F (CBL data)
LD HL, data_block
OTIR ; вывести 128 байт
Способ 2: через страницу ОЗУ #FD с акселератором
Страница #FD, отображённая в окно #C000, аппаратно связана с буфером CBL.
Для 8-битного режима — записать 128 байт; для 16-битного — 256 байт
[Parinov.txt:727–731].
; Запись блока данных в CBL через страницу #FD с акселератором
IN A, (#E2) ; сохранить текущую страницу W3
LD (.save_page), A
LD A, #FD
OUT (#E2), A ; W3 = страница CBL
LD DE, #C000 ; приёмник (CBL buffer)
LD B, 0 ; B = 0 → 256 байт (или 128 для 8-bit)
LD D,D ; ACC_ON: включить акселератор
LD L,L ; ACC_CopyBlock_Horizontal
LD A, (HL) ; загрузить байт в буфер акселератора
LD (DE), A ; записать в CBL
LD B,B ; ACC_OFF: выключить акселератор
LD A, (.save_page)
OUT (#E2), A ; восстановить страницу
10.4.9 Полный пример
Из docs/samples/Пример для CBL.asm [sprinterIntLib.asm]:
; Инициализация IM2
LD A, #BE
LD I, A ; таблица векторов по #BE00
IM 2
; Вектор прерывания CBL = #BEFF
; (Interrupt_Vector OR 0FFh)
; Включение CBL
LD BC, #4E
LD A, %10011000b ; bit7=1 CBL on, bit4=1 IRQ en, bits3-0=1000 = 7.8125 kHz
OUT (C), A
; В ISR:
; IN A, (#FE)
; RLCA
; JR NC, .NoSound
; ... копировать 128 байт через страницу #FD с акселератором
; После проигрывания:
; Установить NumberPage=2, подождать HALT
; Выключение CBL:
LD BC, #4E
LD A, 0
OUT (C), A
10.4.10 Известные проблемы
- CBL vs Fast RAM: порт
#FBиспользуется и для COVOX/CBL, и для включения КЭШ-ОЗУ (см. §10.3.3). - Щелчок перед первым звуком: известная проблема при старте CBL
[
TODO.md:263]. - Помехи при движении мыши: часть тиков прерываний, обслуживающих
CBL-насос, уходит на обслуживание мыши [
TODO.md:270–277]. - Порт #4E — 8-бит vs 16-бит: IvanMak подразумевает 8-битный,
Parinov требует 16-битный
OUT (C),A(см. §10.4.2). - MAME: бит 7 порта #FE = 1 при выключенном CBL: может вызвать ложные срабатывания обработчика (см. §10.4.6).
10.5 Бипер
Стандартный Spectrum-бипер — бит 3 (в некоторых конфигурациях бит 5)
порта #FE. Выведен через ту же схему TDA1543, что COVOX и AY
[IvanMak.txt:639–640].
; Включить бипер
LD A, %00001000 ; бит 3 = 1
OUT (#FE), A
; Выключить бипер
LD A, %00000000 ; бит 3 = 0
OUT (#FE), A
10.6 SSC (Sprinter Sound Card)
Разрабатывалась, но не реализована ни в одной прошивке Sp2000 из-за большого объёма ПЛМ [IvanMak.txt:763–772].
Параметры проекта:
- 2 канала
- 16 восьмибитных голосов
- 256-байтные Wave-таблицы для каждого голоса
- 8-битный регулятор амплитуды
10.7 Кросс-ссылки
- Порты звука:
11-ports.md - Баги AY и CBL:
12-bugs.md - Fast RAM и конфликт с COVOX:
04-memory.md §4.6 - 08-io.md (остальной ввод-вывод):
08-io.md