Нестандартное использование
General Sound
(с) Dr.Lion/RSM
──────────────────────────────────────────
Приведенный ниже материал является авто-
рским достоянием! При его использовании
ссылка на автора обязательна!
На многое ли способна звуковая карточка
General Sound (далее GS)? Кроме проигрива-
ния mod'ов и sample'ов она может еще много
чего, если заставить работать ее нестанда-
ртным способом. Для этого нам нужно загру-
зить в GS свою программу, передать ей уп-
равление и получить полную ВЛАСТЬ над же-
лезом GS. А железо то у GS весьма нехилое:
Процессор: Z80 12MHz
Прерывания: INT 37500Hz
Память: 128-512Kb (страницами по 32Kb)
DAC: 4 канала x 8 бит каждый
Громкость: 4 канала x 5 бит каждый
Меня долго мучала одна бредовая идея. А
можно ли создать на базе Z80 устройство,
которое могло бы эмулировать работу муз.
сопроцессора AY-3-8910 или его YAMAHA ана-
лога? Конечно можно, но каким должно быть
такое устройство? Оно должно програмно-ап-
паратным способом формировать выходной си-
гнал трех каналов A,B,C. Но по самым скро-
мным подсчетам частота процессора устрой-
ства должна быть не менее 14MHz. Даже если
устройство я и соберу, то кто, кроме меня
захочет собрать его и поцепить на свой
старичок SPECCY? Кто поддержит новый стан-
дарт? А как быть людям, которые сидят на
эмуляторах ZX-SPECTRUM? Вот тут-то и поя-
вилась идея использавать для эмуляции AY
железо GS. GS более-менее стандартный де-
вайс и поддерживается серьёзными эмулято-
рами ZX. Хоть частота CPU GS и меньше нео-
бходимых 14MHz, реализовать на нем упроще-
нный вариант эмулятора AY все-таки можно.
Через несколько минут я сумею убедить вас
в этом.
Итак, давайте подробнее разберемся, как
нам заставить зазвучать GS до боли знако-
мыми звуками AY. Во-первых, давайте уяс-
ним, что такое AY и как он работает. AY -
это микросхема, которая содержит в себе
три генератора прямоугольных импульсов
(цифровой тон), генератор шума, генератор
огибающей, регистры амплитуды, регистр сме
сителя, регистр формы огибающей и три ЦАП.
Генераторы тона
Они представляют собой некие счетчики-
делители с предустановкой 12-ти битного
коэффициента деления и выходом цифрового
тона. Счетчики-делители считают на убыва-
ние и при достижении 0-го значения меняют
выходной логический сигнал на противопо-
ложный. Входной частотой для счетчиков-
делителей является тактовая частота AY,
разделённая на 16.
Генератор шума
Он, по-сути, состоит из счетчика-делите-
ля, аналогичного генератору тона и устрой-
ства генерации псевдо-случайного выходного
логического сигнала. Это устройство собра-
но на сдвигающем регистре и элементе "Ис-
ключающее ИЛИ". Сигнал генератора шума фо-
рмируется примерно так: тактовый генератор
AY, разделенный на 16 -> 5-ти битный счет-
чик-делитель -> генератор псевдо-случайно-
го выходного логического сигнала.
Генератор и форма огибающей
Генератор огибающей состоит из 16-ти би-
тного счетчика делителя к логическому вы-
ходу которого подключен 4-х разрядный ре-
версивный счетчик. Режим работы реверсив-
ного счетчика задают биты регистра формы
огибающей. На выходе реверсивного счетчи-
ка формируется 4-х разрянная последовате-
льность амплитуд огибающей которая подае-
тся вначале на смеситель а потом на ЦАП.
Регистры амплитуды
Так же, как и генераторы тона представ-
лены для каждого канала AY раздельно. Мла-
дшие 4-ре бита регистра являются кодом ам-
плитуды и подаются на смеситель. Бит 4 -
это флаг, указывающий смесителю на источ-
ник амплитуды. При 0 - источник младшие
биты регистра амплитуды, при 1 - источник
код на выходе реверсивного счетчика гене-
ратора огибающей.
Регистр смесителя
Биты 0-2 разрешают/запрещают поступление
в смеситель выходных логических сигналов
генераторов тона для каждого канала, биты
3-5 разрешают/запрещают поступление в сме-
ситель выходного логического псевдо-случа-
йного сигнала от генератора шума для каж-
дого канала отдельно. Если логический сиг-
нал источника равен 0, то его код амплиту-
ды тоже равен 0, если равен 1, то источник
кода амплитуды определяется в зависимости
от флага огибающей в регистре амплитуды.
Цифро-аналог. преобразователи
На ЦАП каждого канала подаются сформиро-
ваные смесителем коды амплитуд тона, шума
и огибающей. Эти коды складываются и ЦАП
формирует на выходе определенный уровень
напряжения. Следует отметить, что шкала
уровней напряжений ЦАП AY логарифмическая.
Из всей описаной выше начинки AY в GS
имеются лишь ЦАП'ы, которые к тому же име-
ют линейную шкалу выходного напряжения.
Поэтому недостающие узлы мы будем строить
из особых "кирпичиков" - команд CPU Z80.
Прежде всего давайте определим задачи,
которые должен выполнять эмулятор AY. Их
всего две:
1. Генерация выходных сигналов каналов AY.
2. Интерпретация поступающих на эмулятор
входных данных (данные в формате реаль-
ного AY), перенастройка эмулятора.
Т.е. у нас должно работать одновременно
две задачи (процесса). Причем первая из
них должна работать так, чтобы ничто не
могло прервать её работу, а значит повли-
ять на стабильность и качество звука - это
задача с абсолютным приоритетом. Очевидно,
что вторую задачу можно выполнять по мере
возможности но не следует забывать, что
скорость её работы напрямую связана со
скоростью обмена между эмулятором AY и ZX.
Теперь перенесем изложенные рассуждения
на железо GS. Задача N1 должна работать в
цикле обработки маскируемых прерываний
(именно этот тип прерываний доступен в GS)
а задача N2 - в оставшееся после обработки
прерываний время. Давайте прикинем длину
одного цикла прерываний GS в тактах:
Lgsi=Fgsc/Fgsi
где Lgsi - длина цикла прерывания, такт;
Fgsc - тактовая частота GS Z80 =12MHz;
Fgsi - частота прерываний GS =37500Hz.
Lgsi=12000000/37500=320 тактов
Полученая цыфра вам, на первый взгляд,ни
о чем не говорит. Но, 320 тактов - это 80
элементарных комманд или 30-35 более-мение
серьезных комманд. Поверте, этого недоста-
точно для эмуляции всех узлов AY. Мало то-
го, доже 640 тактов не хватает. Поэтому
для процедуры эмуляции придетля выделить 3
прерывания по 320 тактов, т.е. 960 тактов.
За это время можно просчитать все необхо-
димые узлы AY. Вот так выглядит процедура
эмуляции, подвешеная на прерывания:
;------ Процедура генерации работы AY (обработчик INT в GS) ----
GS_INT EXA ;4 OUT to DAC
EXX ;4
LD A,(#6000) ;13
LD A,(#6100) ;13
LD A,(#6200) ;13
LD A,(#6300) ;13 WorkTime=60
A_SetA LD DE,#0000 ;10 TONE A
A_NumA LD HL,#0000 ;10
ADD HL,DE ;11
LD (A_NumA+1),HL ;16
A_NumB LD A,#00 ;7
A_SetB ADC A,#00 ;7
LD (A_NumB+1),A ;13
JR NC,B_SetA ;7/12
LD A,C ;4
XOR %00000001 ;7 MinTime=86
LD C,A ;4 MaxTime=96
B_SetA LD DE,#0000 ;10 TONE B
B_NumA LD HL,#0000 ;10
ADD HL,DE ;11
LD (B_NumA+1),HL ;16
B_NumB LD A,#00 ;7
B_SetB ADC A,#00 ;7
LD (B_NumB+1),A ;13
JR NC,C_SetA ;7/12
LD A,C ;4
XOR %00000010 ;7 MinTime=86
LD C,A ;4 MaxTime=96
C_SetA LD DE,#0000 ;10 TONE C
C_NumA LD HL,#0000 ;10
ADD HL,DE ;11
LD (C_NumA+1),HL ;16
C_NumB LD A,#00 ;7
C_SetB ADC A,#00 ;7
LD (C_NumB+1),A ;13
JR NC,E_SetA ;7/12
LD A,C ;4
XOR %00000100 ;7 MinTime=86
LD C,A ;4 MaxTime=96
E_SetA LD DE,#0000 ;10 ENVELOP
E_NumA LD HL,#0000 ;10
ADD HL,DE ;11
LD (E_NumA+1),HL ;16
E_NumB LD A,#00 ;7
E_SetB ADC A,#00 ;7
LD (E_NumB+1),A ;13
JR NC,N_SetA ;7/12
LD B,(IX) ;19 MinTime=86
INC LX ;8 MaxTime=108
N_SetA LD DE,#0000 ;10 NOISE
N_NumA LD HL,#0000 ;10
ADD HL,DE ;11
LD (N_NumA+1),HL ;16
N_NumB LD A,#00 ;7
N_SetB ADC A,#00 ;7
LD (N_NumB+1),A ;13
JR NC,Mixer ;7/12
LD A,R ;9
RRCA ;4
LD R,A ;9
JR NC,Mixer ;7/12
LD A,C ;4
XOR %00111000 ;4 MinTime=86
LD C,A ;4 MaxTime=122
Mixer LD A,C ;4 MIXER
MixVal OR 0 ;7
LD L,A ;4 WorkTime=15
AEnFlag LD H,B ;4/7 DAC A VALUE
NOP ;4/0
LD A,H ;4
BIT 0,L ;8
JR NZ,ASetVo0 ;7/12
ADD A,H ;4
ASetVo0 BIT 3,L ;8
JR NZ,ASetVo1 ;7/12
ADD A,H ;4 MinTime=64
ASetVo1 LD (#6000),A ;13 MaxTime=63
BEnFlag LD H,B ;4/7 DAC B VALUE
NOP ;4/0
LD A,H ;4
BIT 1,L ;8
JR NZ,BSetVo0 ;7/12
ADD A,H ;4
BSetVo0 BIT 4,L ;8
JR NZ,BSetVo1 ;7/12
ADD A,H ;4
BSetVo1 LD (#6100),A ;13 MinTime=77
LD (#6200),A ;13 MaxTime=76
CEnFlag LD H,B ;4/7 DAC C VALUE
NOP ;4/0
LD A,H ;4
BIT 2,L ;8
JR NZ,CSetVo0 ;7/12
ADD A,H ;4
CSetVo0 BIT 5,L ;8
JR NZ,CSetVo1 ;7/12
ADD A,H ;4 MinTime=64
CSetVo1 LD (#6300),A ;13 MaxTime=63
EXX ;4 OTHER
EXA ;4
EI ;4
RET ;10 WorkTime=22
;MinWorkTime=732 MaxWorkTime=817 MidWorkTime=775 Free=143-10
Путем подсчета минимального и максималь-
ного времени работы процедуры можно уста-
новить, что период ее запуска составляет
3 прерывания (внутри процедуры не может
возникнуть прерывание) т.е. базовая часто-
та дискретизации равна:
Fgsd=Fgsi/3=37500/3=12500Hz
Чтобы сформировать один период генерато-
ра частоты тона Fayt необходима частота
дискретизации 2*Fayt (т.к. за один период
частоты дискретизации формируется только
один полупериод Fayt). В нашем случае ба-
зовая частота дискретизации равна 12500Hz,
следовательно максимальная частота генера-
тора тона составляет Fgsd/2=6250Hz, т.е.
минимальное значение регистра тона - 18.
(продолжение следует)
──────────────────────────────────────────