?? yiyuekongzhi.txt
字號:
sstack segment stack
dw 200 dup(?)
sstack ends
data segment
bg db 'Two tigers ...'
db 0ah,0dh
db 'press any key to stop! ',0ah,0dh,'$'
freq dw 2 dup(262,294,330,262) ;"兩只老虎"樂曲中,音符的頻率(音階)
dw 2 dup(330,349,392) ;其中,0頻率表示結尾
dw 2 dup(392,440,392,349,330,262)
dw 2 dup(294,196,262),0
time dw 10 dup(8),16,8,8,16 ; "兩只老虎"樂曲中,音符的延時(節拍)
dw 2 dup(4,4,4,4,8,8) ;其中4,8,16表示延時的次數
dw 2 dup(8,8,16)
old_seg dw ?
old_off dw ?
data ends
code segment
assume cs:code, ds:data, ss:sstack
star proc far ;程序開始
mov ax,data
mov ds,ax
mov ax,sstack
mov ss,ax
push di ;寄存器壓棧
push si
push bp
push bx
mov al,90h ;8255初始化
mov dx,303h
out dx,al
mov al,0ch ;關閉8253的T2計數器(8255的PC6=0)
mov dx,303h
out dx,al
mov al,00h ;關閉喇叭(8255的PC0=0)
mov dx,303h
out dx,al
mov al,0b6h ;8253初始化
mov dx,307h
out dx,al
mov dx,offset bg ;顯示提示信息
mov ah,9
int 21h
mov si,offset freq ;設置頻率指針→si
mov bp,offset time ;設置延時指針→bp
pp: mov ah, 0bh ;檢測是否有任意鍵按下?
int 21h
cmp al,00
jne end_sing ;若有,則結束演湊
mov di,[si] ;取1個音符的頻率→di
cmp di,0 ;檢測是否是樂曲結尾
je end_sing ;若是,則結束演湊
mov dx,12h ;計算音符的頻率所對應的8253計數初值
mov ax,34dch ;1.19318MHz
div di
mov dx,306h ;向8253裝入計數初值
out dx,al ;先裝低字節
mov al,ah
out dx,al ;再裝高字節
mov dx,303h ;打開喇叭(8255的PC0=1)
mov al,01h
out dx,al
mov al,0dh ;打開8253的T2(PC6=1),開始發聲
out dx,al
mov bx,ds:[bp] ;取1個音符的延時次數→bx
call time_delay ;調用延時子程
mov dx,303h ;關閉8253的T2(PC6=0)
mov al,0ch
out dx,al
mov al,00h ;關閉喇叭(PC0=0)
out dx,al
add si,2 ;取下1 個音符的頻率
add bp,2 ;取下1 個音符的延時次數
jmp pp ;繼續
end_sing:
mov dx, 303h ;關閉8253的T2
mov al, 0ch
out dx, al
mov al, 00h ;關閉喇叭
out dx, al
pop bx ;寄存器出棧
pop bp
pop si
pop di
mov ax,4c00h ;返回DOS
int 21h
star endp
new_intr proc ;新中斷服務程序
dec bx ;該服務程序只將延時次數-1
iret
new_intr endp
time_delay proc near ;延時子程序
pushf ;壓棧
push ds
push es
push bx
mov ah,35h ;取原中斷(INT1CH)的向量,并保存
mov al,1ch
int 21h
mov old_off, bx
mov bx, es
mov old_seg, bx
pop bx
pop es
push ds
mov ah, 25h ;設置新中斷服務程序的向量
mov al, 1ch
mov dx, seg new_intr
mov ds,dx
lea dx, new_intr
int 21h
pop ds
TD: cmp bx,0h ;延時次數已到?
jnz TD ;未到,則繼續
mov ah,25h ;已到,則恢復原中斷向量
mov al,1ch
mov dx,old_seg
push dx
mov dx,old_off
pop ds
int 21h
pop ds
popf
;time delay end
ret
time_delay endp
code ends
end star ;程序結束
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -