Уч. пособие к лабораторной работе Программирование системных устройств (1015477), страница 3
Текст из файла (страница 3)
pop di
pop dx
pop cx
pop bx
pop ax
ret
sound endp
convert proc near
; Преобразование числа в ASCII-код
; [AX] - преобразуемое число,
; [DS]:[DI] - адрес буфера для размещения ASCII-кода
push ax ; сохраняем число
mov al,'0' ; заполняем...
mov cx,2 ; 2 байта буферной...
rep stosb ; области нулями
pop ax ; восстанавливаем число
mov cx,10 ; записываем основание системы счисления
conloop:xor dx,dx ; очищаем старший байт делимого
div cx ; делим [DX,AX] на 10
add dl,30h ; превращаем цифру остатка в ASCII-код
dec di ; продвигаем указатель буфера на 1 байт назад
mov [di],dl ; записываем в буфер ASCII-код цифры
cmp ax,0 ; результат деления на 10 нулевой?
jnz conloop ; возврат, если результат ненулевой
ret
convert endp
beep proc far
; запуск процедуры sound
push ds
sub ax,ax
push ax
mov bx,adata
mov ds,bx
mov es,bx
mov bx,1000 ; задаем длительность 1000 * 0.01 = 10 с
mov di,440 ; задаем частоту 440 Гц (звук Ля первой октавы)
call sound
ret
beep endp
start ends
end beep
Исходный код подпрограмм файла «playsnd.asm »
; Программа проигрывания мелодии, заданной таблицей частот, которая
; расположена по адресу freq и таблицей длительностей нот – по адресу time
;
; Структура вызова подпрограмм и расположения данных
; __________ __________ __________ __ ___ __
; | proc | | proc | | proc | | |
; | melody |---->| play |<--->| sound |--->| динамик |
; |__________| |__________| |__________| |__ ___ __|
; Δ
; |
; ____V_____
; | adata |
; | segment |
; |__________|
;
;
;
astack segment para stack 'stack'
db 64 dup(?)
astack ends
adata segment para 'data'
;
; Таблица частот:
freq dw 330,294,262,294,3 dup(330)
dw 3 dup(294),330,392,392,0ffffh
;
; Таблица длительностей:
time dw 6 dup(25),50
dw 2 dup(25,25,50)
;
adata ends
;
acode segment
assume ds:adata, cs:acode, ss:astack
play proc near
; Проигрывание мелодии с параметрами, заданными в регистрах:
; [SI] - адрес таблицы частот, заканчивающейся байтом 0FFFFH
; [BP] - адрес таблицы длительностей в 1/100 сек.
; целая_нота=200, 1/2=100, 1/4=50, 1/8=25, 1/16=12
push bx
push di
push si
push bp
zvuk: mov di,[si] ; загрузка частоты ноты из таблицы
cmp di,0ffffh ; проверка на достижение конца
je end_play ; условный выход из цикла
mov bx,ds:[bp] ; загрузка длительности ноты
call sound ; вызов генератора звука
add si,2 ; продвижение по таблице частот
add bp,2 ; продвижение по таблице длительностей
jmp zvuk ; переход к следующей ноте
end_play: pop bp
pop si
pop di
pop bx
ret
play endp
sound proc near
; Генерация сигнала заданной частоты и длительности
; [DI] - частота сигнала в Гц
; [BX] - длительность сигнала в 1/100 сек.
push ax
push bx
push cx
push dx
push di
mov al,0B6h ; задание номера счетчика и выбор режима его работы
out 43h,al
mov dx,0010h ; вместо 0010h подставьте значение двух старших байта входной частоты
mov ax,1000h ; вместо 1000h подставьте два младших байта входной частоты в Гц
div di
out 42h,al
jcxz $+2
jcxz $+2
mov al,ah
out 42h,al
in al,61h
mov dl,al
or al,3
out 61h,al
wt: mov cx,30000 ; вместо 30000 указать точное количество повторения цикла
spkon: jcxz $+2 ; вставить нужное
jcxz $+2 ; количество
loop spkon ; команд задержки
dec bx
jnz wt
mov al,dl
out 61h,al
pop di
pop dx
pop bx
pop cx