Assembler - язык неограниченных возможностей


Команды DSP - часть 5


; процедура reprogram_pit ; перепрограммирует канал 0 системного таймера на новую частоту ; Ввод: ВХ = делитель частоты reprogram_pit proc near cli ; запретить прерывания mov al,00110110b ; канал 0, запись младшего и старшего байт ; режим работы 3, формат счетчика - двоичный out 43h,al ; послать это в регистр команд первого таймера mov al,bl ; младший байт делителя - out 40h,al ; в регистр данных канала 0 mov al,bh ; и старший байт - out 40h,al ; туда же sti ; теперь IRQO вызывается с частотой ; 1 193 180/ВХ Hz ret reprogram_pit endp

; процедура hook_int8 ; перехватывает прерывание INT 08h (IRQ0) hook_int8 proc near mov ax,3508h ; AH = 35h, AL = номер прерывания int 21h ; получить адрес старого обработчика mov word ptr old_int08h,bx ; сохранить его в old_int08h mov word ptr old_int08h+2,es mov ax,2508h ; AH = 25h, AL = номер прерывания mov dx,offset int08h_handler ; DS:DX - адрес обработчика int 21h ; установить обработчик ret hook_int8 endp

; процедура restore_int8 ; восстанавливает прерывание INT 08h (IRQ0) restore_int8 proc near mov ax,2508h ; AH = 25h, AL = номер прерывания lds dx,dword ptr old_int08h ; DS:DX - адрес обработчика int 21h ; установить старый обработчик ret restore_int8 endp

; процедура open_file ; открывает файл filename и копирует звуковые данные из него, ; считая его файлом tada.wav, в буфер buffer open_file proc near mov ax,3D00h ; AH = 3Dh, AL = 00 mov dx,offset filename ; DS:DX - ASCIZ-имя файла с путем int 21h ; открыть файл для чтения, jc error_exit ; если не удалось открыть файл - выйти mov bx,ax ; идентификатор файла в ВХ mov ax,4200h ; АН = 42h, AL = 0 mov сх,0 ; CX:DX - новое значение указателя mov dx,38h ; по этому адресу начинаются ; данные в tada.wav int 21h ; переместить файловый указатель mov ah,3Fh ; АН = 3Fh mov cx,27459 ; это - длина звуковых данных ; в файле tada.wav mov dx,offset buffer ; DS:DX - адрес буфера int 21h ; чтение файла ret error_exit: ; если не удалось открыть файл mov ah,9 ; АН = 09h mov dx,offset notopenmsg ; DS:DX = сообщение об ошибке int 21h ; открыть файл для чтения int 20h ; конец программы notopenmsg db "Ошибка при открытии файла",0Dh,0Ah,'$' open_file endp

buffer: ; здесь начинается буфер длиной 27 459 байт end start

Если вы скомпилировали программу latency.asm из главы 5.10.5 и попробовали запустить ее в разных условиях, то могли заметить, что под Windows 95, а также под EMM386 и в некоторых других ситуациях пауза между реальным срабатыванием прерывания таймера и запуском обработчика может оказаться весьма значительной и варьироваться с течением времени, так что качество звука, выводимого нашей программой wavdir.asm, окажется под EMM386 очень плохим, а в DOS-задаче под Windows 95 вообще получится протяжный хрип. Чтобы этого избежать, а также чтобы указывать точную скорость оцифровки звука и выводить 16-битный звук, нам надо обратиться к программированию контроллера DMA (пример программы, выводящей звук при помощи DMA, см. в конце следующей главы).





Начало  Назад  Вперед