⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aexp5.asm

📁 8253定时/计数器的发声实现程序
💻 ASM
字号:
;*------------------------------------------------------*/
;*    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(131,147,165,176,196,220,247)            ;"两只老虎"乐曲中,音符的频率(音阶)
     dw 2 dup(330,349,392)              ;其中,0频率表示结尾
     dw 2 dup(392,440,392)
     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 + -