Для генерации звука необходимо использовать порты микросхемы программируемого переферийного интерфейса (ППИ) 8255. ППИ имеет несколько портов, через которые внешние устройства могут подключаться к ЦП. Через ППИ компьютер принимает скан-коды от клавиатуры, считывает состояние DIP-переключателей на системной плате, управляет рядом переферийных устройств, включая микросхему таймера 8253. IBM PC/AT не использует микросхему 8255. Вместо нее установлен клавиатурный процессор 8042, однако, IBM PC/AT использует те же адреса портов, что и 8255 для работы с клавиатурой и управления таймером. Управление динамиком осуществляется с помощью двух бит порта 61h ППИ. Бит 0 этого порта подключен ко входу GATE2. Занесение 1 в этот бит разрешает счет канала 2 таймера. Бит 1 разрешает или запрещает прохождение импульса на динамик.
На вход динамика поступает логическое «И» двух сигналов: выхода OUT2 таймера и содержимого бита 1 порта 61h. Необходимо отметить, что при запрещении счета канала 2, когда GATE2=0, на выходе OUT2 устанавливается 1. При совпадении двух сигналов на динамик подается прямоугольный импульс, который слышится как щелчок. Так как динамик управляется двумя сигналами, то и генерация звука может быть произведена двояко:
- запретить работу канала 2 (бит 0 сброшен, OUT2=1), переключать бит 1, каждое переключение вызывает щелчок; скорость переключения бита 1 определяет частоту звучания;
- разрешить работу канала 2 (бит 0 установлен), включить динамик (бит 1 установлен), скорость переключения и OUT2 определяет частоту звучания.
Учитывая, что остальные биты порта 61h используются для работы с другими устройствами и не должны изменяться, установку битов 0 и 1 следует проводить командами OR и AND. Для программирования канала 2 таймера так, чтобы он выдавал импульсы с частотой, лежащей в звуковом диапазоне (20-20 000 Гц), следует использовать режим таймера 3 и установить (CR) == 1193180/f, где f - требуемая частота звука.
Пример:
; подпрограмма генерации звука
; Вход: (АХ)= частота звука в Гц
Sound proc near
mov bx,ax ;частота
mov ax, free
mov dx,frec+2 ;(dx:ax)=l 193180
div bx ;ax=(dx:ax)/bx
mov bx,a ;сохранить счетчик таймера
in al,61h ;разрешить счет канала 2
or al,3 ;и разрешить работу динамика
out 61h,a1
mov al,10110110b ;управляющее слово таймера: канал 2,