📄 8255.txt
字号:
;*------------------------------------------------------*/
;* Aexp5.asm(音乐发生器接口实验) */
;* 音乐发生器程序Source File */
;* Copyright (c) 2001 by HUST */
;*------------------------------------------------------*/
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 + -