📄 musicpro.asm
字号:
dseg segment para 'data'
dw 0 ;反向取频率的结束标志
musf dw 262,294,330,349,392,440,494,523,0 ;频率
;0是正向取频率1的结束标志
must dw 7 dup(5000),10000 ;发声时间
flag dw -1 ;-1正向取频率,0反向取频率,1结束
dseg ends
;******************************************************
cseg segment para 'data'
assume cs:cseg,ds:dseg
tone proc far
push ds
sub ax,ax
push ax
mov ax,dseg
mov ds,ax
lea si,musf ;si<-频率首址
next: lea bp,must ;bp<-时间首址
freq: mov di,[si] ;取一个频率
cmp di,0 ;频率为0(是结束符转)
je endf
mov bx,ds:[bp] ;取一个时间(数据段中用bp)
mov al,0b6h ;(al)=1011 0110
out 43h,al ;设置计数器2输出方波
;求计数值
mov dx,12h ;(dx,ax)=1234deH
mov ax,34deh ;时钟频率=1.1931818MHZ
div di ;(dx,ax)/di商ax是计数值
;写计数值
out 42h,al ;先写低字节计数值
mov al,ah ;后写高字节计数值
out 42h,al
in al,61h ;置61H口b0,b1位为1
mov ah,al ;保存61H口原值
or al,3 ;b0为1打开定时器2
out 61h,al ;b1为1打开与门
long: mov cx,2801*10 ;延时(发声期间)
delay: loop delay
dec bx
jnz long
mov al,ah ;恢复61H口
out 61h,al
test flag,1 ;flag的b0为转反方向取频率
jz lower
add si,2 ;频率偏移加2(正取向)
jmp cont
lower: sub si,2 ;频率偏移减2(反取向)
cont: add bp,2 ;时间偏移加2
jmp freq
endf: inc flag ;正向发声结束flag+1(为0)
;反向发声结束falg+1(为1)
jnz exit ;为1转结束
sub si,2 ;偏移减2(反向取)
jmp next
exit: mov al,48h
out 61h,al
ret
tone endp
;-------------------------------------------------------
cseg ends
;********************************************************
end tone
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -