stack segment para stack 'stack'
db 64 dup('stack...')
stack ends
;---------------------------------------------------------------------------------------
data segment para 'data'
mus_freq dw 330,294,262,294,3 dup(330) ; bar 1 &2
dw 3 dup(294),330,392,392 ; bar 3 &4
dw 330,294,262,294,4 dup(330) ; bar 5 &6
dw 294,294,330,294,262, -1 ; bar 7 &8
mus_time dw 6 dup(25),50 ; bar 1 &2
dw 2 dup(25,25,50) ; bar 3 &4
dw 12 dup(25),100 ; bar 5 &6
data ends
;---------------------------------------------------------------------------------------
code segment para 'code'
music proc far
assume cs:code ,ss:stack ,ds:data
start:
push dx
mov ax, 0
push ax
mov ax,data ;initialize DS
mov ds,ax
mov ax, stack
mov ss, ax
lea si, mus_freq
lea bp, ds:mus_time
freq:
mov di,[si]
cmp di, -1
je end_mus
mov bx, ds:[bp]
call gensound
add si, 2
add bp, 2
jmp freq
end_mus:
ret
music endp
gensound proc near
push ax
push bx
push cx
push dx
push di
mov al, 0b6h ;10110110 即将计数器2设定为模式3
out 43h, al ;send it to control register
;使AX中得到送往定时器2的计数值
mov dx, 12h ;timer divisor
mov ax, 348ch
div di ;119130/(given size)
out 42h, al ;给计数器2装入计数值x从而产生对应赫兹的频率
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 3 ;make pb0=1 pb1=1
out 61h, al ;turn the speaker on
wait1: mov cx, 2800 ;wait for sepcified interval
delay: loop delay
dec bx
jnz wait1
mov al, ah ;recover value of port
out 61h, al ;recover the register
pop di
pop dx
pop cx
pop bx
pop ax
ret
gensound endp
code ends
end start |