Исторический контекст и место в эволюции ZX Spectrum
Происхождение и создание
Звуковой сопроцессор AY-3-8910 был разработан американской компанией General Instrument в конце 1970-х годов как часть семейства программируемых звуковых генераторов (PSG). Его более простая версия, AY-3-8912, отличалась только уменьшенным количеством линий ввода-вывода. Интересно, что изначально чип создавался для аркадных автоматов и бытовых компьютеров, но настоящую популярность обрел именно в клонах ZX Spectrum.Внедрение в мир Spectrum
Первым компьютером Spectrum с аппаратной поддержкой AY стал Sinclair ZX Spectrum 128K (1985 год), разработанный совместно с испанской компанией Investrónica. Примечательно, что в оригинальном дизайне Клайва Синклера не предусматривался отдельный звуковой чип — всем звуком управлял сам Z80 через простой бипер. AY стал компромиссным решением для улучшения звуковых возможностей.В СССР и странах Восточной Европы AY получил особенное распространение благодаря клонам Spectrum, таким как:
- Pentagon — использовал AY-3-8910/8912
- Scorpion — часто имел два чипа AY для стереозвука
- ATM Turbo — советский клон с расширенными возможностями
- Profi — семейство российских компьютеров, разработанных в СП «Крамис»
Аппаратные характеристики и архитектура
Технические спецификации
- Тактовая частота: 1.773445 МГц для Spectrum (CLK = CPU clock / 2)
- Разрядность: 12-битные таймеры тона, 5-битный генератор шума
- Каналы: 3 независимых звуковых канала (A, B, C)
- Возможности каждого канала:
- Программируемая частота (12 бит, ~ 0-110840 Гц)
- 16 уровней громкости (4 бита)
- Возможность использования огибающей (envelope)
- Индивидуальное включение тона/шума
- Генератор огибающей: 16 предустановленных форм + программная
- Порты ввода-вывода: 2 программируемых 8-битных порта (только в AY-3-8910)
Схема подключения в Spectrum 128K
В оригинальном Spectrum 128K чип AY подключен через декодер адресов:(весь пример кода и технические детали будут на ассемблере Z80)
Assembler Z80:
; Порты AY в Spectrum 128K
AY_REG_SELECT equ $FFFD ; Выбор регистра AY
AY_REG_WRITE equ $BFFD ; Запись значения в выбранный регистр
AY_REG_READ equ $BFFD ; Чтение значения из выбранного регистра
Адресное пространство и конфликты
Важная особенность: AY разделяет порт чтения с другими устройствами. При чтении из $FFFD возвращаются данные с клавиатуры, что требует аккуратного программирования.Регистры AY: полный разбор
Структура регистров (16 регистров, R0-R15)
Регистры тона (R0-R5):
Код:
R0/R1: Канал A тон (младший/старший байт)
R2/R3: Канал B тон
R4/R5: Канал C тон
Регистр 6: Генератор шума (5 бит)
Код:
Биты 0-4: период шума (N = значение * 2)
Регистры 7-9: Включение тона/шума
Код:
Регистр 7: Управление смешиванием
Бит 0: Выключить тон канала A (1=выкл)
Бит 1: Выключить тон канала B
Бит 2: Выключить тон канала C
Бит 3: Выключить шум канала A
Бит 4: Выключить шум канала B
Бит 5: Выключить шум канала C
Биты 6-7: Не используются
Регистры 8-10: Громкость каналов
Код:
4 бита на канал (0-15)
Если бит 4 = 1, используется огибающая вместо фиксированной громкости
Регистры 11/12: Огибающая период
Код:
Аналогично тону: 16-битное значение периода огибающей
Регистр 13: Форма огибающей
Код:
Биты 0-3: Номер формы (0-15)
Основные формы:
0: \___ однонаправленное затухание
1: /___ нарастание
4: \\\\ пилообразная
8: \___\___ повторяющаяся
10: \\__\\__ прямоугольная
Регистры 14/15: Порты ввода-вывода
Код:
Только для AY-3-8910, в Spectrum обычно не используются
Программирование AY на ассемблере Z80
Базовые процедуры работы
Assembler Z80:
; Инициализация AY
INIT_AY:
ld bc, AY_REG_SELECT
ld e, 7 ; Регистр 7 - управление
out (c), e
ld bc, AY_REG_WRITE
ld a, %00111111 ; Выключить все тона и шумы
out (c), a
ret
; Установка значения в регистр AY
; Вход: A = номер регистра, E = значение
SET_AY_REG:
ld bc, AY_REG_SELECT
out (c), a ; Выбираем регистр
ld bc, AY_REG_WRITE
out (c), e ; Записываем значение
ret
; Воспроизведение ноты на канале A
; Вход: HL = частота (12 бит)
PLAY_NOTE_A:
ld a, 0
ld e, l
call SET_AY_REG ; Младший байт тона
ld a, 1
ld e, h
call SET_AY_REG ; Старший байт тона
; Включаем тон канала A
ld a, 7
ld e, %00111110 ; Оставляем только тон A
call SET_AY_REG
; Устанавливаем громкость
ld a, 8
ld e, 15 ; Максимальная громкость
call SET_AY_REG
ret
Продвинутые техники: программная огибающая
Реальные трекеры часто реализуют собственную огибающую для большего контроля:
Assembler Z80:
; Структура канала в памяти
CHANNEL_STRUCT:
.freq dw 0 ; Текущая частота
.volume db 0 ; Текущая громкость (0-15)
.env_pos db 0 ; Позиция в огибающей
.env_speed db 0 ; Скорость изменения
.env_table dw 0 ; Адрес таблицы огибающей
; Таблица огибающей атака-сустейн
ENV_ATTACK:
db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
db 15,15,15,15,15,15,15,15 ; Сустейн
db 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 ; Релиз
; Процедура обработки огибающей (вызывается в прерывании)
PROCESS_ENVELOPE:
ld ix, CHANNEL_STRUCT
ld a, (ix + CHANNEL_STRUCT.env_pos)
inc a
cp 48 ; Длина огибающей
jr nz, .save_pos
xor a ; Зациклить
.save_pos:
ld (ix + CHANNEL_STRUCT.env_pos), a
ld hl, ENV_ATTACK
ld d, 0
ld e, a
add hl, de
ld a, (hl) ; Новое значение громкости
ld (ix + CHANNEL_STRUCT.volume), a
; Применяем к AY
ld a, 8 ; Регистр громкости канала A
ld e, (ix + CHANNEL_STRUCT.volume)
call SET_AY_REG
ret
Генерация шумовых эффектов
Assembler Z80:
; Установка параметров шума
SET_NOISE:
; Период шума
ld a, 6
ld e, 16 ; Среднее значение
call SET_AY_REG
; Включаем шум на каналах
ld a, 7
ld e, %00110111 ; Тон A,B,C выкл, шум вкл на всех
call SET_AY_REG
; Громкости
ld a, 8
ld e, 12
call SET_AY_REG
ld a, 9
ld e, 12
call SET_AY_REG
ld a, 10
ld e, 12
call SET_AY_REG
ret
; Эффект выстрела
SHOT_EFFECT:
ld hl, 50 ; Высокая частота
call PLAY_NOTE_A
ld a, 6
ld e, 1 ; Максимальная частота шума
call SET_AY_REG
; Плавное уменьшение громкости
ld b, 15
.loop:
push bc
ld a, 8
ld e, b
call SET_AY_REG
ld bc, 1000 ; Задержка
.delay:
dec bc
ld a, b
or c
jr nz, .delay
pop bc
djnz .loop
ret
Программирование на BASIC 128K
Хотя BASIC не оптимален для работы со звуком, в 128K режиме есть специальные команды:
Бейсик ZX:
10 REM Инициализация AY
20 BORDER 0: PAPER 0: INK 7: CLS
30 REM Воспроизведение ноты
40 SOUND 1, 100, 10: REM Канал A, частота 100, длительность 10
50 REM Аккорд
60 SOUND 1, 100, 20: SOUND 2, 125, 20: SOUND 4, 150, 20
70 REM Шум
80 SOUND 8, 10, 30: REM Шум на канале A
90 REM Использование огибающей
100 ENV 1, 5, 1000, 100, 5, 0, 5, 1000, 100
110 SOUND 1, 10, 100, 0, 1
Оптимизации и хитрости программирования
Использование прерываний для музыки
Assembler Z80:
SETUP_MUSIC_IRQ:
di
ld hl, MUSIC_INT
ld ($FE00), hl ; Вектор прерывания IM2
ld a, $FE
ld i, a
im 2
ei
ret
MUSIC_INT:
push af
push bc
push de
push hl
push ix
exx
ex af, af'
push af
push bc
push de
push hl
; Обработка одного тика музыки
call MUSIC_TICK
pop hl
pop de
pop bc
pop af
ex af, af'
exx
pop ix
pop hl
pop de
pop bc
pop af
ei
ret
Полифоническая музыка с тремя каналами
Сложность в том, что нужно распределять ноты между каналами:
Assembler Z80:
; Структура для трекера
MUSIC_TRACKER:
.pattern_ptr dw PATTERN_DATA
.position db 0
.speed_counter db 0
.speed db 6
.channels:
.chA_note db 0
.chA_instr db 0
.chA_volume db 0
.chB_note db 0
.chB_instr db 0
.chB_volume db 0
.chC_note db 0
.chC_instr db 0
.chC_volume db 0
; Таблица частот нот (октава 3)
NOTE_FREQ_TABLE:
dw 3822, 3607, 3405, 3214, 3034, 2863 ; C, C#, D, D#, E, F
dw 2702, 2551, 2407, 2272, 2145, 2024 ; F#, G, G#, A, A#, B
Особенности разных моделей Spectrum
Spectrum 128K (оригинальный)
- Один чип AY-3-8912
- Монофонический выход
- Конфликты при чтении портов
Pentagon 128K/512K
- Часто два чипа AY для стерео
- Возможность независимого программирования
- Порт $FFDF для выбора чипа
Scorpion ZS 256
- Поддержка стерео через один чип
- Дополнительные режимы смешивания
- Программируемый усилитель
Советские клоны (ATM Turbo, Profi)
- Часто нестандартные порты
- Дополнительные аппаратные возможности
- Проблемы с совместимостью
Создание музыки: практические советы
Ограничения и обходные пути
- Только 3 канала → Используйте быстрое переключение нот (арпеджио)
- Нет SAMPLES → Генерация шумом ударных
- Ограниченная огибающая → Программная реализация
Оптимальные частоты дискретизации
Для музыки: 50 Гц (частота прерываний)Для эффектов: до 100 Гц с чередованием каналов
Стерео-эффекты на моно AY
Хотя оригинальный Spectrum 128K имеет моно выход, можно эмулировать стерео:
Assembler Z80:
; Псевдо-стерео чередованием каналов
PSEUDO_STEREO:
ld a, (tick_counter)
and 1
jr z, .left
.right:
ld e, %00000101 ; Только каналы B и C
jr .apply
.left:
ld e, %00001010 ; Только каналы A и C
.apply:
ld a, 7
call SET_AY_REG
ret
Инструменты и разработка
Современные средства
- AY-трекеры: Vortex Tracker, Arkos Tracker
- Эмуляторы: FUSE, UnrealSpeccy, ZXSpin
- Компиляторы: SJASM, Pasmo, Z80asm
Оптимизация кода
Assembler Z80:
; Быстрая установка регистров AY (экономия тактов)
FAST_AY_OUT:
ld bc, AY_REG_SELECT
out (c), a ; A = номер регистра
inc b ; BC = AY_REG_WRITE
out (c), e ; E = значение
ret
; Массовая инициализация регистров
INIT_AY_BULK:
ld hl, AY_DEFAULT_VALUES
ld b, 16 ; 16 регистров
ld c, 0 ; Начинаем с регистра 0
.loop:
ld a, c
ld e, (hl)
call FAST_AY_OUT
inc hl
inc c
djnz .loop
ret
AY_DEFAULT_VALUES:
db 0,0,0,0,0,0,0,%00111111,0,0,0,0,0,0,0,0
Пример полноценной музыкальной дорожки
Assembler Z80:
MUSIC_DATA:
; Паттерн 0
PATTERN_0:
db $24, $01, $0F, $00, $00, $00, $28, $01, $0F ; Нота, инструмент, громкость
db $00, $00, $00, $2B, $01, $0F, $00, $00, $00
db $30, $01, $0F, $00, $00, $00, $00, $00, $00
db $00, $00, $00, $00, $00, $00, $00, $00, $00
INSTRUMENT_TABLE:
; Инструмент 0: пианино
db %00000001 ; Использовать огибающую
db 0, 100 ; Атака
db 15, 50 ; Сустейн
db 0, 100 ; Релиз
db 0 ; Нет вибрато
PLAY_MUSIC:
ld ix, MUSIC_TRACKER
ld a, (ix + MUSIC_TRACKER.speed_counter)
inc a
cp (ix + MUSIC_TRACKER.speed)
jr nz, .no_new_note
; Обработка новой ноты
call GET_NEXT_NOTE
call APPLY_NOTE_TO_AY
.no_new_note:
ld (ix + MUSIC_TRACKER.speed_counter), a
ret
Заключение
AY-3-8910, несмотря на свои ограничения, стал легендарным звуковым чипом благодаря простоте программирования и характерному "спектрумовскому" звучанию. Его изучение — это не только погружение в историю, но и отличный способ понять основы синтеза звука и низкоуровневого программирования периферии.Ключевые принципы для запоминания:
- AY — это программируемый генератор тона и шума
- 3 канала с независимыми частотами и громкостями
- Огибающая позволяет создавать динамическое звучание
- Оптимизация через прерывания и быстрые процедуры записи
- Совместимость между разными клонами требует тестирования