📄 music.asm
字号:
data segment para 'data'
info1 db 0dh,0ah,'welcome you to come here!$' ;各种提示信息
info2 db 0dh,0ah,'this is a music program!$'
info3 db 0dh,0ah,'please select!$'
info4 db 0dh,0ah,'input error!$'
info5 db 0dh,0ah,'please input aging!$'
muslist db 0dh,0ah,'p play' ;p播放音乐
db 0dh,0ah,'q exit' ;q退出
db 0dh,0ah,'$' ;结束符
;******************************************************
mus_freg dw 330,392,330,294,330,392,330,294,330 ;音乐频率表
dw 330,392,330,294,262,294,330,392,294
dw 262,262,220,196,196,220,262,294,332,262,-1
mus_time dw 3 dup(50*8),25*8,25*8,50*8,25*8,25*8,100*8 ;音乐节拍时间表
dw 2 dup(50*8,50*8,25*8,25*8),100*8
dw 3 dup(50*8,25*8,25*8),100*8
;******************************************************
data ends
stack segment para stack 'stack' ;初始化堆栈
db 200 dup('stack')
stack ends
code segment
assume ds:data,ss:stack,cs:code
main proc far ;主程序
mov ax,data ;初始化DS
mov ds,ax
mov ah,0 ;设置显示方式
mov al,4 ;320*200 4色图形
int 10h
mov ah,0bh ;设置色调色板
mov bh,0
mov bl,1 ;bl=1蓝色背景色
int 10h
mov ah,0bh ;设置前景色
mov bh,01h
mov bl,00
int 10h
;***********定义一个宏**********
show macro b
lea dx,b
mov ah,9
int 21h
endm
;*********************************
show info1
show info2
show info3
show muslist
input: mov ah,01h
int 21h
cmp al,'q'
jz retu
cmp al,'p'
jnz exit
call music
jmp exit1
exit1: show info5
jmp input
exit: call clear
show info4
show info5
show info1
show info2
show info3
show muslist
jmp input
retu: mov ah,4ch
int 21h
main endp
;***********************************************************
;通用发生程序
gensound proc near
push ax ;保存将要用到的寄存器
push bx
push cx
push dx
push di
mov al,0b6h ;向8253-5/8254-2计数器2写控制字
out 43h,al ;方式3、双字节写和二进制计数方式写到控制口
mov dx,12h ;设置被除数
mov ax,533h*896
div di ;其商(AX)为预置值
out 42h,al ;先送LSB
mov al,ah
out 42h,al ;后送MSB
in al,61h ;读8255端口B(61H)原值
mov ah,al ;保存端口原值
or al,3 ;使PB0=1,PB1=1
;当PB0=1时,GATE2获得高电平,使定时器2在模式3(方波)下工作
;当PB1=1时,允许OUT2的输出信号到达扬声器
out 61h,al ;接通扬声器
wait1: mov cx,663 ;663*15.08us=10ms
call waitf
dec bx
jnz wait1
mov al,ah ;写回61H口原值,关闭扬声
out 61h,al
pop di ;恢复寄存器
pop dx
pop cx
pop bx
pop ax
ret ;子程序结束返回
gensound endp
;***********************************************************
;音乐演奏子程序
music proc near
push ds
sub ax,ax
push ax
lea si,mus_freg ;将频率表的偏移地址送入SI
lea bp,ds:mus_time ;将节拍时间表的偏移地址送入BP
freg: mov di,[si] ;取音符频率
cmp di,-1 ;结束?
je end_mus ;是,退出
mov bx,ds:[bp] ;取音符持续时间
call gensound ;调用GENSOUND发音子程序
add si,2 ;频率表指针增2
add bp,2 ;时间表指针增2
jmp freg ;继续演奏
end_mus:
ret ;返回DOS
music endp
;**********************************************************
waitf proc near
push ax
waitf1:
in al,61h
and al,10h
cmp al,ah
je waitf1
mov ah,al
loop waitf1
pop ax
ret
waitf endp
;***********************************************************
;清屏子程序
clear proc near
push ax
push bx
push cx
push dx
mov ah,6
mov al,0
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
int 10h
pop dx
pop cx
pop bx
pop ax
ret
clear endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -