Files
Sprinter-SDCC/docs/new/10-sound.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

16 KiB
Raw Blame History

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:632634].

На Sp2000 все три компонента присутствуют в основной прошивке ППЛМ. CBL включается через порт #4E (бит 7 = 1). При выключенном CBL (бит 7 = 0) работает обычный 8-bit COVOX [IvanMak.txt:662666].

10.2 GM80C760 (AY-3-8910)

10.2.1 Реализация

AY-функция реализована на микросхеме GM80C760 (ППЛМ ALTERA EP1K30), AY-3-8910/8912 совместимая. Это не отдельная дискретная микросхема [IvanMak.txt:636637].

На EP1K30 (Sp2000) реализована 3-я версия AY. Включает три голоса, шум и генератор огибающей (envelope). В формирователе огибающей обнаружена небольшая ошибка, детали не документированы [IvanMak.txt:224229], [12-bugs.md §11.2].

10.2.2 Порты

Порт Назначение
#BFFD AY-8910 — запись номера регистра (address)
#FFFD AY-8910 — чтение/запись данных регистра (data)

Внутренние номера в карте дешифратора ППЛМ: 90h (#BFFD), 91h (#FFFD) [IvanMak.txt:12981299].

10.2.3 Программирование

Программирование — стандартное для AY-3-8910/8912 [IvanMak.txt:636637]:

; Установить регистр 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 — запись в COVOX
  • IN A, (#FB) — включение КЭШ-ОЗУ

Если КЭШ-ОЗУ включено, запись в #FB уходит в кэш, а не в COVOX. Перед работой с COVOX кэш нужно отключать: IN A, (#7B) [IvanMak.txt:850851], [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:692693].

Примечание: IvanMak.txt упоминает его как 8-битный, но Parinov.txt явно указывает 16-битный доступ. Современный код использует OUT (C),A.

Биты порта #4E [Parinov.txt:695698]:

Бит Мнемоника Назначение
7 CBL_ON 1 = CBL включён, 0 = обычный COVOX
6 STEREO 1 = стерео, 0 = моно
5 16BIT 1 = 16-битные сэмплы, 0 = 8-битные
4 IRQ_EN 1 = включить прерывания от CBL
30 FREQ Частота дискретизации (см. таблицу)

10.4.3 Частоты дискретизации

[Parinov.txt:700718]:

Код Частота Примечание
0 16 kHz старые режимы, НЕ ИСПОЛЬЗОВАТЬ
1 22 kHz старые режимы, НЕ ИСПОЛЬЗОВАТЬ
27 зарезервировано
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:767783]:

Режим Нулевой уровень Размер блока Формат данных
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:758760]:

  • Счётчик CBL считает «назад» — из-за особенности команды OUTI, где B уменьшается и попадает на A15..A8.
  • Для 8-битных режимов буфер условно разбит на две банки по 128 байт.
  • Для 16-битного режима блок = 256 байт (весь буфер).

Механизм работы:

  1. Процессор записывает блок данных (128 байт для 8-бит, 256 байт для 16-бит) в буфер CBL.
  2. Аппаратный счётчик CBL автоматически считывает данные из буфера и отправляет в ЦАП на заданной частоте.
  3. Бит 7 порта #FE указывает, какая банка сейчас выводится в ЦАП.
  4. Когда банка переключается — CBL запрашивает следующую порцию данных (через прерывание или polling).
  5. Запрос данных возникает для каждых 128 байт (256 в 16-битном режиме).

10.4.6 Порт статуса #FE

Бит 7 порта #FE — запрос данных для CBL [Parinov.txt:720724]:

Бит Назначение
7 CBL data request — 1 = CBL запрашивает новую порцию данных
5 Frame sync — кадровый импульс (4 мс длиной, 20 мс период)

Примечание: В MAME при выключенном CBL бит 7 порта #FE всегда = 1. Это следует учитывать при разработке обработчика прерываний [im2_isr_design.md:2631].

Противоречие [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:762764].
  • Вектор прерывания CBL — #FF (как и у клавиатуры, и у кадрового). Отличать — по биту 7 порта #FE [sprinterIntLib.asm:2426].

Обработчик прерываний на 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:727731].

; Запись блока данных в 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 Известные проблемы

  1. CBL vs Fast RAM: порт #FB используется и для COVOX/CBL, и для включения КЭШ-ОЗУ (см. §10.3.3).
  2. Щелчок перед первым звуком: известная проблема при старте CBL [TODO.md:263].
  3. Помехи при движении мыши: часть тиков прерываний, обслуживающих CBL-насос, уходит на обслуживание мыши [TODO.md:270277].
  4. Порт #4E — 8-бит vs 16-бит: IvanMak подразумевает 8-битный, Parinov требует 16-битный OUT (C),A (см. §10.4.2).
  5. MAME: бит 7 порта #FE = 1 при выключенном CBL: может вызвать ложные срабатывания обработчика (см. §10.4.6).

10.5 Бипер

Стандартный Spectrum-бипер — бит 3 (в некоторых конфигурациях бит 5) порта #FE. Выведен через ту же схему TDA1543, что COVOX и AY [IvanMak.txt:639640].

; Включить бипер
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:763772].

Параметры проекта:

  • 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