Программирование Adlib/SoundBlaster
ЧМ Синтезатор
Версия 2.0 ( 24 февраля 1992 )
Авторское Право 1991 (c), 1992 Jeffrey S. Lee
jlee@smylex.uucp
Все числа в шестнадцетеричной системе, если специально не оговоренно.
Часть 1 - Порты звуковой карты
Звуковая плата программируется посылкой данных во внутренние регистры
через два порта ввода/вывода:
0x0388 - порт Адреса / Состояния (R/W)
0x0389 - порт Данных (W/O)
Sound Blaster Pro воспроизводит стерео музыку, обращение к каналам
происходит также, но базовый адрес для левого канала 0x220, правого
0x222. Sound Blaster совместим с Adlib. Через 0x388 и 0x389 порты
происходит вывод музыки через оба динамика.
В звуковой плате 244 внутренних регистра (01-F5). Для того чтобы
записать значение в регистр:
- запишите номер регистра в порт адреса;
- запишите значение в регистр данных.
После записи порт адреса надо 6 раз считать из него, перед посылкой
данных в регистр данных. После записи данных 30 раз, прежде, чем
можно будет снова продолжить программирование карты. В руководстве
по Adlib сказано, что ожидать надо 3.3 микросекунды для адреса,
и 23 мкс для данных.
Регистры звуковой карты только на запись.
Для того того чтобы прочитать байт состояния звуковой карты, просто
прочитайте порт 0x388. Байт состояния имеет следующую структуру:
7 6 5 4 3 2 1 0
+---------+--------+--------+------+------+------+------+------+
| Оба | таймер | таймер | Неиспользуется |
| таймера | 1 | 2 | |
+---------+--------+--------+------+------+------+------+------+
Бит 7 - установлен если оба таймера истекли.
6 - установлен если 1 таймер установлен.
5 - установлен если 2 таймер установлен.
Часть 2 - Регистры
В этой таблице приведены функции каждого регистра в звуковой карты.
Регистры объясняются после таблицы. Не приведенные регистры неиспользуются.
Адрес Функци
------- ----------------------------------------------------
01 Тест LSI / Выбор формы волны
02 Таймер 1
03 Таймер 2
04 Флаги управления Таймера
08 Речевой режим синтеза / Способ кодирования нот
20. .35 Тремоло / Вибрато / Постоянный уровень /
Изменение длительности / Умножение частоты
40. .55 Изменение уровня / Уровень сигнала ( громкость )
60. .75 Атака / Спад после атаки
80. .95 Постояный уровень / Затухание
A0.. A8 Частота ( 8 младших битов )
B0.. B8 Включить ноту / Октава / Частота ( 2 старших бита )
BD Глубина тремоло / вибрато / контроль ритма
C0.. C8 Величина обратной связи / режим обьединения цепей
E0.. F5 Форма волны
Группы из двадцати двух регистров ( 20-35, 40-55, и т.д.. ) содержат
информацию о 9 инструментах. Информация о каждом инструменте состоит
из байта описания цепи 1, и байта описания цепи 2. Следующая таблица
показывает смещения в пределах каждой группы регистров для каждой цепи.
Канал 1 2 3 4 5 6 7 8 9
Цепь 1 00 01 02 08 09 0A 10 11 12
Цепь 2 03 04 05 0B 0C 0D 13 14 15
Таким образом, адрес байта атака/спад для канала 3 - 62 для цепи 1,
и 65 для цепи 2. ( Адрес второй цепи - всегда равняется адрес первой
цепи плюс три ).
Чтобы иллюстрировать эту связь, приведены адреса необходимые чтобы
управлять каналом 5:
29 - Цепь 1 Тремоло
2C - Цепь 2 Тремоло
49 - Цепь 1 Уровень
4C - Цепь 2 Уровень
69 - Цепь 1 Атака
6C - Цепь 2 Атака
89 - Цепь 1 Затухание
8C - Цепь 2 Затухание
A4 - Частота ( 8 младших битов )
B4 - Включить ноту / Октава / Частота ( 2 старших бита )
C4 - Величина обратной связи / режим обьединения цепей
E9 - Цепь 1 Форма Волны
EC - Цепь 2 Форма Волны
Пояснения работы регистров карты
Байт 01 - Этот байт обычно используется чтобы проверять LSI устройство. Все
биты обычно установлены в ноль. Бит 5 разрешает выбор формы волны
0 - синусоидальная, 1 - определяется E0-F5
Байт 02 - Таймер 1. Если таймер 1 доступен, значение в этом
регистре будет увеличиваться пока не переполняется. После
переполнения, звуковая плата будет вызывать прерывание таймера
( int 08 ) и установит биты 7 и 6 в байте состояния. Счетчик
этого таймера увеличивается каждые 80 микросекунд.
Байт 03 - Таймер 2. Если таймер 1 доступен, значение в этом
регистре будет увеличиваться пока не переполняется. После
переполнения, звуковая плата будет вызывать прерывание таймера
( int 08 ) и установит биты 7 и 6 в байте состояния. Счетчик
этого таймера увеличивается каждые 320 микросекунд.
Байт 04 - Служебный байт таймера
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| IRQ | T1 | T2 | Неиспользуется | T2 | T1 |
| RST | MSK | MSK | | CTL | CTL |
+-----+-----+-----+-----+-----+-----+-----+-----+
сброс маски старт таймеров
таймера таймеров
Бит 7 - Сброс флажков таймеров 1 & 2. При этом
все другие биты игнорируются.
Бит 6 - Маска таймера 1. При установлен, то бит 0 игнорируется.
Бит 5 - Маска таймера 2. При установлен, то бит 1 игнорируется.
Бит 1 - Когда очищен, то таймер 2 не работает.
Когда установлен, значение из байта 03 загружаетс
в таймер 2, и начинается увеличиваться.
Бит 0 - Когда очищен, то таймер 1 не работает.
Когда установлен, значение из байта 02 загружаетс
в таймер 1, и начинается увеличиваться.
Байт 08 - Речевой режим синтеза / Способ кодирования нот.
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| CSM | Key | Неиспользуется |
| Sel | Spl | |
+-----+-----+-----+-----+-----+-----+-----+-----+
Бит 7 - Когда установлен, выбирает композитный режим синтеза речи
( все KEY-ON биты должен быть очищены ). Когда сброшен,
то выбор FM режима.
Бит 6 - Выбор режима кодирования нот.
Байты 20-35 - Тремоло / Вибрато / Постоянный уровень /
Изменение длительности / Умножение частоты
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| Amp | Vib | EG | KSR | Умножение частоты |
| Mod | | Typ | | |
+-----+-----+-----+-----+-----+-----+-----+-----+
"Тремоло" Постоянный
уровень
"Вибрато" Изменение
длительности
Бит 7 - Применяется "тремоло" когда установлено; глубина
управляется флажком AM-Depth по адресу BD.
Бит 6 - Применяется "вибрато" когда установлено; глубина
управляется флажком VIB-depth по адресу BD.
Бит 5 - Если установлен, постоянный уровень сигнала поддерживаетс
пока не отпущено; когда сброшен, звук начинается без задержки
после постоянной фазы.
Бит 4 - Когда установлен, то включает режим изменения длительности
сигнала с ростом частоты
Бит 3-0 - Эти биты указывают какая гармоника будет
воспроизводить звук ( или модуляцию ) в отношении частоты
воспроизводимого звука
( коэффициент умножения частоты )
0 - на одну октаву ниже
1 - в определеной частоте звука
2 - на одна октаву выше
3 - на октаву и пятый выше
4 - Две октавы выше
5 - Две октавы и мажор треть выше
6 - Две октавы и пятый выше
7 - Две октавы и минор седьмой выше
8 - Три октавы выше
9 - Три октавы и мажор секунда выше
A - три октавы и мажор треть выше
B - " """ """
C - три октавы и пятый выше
D - " """ " "
E - три октавы и мажор седьмой выше
F - " """ """
Байты 40-55 - Изменение уровня / Уровень сигнала ( громкость )
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| Изменение | Общий Уровень |
| Уровня | 24 12 6 3 1.5 .75 | < - dB
+-----+-----+-----+-----+-----+-----+-----+-----+
Биты 7-6 - устанавливают как будет уменьшатся выходной уровень
с ростом частоты:
00 - нет изменени
10 - 1.5 DB/8ve
01 - 3 DB/8ve
11 - 6 DB/8ve
Биты 5-0 - контролирует общий выходной уровень цепи.
Когда все биты очищены то самый громкий;
Когда все установлены то самый тихий.
Определяют уровень сигнала. Когда цепь включена
аддитивно или является генератором несущей,
они устанавливают громкость звучания.
Если цепь используется для генерации
модулирующего сигнала, эти разряды задают
глубину модуляции. Учтите, что громкость
от их содержимого зависит не линейно. При
увеличении на 1 уменьшается на 0.75 DB
Байты 60-75 - Атака / Спад после атаки
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| Скорость | Скорость |
| Атаки | Спада |
+-----+-----+-----+-----+-----+-----+-----+-----+
Биты 7-4 - скорость атаки. 0 - низкая, F - быстрая.
Биты 3-0 - скорость спада. 0 - низкая, F - быстрая.
Байты 80-95 - Постоянный уровень / Затухание
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| Постоянный Уровень | Скорость |
| 24 12 6 3 | затухания |
+-----+-----+-----+-----+-----+-----+-----+-----+
Биты 7-4 - постоянный Уровень. 0 самый громокий, F самый тихий.
Биты 3-0 - Скорость затухания. 0 - медленно, F самый быстрый.
Байты A0-B8 - Частота ( 8 младших битов ) /
Включить ноту / Октава / Частота ( 2 старших бита )
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| Восемь младщих битов частоты | (A0-A8)
| |
+-----+-----+-----+-----+-----+-----+-----+-----+
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+------+
| Неисполь- | Вкл | Октава |Два старших | (B0-B8)
| зуется | Ноту| |бита частоты|
+-----+-----+-----+-----+-----+-----+-----+------+
Эти регистры задают ноту и октаву для каждого из девяти
голосовых каналов. Отметим, что для работы с синтезатором
достаточно знать частоты нот в пределах одной октавы.
Бита 5 - Канал звучит когда установлен.
Биты 4-2 - Октава (0-7). 0 низкая, 7 высокая.
Биты 1-0 - Старшие биты частоты.
Кодирование нот в октаве 4:
Код Частота Нота
16B 277.2 C(#)(до#)
181 293.7 D (ре)
198 311.1 D(#)(ре#)
1B0 329.6 E (ми)
1CA 349.2 F (фа)
1E5 370.0 F(#)(фа#)
202 392.0 G(соль)
220 415.3 G(#)(соль#)
241 440.0 A(ля)
263 466.2 A(#)(ля#)
287 493.9 B(си)
2AE 523.3 C(до)
Байты C0-C8 - Величина обратной связи / режим обьединения цепей
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| Неиспользуется | Глубина | Alg |
| | Обратной Связи | |
+-----+-----+-----+-----+-----+-----+-----+-----+
Режим обьединения сигналов
колебательных цепей.
Биты 3-1 - Величина обратной связи. Если все три бита = 0,
то обратной связи нет. При значениях 1-7, цепь 1
будет посылать часть вывода обратно самостоятельно.
1 меньше 7 - максимум.
Бита 0 - Если = 0, то цепь 1 модулирует цепь 2. В этом случае,
только цепь 2 воспроизводит звук. Если = 1, обе
цепи воспроизводят звук. Комплексные звуки легко
создаются, если = 0.
Байт BD - Глубина тремоло / вибрато / контроль ритма
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+-----+
| AM | Vib | Rhy | BD | SD | TOM | Top | HH |
| Dep | Dep | Ena | | | | Cym | |
+-----+-----+-----+-----+-----+-----+-----+-----+
Глубина режим Малый барабан Тарелки
тремоло ударных включить включить
Глубина Большой Там-там
вибрато барабан включить
включить Цимбалы
включить
Бит 7 - задает глубину "тремоло" =1 - 4.8db, =0 - 1db.
Бит 6 - определяет глубину "вибрато" =1 - 14%, =0 - 7%.
Бит 5 - включает режим мелодии (0) ( 9 голосов )
или ударных (1) ( 6 голосов ).
Если установлен режим ударных используютс
биты с 4 по 0. Смещение регистров колебательных
цепей в этом режиме такое:
Канал 1 2 3 4 5 Большой Малай Там-там Цимбалы Тарелки
барабан барабан
Цепь 1 00 01 02 08 09 0A 14 12 15 11
Цепь 2 03 04 05 0B 0C 0D
Байты E0-F5 - Выбор Формы Волны
7 6 5 4 3 2 1 0
+-----+-----+-----+-----+-----+-----+-----+------+
| Неиспользуется | Выбор формы|
| | волны |
+-----+-----+-----+-----+-----+-----+-----+------+
Биты 1-0 - Когда бит 5 регистра 01 установлен, выходна
форма волны будут искажаться согласно форме волны
обозначенной этими двумя битами. Мы будем пробовать
изображать схематически их здесь, но это трудно
___ ___ ___ ___ _ _
/ \ / \ / \ / \ / | / |
/_____\_______ /_____\_____ /_____\/_____\ /__|___/__|___
\ /
\___/
00 01 10 11
Обнаружение Звуковой Платы
Согласно руководству AdLib, "официальный" метод обнаружения Adlib
1) Сбросьте оба таймера записав 60h в регистр 4.
2) Разрешите прерывания записав 80h в регистр 4.
3) Прочитайте регистр состояния ( порт 388-ой ). Сохраните результат.
4) Запишите FFh в регистр 2 ( Таймер 1 ).
5) Запустите таймер 1 записав 21h в регистр 4.
6) Сделайте задержку на 80 микросекунд.
7) Читайте регистр состояния ( порт 388-ой ). Сохраните результат.
8) Сбросьте и таймеры и прерывания ( см. шаги 1 и 2 ).
9) Проверите сохраненные результаты шагов 3 и 7 и AND их с E0h.
Результат шага 3 должен быть 00h, и результат шага 7 должен
быть C0h. Если это правильно, то AdLib-совместимая плата
устанавлена в ПЭВМ.
Другой метод:
PROC Detectadlib ;proc to detect adlib
stc ;set the carry flag (default)
pusha ;preserve regs
mov dx,0388h ;use the code posted by lee
in al,dx ;someone else suggested it...
cmp al,0 ;seems to work
je @@there ;adlib present, clear carry flag
cmp al,6 ;adlib not present if al<>0 OR 6
jne @@carryon ;and again...
;
@@there: clc ;clear cf, adlib is there
@@carryon:
popa ;restore our regs
ret ;return
ENDP ;end of detect adlib proc
Официальный метод
AdlibAddr dw 0388h
WriteFM PROC NEAR
push ax
push cx
push dx
xchg al,ah
mov dx, cs:AdlibAddr
out dx, al
mov cx,7
call FMwait
inc dx
mov al,ah
out dx,al
dec dx
mov cx,30
call FMwait
pop dx
pop cx
pop ax
ret
FMwait: in al,dx
loop FMwait
ret
WriteFM ENDP
;-----------------------------------------------------------------------------
;- Check for FM chip, returns CF = 0 if found, or CF = 1 if not --------------
;-----------------------------------------------------------------------------
TestFMchip proc far
mov ax, 00100h
Call WriteFM
mov ax, 00480h
Call WriteFM
mov dx, cs:AdlibAddr
in al, dx
mov cl, al
mov ax, 002FFh
Call WriteFM
mov ax, 00421h
Call WriteFM
mov dx, cs:AdlibAddr
mov cx, 100
call FMwait
mov ch, al
mov ax, 00460h
Call WriteFM
mov al, 80h
Call WriteFM
and cl, 0E0h
cmp cl, 0
jne No_FMchip
and ch, 0E0h
cmp ch, 0C0h
jne No_FMchip
popa
clc
ret
No_FMchip:
popa
stc
ret
TestFMchip endp
Примечания переводчика
Данный документ составлен Анисимовым С.Ю. 09/1995
Данными для составления этого документа послужила информация
из различных источников. Поэтому автор не несет ответственность
за неверную информацию, и за повреждения техники и тел при
использовании этого документа.
С наилучшими пожеланиями, для всех любителей программировать Adlib !
Vale !