ПРОФЕССИОНАЛЬНЫЙ ПОДХОД
Программирование музыкального сопроцессора
(С) ОК & КО, г.Красноармейск, Саратовская обл., 1995.
В этом материале я попытался изложить принцип работы программиста с музыкальным процессором AY-3-8910 (8912), а также привел примеры программ для практического использования сопроцессора при создании звукового сопровождения программ. Существует' несколько
программ для создания музыки с помощью музыкального сопроцессора Но все они создают музыкальный файл, занимающий значительное место в памяти и порою не позволяющий делать простые шумовые и музыкальные эффекты короткой длительности (что необходимо в большинстве игровых программ, например, звук падающего мяча или выстрел из оружия). •
О том, как подключается сама микросхема в ZX-РЕВЮ было немало напитано и, поэтому, я приступлю сразу к описанию структуры и метода программирования сопроцессора . Программируемый генератор звуков (в дальнейшем ПГЗ) можно представить как три тональных генератора и генератор шума, амплитудой и частотой которых можно управлять программно. Амплитуда выходного сигнала изменяется тремя цифро-аналоговыми преобразователями (ЦАП), раздельно для каждого канала. Огибающая может управляться как непосредственно пользователем, так и генерироваться самим ПГЗ. Все команды управления генератором передаются через внутренние регистры ПГЗ, а доступ к регистрам реализуется через соответствующие порты. Одновременный доступ возможен только к одному из регистров сопроцессора . Номер этого регистра должен быть помещен в порт #FFFD (65533), а данные для этого выбранного регистра передаются через порт #BFFD (49149). Если потребуется считать данные с какого-либо регистра ПГЗ, то для этого нужно установить его номер в #FFFD (out) и считать данные регистра с этого же порта (in). Для наглядности см. рис.1.
31 н |
«FFFD |
(out) |
Выбор регистра |
& |
«FFFD |
(in) |
Чтение регистра |
0 с |
«BFFD |
(out) |
Данные в регистр |
РИС.1.
Теперь перейдем к рассмотрению непосредственно регистров сопроцессора. Для задания нужной частоты тона в одном из каналрв, нужно поместить данные в соответствующие два регистра. Один из них, регистр грубого тона (ГТ), задает старшую часть 12-разрядного числа, выражающего частоту То-на. Второй - регистр чистого тона (ЧТ), задает младшую часть (байт) этого числа. Таким образом, частота тона складывается из четырех битов регистра ГТ и восьми битов регистра ЧТ. Образование 12-раз-рядного периода тона и соответствующие порты для трех каналов
(А, В, и С) показаны на рис.2.
регистр ГТ
|7|б|5|4 |
3 |
2 |
|
1» |
регистр ЧТ |
-te испольэ |
1 |
|
|
|
76 |
5 4 3|2|l|0 |
|
|
|
|
|
|
|
|
|
|
|
|
И |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
210 |
12-ти разрядный период тона
каналы |
per ГТ |
per ЧТ |
А |
1 |
0 |
В |
3 |
2 |
с |
5 |
л |
Рис.2.
На любой из каналов ПГЗ может подаваться шум. Причем, либо отдельно, либо подмешиваясь к тону в одинаковой с ним пропорции (то есть шум не может быть громче или тише тона). Частота шумового сигнала задается 5-разрядным числом в регистре 6, старшие 3 бита этого регистра не используются. Генератор шума всего один и, поэтому, частоту шума нельзя задать отдельно для каждого канала. Если два (или три) канала используют генератор шума, то частота его будет одинакова в обоих (во всех) каналах.
Теперь о том, как выбрать, что должно, по нашему замыслу, звучать в каналах: шум, тон или шум с тоном одновременно, а может и вообще запретить какому-нибудь каналу издавать какие-либо звуки. За все это отвечает регистр 7, так называемый смеситель. Его младшие три разряда запрещают или разрешают подачу тона на канал (1-запретить, О-разрешить), причем, бит 0 - соответствует каналу "А", бит 1 - каналу "В", бит 2 -каналу "С". Следующие три разряда аналогичным образом управляют выдачей шума. Для наглядности см. рис.3.
регистр 6 регистр 7
(шум) (смеситель)
| шум | тон [
Рис.3.
Управление амплитудой (или попросту громкостью) выходного сигнала, будь то шум или тон, производится 16-ступенчатым ЦАП и регистрируется четырьмя битами соответствующих регистров. Для канала "А" - это будет регистр 8, для "В" - регистр 9 и для "С" регистр 10. Причем интересно, если не задавать частоту для выбранного канала, то можно использовать регистр управления амплитудой этого канала как обыкновенный ЦАП, например, для выдачи считанного при помощи АЦП аналогового сигнала. Если в регистре управления амплитудой включен пятый бит (бит 4), то это информирует ПГЗ о том, что в данном канале включен внутренний звуковой эффект. Эффект заключается в автоматической генерации огибающей сигнала. В ПГЗ запрограммировано 8 форм огибающих. Наглядно их можно представить из рис.4.
биты регистра |
13 |
форма сигнала |
3 |
2 |
1 |
0 |
|
0 |
0 |
X |
X |
|
0 |
1 |
X |
X |
/_ |
|
0 |
0 |
0 |
NTsTsJNX |
|
0 |
0 |
1 |
V |
|
0 |
1 |
0 |
|
|
0 |
1 |
1 |
SI |
|
1 |
0 |
0 |
/VT/VT/ |
|
1 |
0 |
1 |
у |
Примечание х-обозиачены
незначащие биты
РИС.4.
Регистр 13 служит для выбора формы огибающей. Так же, как и шум, эффект может быть лишь один для всех каналов. В регистре 12 задается старший байт частоты огибающей, в регистре 11 - младший. Полностью частота огибающей равна 16-разрядному числу, складывающемуся из регистров 12 и 11. Вот, в принципе, и все, что нужно знать для того, чтобы начать программирование ПГЗ. Я нарочно не стал писать про дополнительные регистры памяти ПГЗ, так как к программированию звуков они не имеют никакого отношения и я еще ни в одной программе не встречался с их использованием.
Терерь смело моя$но переходить к примерам.
Пользователям, имеющим 48-ки-лобайтную машину и музыкальный сопроцессор, не стоит огорчаться из-за отсутствия оператора PLAY. Можно вполне обойтись и без него. Непосредственное программирование регистров сопроцессора Дает программисту больше возможности, чем пресловутый оператор PLAY. Так что же нужно сделать для того, чтобы заставить зазвучать ПГЗ? Для этого достаточно установить частоту хотя бы в одном из регистров грубого или чистого тона, открыть смеситель, занести туда ноль, и установить громкость в том канале, для которого была установлена частота. Сделать это можно при помощи программы на БЕЙСИКЕ:
10 FOR F-l ТО 3: READ A: READ I: OUT 65533,A: OUT 49149,1: NEX Т F: STOP
20 GO TO 10
30 DATA 1,5,7,0,8,15
40 DATA 1,0,7,63,8,0
Набрав и запустив данную программу, Вы услышите смесь тона и шума. Звук будет слышен даже после выполнения команды NEW. Чтобы заставить сопроцессор замолчать, нужно после остановки программы выполнить CONTINUE. Это приведет регистры сопроцессора в бездейственное состояние. Я думаю, что не составит труда самим разобраться в работе этой программы, но все-таки поясню. В операторе DATA данные идут в порядке: регистр-данные-регистр-данные. . . То есть в строке 30 сначала устанавливается частота для первого канала в регистре грубого тона (per.1, данн.5). Далее разрешается подача одновременно шума и тона во всех каналах (per.7, данн.0). После чего в первом канале устанавливается максимальная громкость (per.8, данн.15). Строка 40 обнуляет частоту, закрывает подачу шума и тона во всех каналах и уменьшает громкость до нуля. В принципе, чтобы "заглушить" ПГЗ хватило бы одного из этих действий, но, чтобы в дальнейшем регистры нам не' мешали, лучше "заглушить" их все.
Теперь более практические примеры .
10 F6R F«1 ТО 4: READ A: READ I: OUT 65533,A: OUT 49149,1: NEX T F
15 FOR F-l TO 16: READ I: OUT 65533,0: OUT 49149,1: OUT 65533, 13: OUT 49149,1
20 PAUSE 10: NEXT F
25 DATA 7,56,8,16,12,10,1,1
30 DATA 30,220,120,0,30,120,17 0,170,120,170,220,250,250,250,25 0,250
Строка 10 к соответственно 25, устанавливает начальные параметры регистров. Она открывает все каналы для тона, устанавливает в первом канале использование внут~ реннего эффекта (8, 16), устанавливает период огибающей эффекта (12, 10) и устанавливает регистр грубого тона для первого канала. Строкй 15-20 и соответственно 30 изменяют регистр чистого тона и запускают эффект, причем, давая ему полностью дозвучать (PAUSE 10). Не стоит искать в данном примере какую-либо музыкальную ценность, он дан чисто для Практического знакомства с программированием музыки. При желании можно, подбирая значения DATA, воспроизвести несложную мелодию. Можно даже усложнить программу и писать музыку для трех каналов, используя весь звукоряд ПГЗ, но та1-кую задачу проще будет выполнить на любом из множества музыкальных редакторов для AY (например, WHAM+AY, SOUND TRACKER, SOUND MASTER, ASM). Нас в данном случае интересуют лишь короткие звуковые эффекты, не занимающие много места в памяти и легко доступные для использования.
Следующая программа позволяет воспроизводить звук, похожий на звук выстрела.
10 FOR F-l ТО 4: READ A: READ I: OUt 65533,A: OUT 49149,1: NEX T F
20 DATA 7,7,8,16,12,10,6,31
30 GO SUB 9000: STOP 9000 OUT 65533,13: OUT 49149,1< RETURN
Строки 10-20 - установка начальных параметров. Сам "выстрел" вызывается оператором GO SUB 9000 (как это демонстрируется в строке 30), что гораздо удобнее для использования в программах.
И, в заключение, приведу программу в машинных кодах, имеющую практическую ценность при звуковом оформлении как программ на БЕЙСИКЕ, так и программ в машинном коде.
1 2
3
4
5
6
7
8 9
10 11 12
13
14
15
16 CON1
17
18
19
20 21
22 CON2
23
24
25
26
27
28
29
30
31
32
33
34
35
36
ORG
PUSH
PUSH
PUSH
PUSH
LD
LD
LD
CALL
XOR
CP
CALL
JR
LD
CALL
XOR
CP
CALL
JR
LD
CALL
XOR
CP
JR
LD
RRA
JR
LD
RLCA LD
PUSH
LD
LD
CALL
POP
LD
60208
AF
HL
DE
BC
C, #FD HL,TAB
D, 4 DANN A
(HL) Z ,PLU Z,CONl A,8 CHEN A
(HL) Z, PLU Z,C0N2 A,9 CHEN A
(HL) 2,CONT A,(23672)
Z,CONT A,(HL)
(TAB2),A HL
HL,TAB1 D, 1 DANN HL A,10
37 |
|
CALL |
CHEN |
38 |
CONT |
POP |
ВС |
39 |
|
POP |
DE |
40 |
|
POP |
HL |
41 |
|
POP |
AF |
42 |
|
JP |
#38 |
43 |
DANN |
LD |
B, #FF |
44 |
|
LD |
A,(HL) |
45 |
|
OUT |
(C),A |
46 |
|
INC |
HL |
47 |
|
LD |
B,#BF |
48 |
|
LD |
A,(HL) |
49 |
|
OUT |
(С) , A |
50 |
|
INC |
HL |
51 |
|
DEC |
D |
52 |
|
D R |
NZ,DANN |
53 |
|
RET |
|
54 |
CHEN |
LD |
B,#FF |
55 |
|
OUT |
(C),A |
56 |
|
LD |
B,#BF |
57 |
|
DEC |
(HL) |
58 |
|
LD |
A,(HL) |
59 |
|
OUT |
(C),A |
60 |
PLU |
INC |
HL |
61 |
|
RET |
|
62 |
TAB |
DEFB |
2,200,5,1 |
63 |
|
DEFB |
6,31,7,%110001 |
64 |
CHI |
DEFB |
0 |
65 |
СН2 |
DEFB |
0 |
66 |
СНЗ |
DEFB |
0 |
67 |
ТАВ1 |
DEFB |
4 |
68 |
TAB 2 |
DEFB |
0 |
69 |
|
ENT |
$ |
70 |
|
DI |
|
71 |
|
LD |
A,48 |
72 |
|
LD |
I,A |
73 |
|
IM |
2 |
74 |
|
EI |
|
75 |
|
RET |
|
Программа запускается со строки 70 и работает прерываниям второго типа. То есть она практически незаметна для пользователя. Программа обнаружит себя, если занести по одному из адресов (или по нескольким сразу) CHI, СН2, СНЗ значение 15. Изменить содержимое этих ячеек можно и из БЕЙСИКА (РОКЕ), и из программ в машинном коде. Программа работает по следующему алгоритму:
- сначала сохраняются на стеке значения регистров, используемых программой;
-далее выставляются исходные значения для регистров сопроцессора (строки 6-9);
- после чего проверяются ячейки CHI, СН2, СНЗ и, если они не равны нулю, происходит вызов подпрограмм, обслуживающих соотг ветствующий канал. После их исполнения восстанавливаются регистры и программа переходит на стандартную подпрограмму обработки прерываний (#0038 - строки 10-42).
Тот, кто не захочет набирать программу на ассемблере, может для формирования блока кодов набрать программу на БЕЙСИКЕ.
5 CLEAR 60207 10 FOR F=60208 ТО 60332: READ A: POKE F,А: NEXT F
20 RANDOMIZE USR 15619: REM : SAVE MabcMCODE 60208,125 30 RANDOMIZE USR 60324 40 STOP
50 DATA 245,229,213,197,14,253 ,33,151,235,22,4,205,123,235,175 ,190,204,149,235,40,5,62
60 DATA 8,205,139,235,175,190, 204,14 9,23 5,40,5,62,9,205,139,23 5,175,190,40,26,58,120
70 DATA 92,31,40,20,126,7,50,1
63.235.229.33.162.235.22.1.205.1 23,235,225,62,10,205
80 DATA 139,235,193,209,225,24 1,195,56,0,6,255,126,237,121,35, 6,191,126,237,121,35,21
90 DATA 32,241,201,6,255,237,1
21.6.191.53.126.237.121.35.201.2 ,200,5,1,6,31,7
100 DATA 49,0,0,0,4,0,243,62,48 ,237,71,237,94,251,201
По просьбе корреспондента публикуем его адрес:
412820, Саратовская обл., г.Красноармейск, 5-микрорайон, д.10, кв.68, ОК & КО.
КОРР: "Прошу написать мне, если кто-нибудь может поделиться информацией о 3,5" дисководах".