📄 music.asm
字号:
;**************************************
; 音乐播放
;**************************************
data segment
dlogo db 13,10,' Welcom to use the music player',13,10,13,10,'$'
dplay db ' 1.Play music',13,10,'$' ;播放音乐
dadd db ' 2.Add music',13,10,'$' ;添加乐曲
ddel db ' 3.Delete music',13,10,'$' ;删除乐曲
dquit db ' 4.Exit(Q)',13,10,'$' ;退出系统
dselect db 13,10,'Please select a music',13,10,'$' ;选择一首音乐
dinname db 13,10,'Please input a music name:',13,10,'$' ;输入乐曲名
dinmusi db 13,10,'Please input musical composition:',13,10,'$';输入乐曲
dquest1 db 13,10,'Do you give it up?(Y/N)',13,10,'$' ;是否放弃输入
dquest2 db 13,10,'Are you sure?(Y/N)',13,10,'$' ;确定删除/退出
dret db '0.Return',13,10,'$'
dwarn db 13,10,'Warning: Music table is full!!',13,10,'$'
dinnum db 'Please input the number of playing:','$'
dname db 21,?,21 dup(?) ;输入乐曲名
dfreq db 4,?,4 dup(?) ;输入乐曲频率
dtime db 4,?,4 dup(?) ;输入乐曲时间延迟
dtishi db 13,10,'The part is not finished!',13,10,'Press any key to return...',13,10,'$'
nametab db 'example',13 dup(?),'$','tai hui chuan',7 dup(?),'$'
db 7 dup(20 dup(?),'$') ;存放乐曲名的表
freqtab dw 320,294,262,294,3 dup(330),3 dup(294),330,392,392,330,294,262,294,4 dup(330),294,294,330,294,262,-1,23 dup(?)
;太湖船
dw 330,292,330,294,330,292,330,294,330,330,292,330,294,262,294,330,392,294,262,262,220,196,196,220,262,294,330,262,-1,21 dup(?)
dw 7 dup(50 dup(?)) ;存放乐曲频率的表
timetab dw 6 dup(25),50,2 dup(25,25,50),12 dup(25),100,24 dup(?)
dw 3 dup(50),25,25,50,25,25,100,2 dup(50,50,25,25),100,3 dup(50,25,25),100,22 dup(?)
dw 7 dup(50 dup(?)) ;存放乐曲时间延迟的表
namead db 1,1,7 dup(0),9 dup(?,?) ;存放乐曲名的地址表
freqad db 9 dup(?,?) ;存放乐曲频率的地址表
timead db 9 dup(?,?) ;存放乐曲时间延迟的地址表
data ends
;**************************************
code segment
main proc far
assume cs:code,ds:data,es:data
Start:
mov ax,data
mov ds,ax
mov es,ax
;-------------初始化地址表--------------
mov cx,9
lea ax,nametab
lea bx,namead
lea dx,freqtab
lea si,freqad
lea bp,timetab
lea di,timead
L1:
mov [bx+9],ax
mov [si+9],dx
mov [di+9],bp
add ax,21
add bx,2
add dx,100
add si,2
add bp,100
add di,2
loop L1
;--------------初始化界面---------------
Begin:
lea dx,dlogo
mov ah,09
int 21h
lea dx,dplay
int 21h
lea dx,dadd
int 21h
lea dx,ddel
int 21h
lea dx,dquit
int 21h
;--------------功能选择-----------------
mov ah,1
int 21h ;接收选择
mov cl,al
mov dl,13
mov ah,2
int 21h
mov dl,10
int 21h ;换行
mov al,cl
cmp al,31h
jz play
cmp al,32h
jz addm
cmp al,33h
jz del
cmp al,34h
jz exit
cmp al,81
jz exit
cmp al,113
jz exit
jmp Begin
;--------------播放音乐------------------
play:
lea dx,dplay
mov ah,9
int 21h
lea dx,dselect
int 21h
;显示乐曲列表
mov cx,9
mov si,0
mov dl,30h
lea bx,namead
mov di,9
L2:
mov al,[bx+si]
cmp al,1 ;检查此地址是否被使用
jnz L3
inc dl ;乐曲序号+1
mov ah,02
int 21h ;显示乐曲序号
push dx ;保存dl
mov dl,2eh
int 21h
mov ah,9
mov dx,[bx+di]
int 21h ;显示乐曲名
mov dl,13
mov ah,2
int 21h
mov dl,10
int 21h ;换行
pop dx ;还原dl
L3:
inc si
add di,2
loop L2
mov ah,9
mov cl,dl ;cl-乐曲总数
lea dx,dret
int 21h ;显示返回
;--------------选择乐曲------------------
mov ah,01
int 21h
push ax
mov dl,13
mov ah,2
int 21h
mov dl,10
int 21h ;换行
pop ax
sub al,30h
cmp al,0
js play
jz Begin ;输入0则返回
cmp al,cl
jg play ;大于乐曲总数
;-----------求乐曲物理序号---------------
mov ch,0
mov cl,al
mov si,0
L4:
jcxz L6
mov dl,[bx+si] ;bx-namead首地址
inc si
dec cx
cmp dl,1
jnz L5
jmp L4
L5:
inc cx
inc al ;al-物理序号
jmp L4
L6:
push ax ;保存物理序号
lea dx,dinnum ;输入播放的次数
mov ah,9
int 21h
mov ah,1
int 21h
mov cl,al
mov dl,13
mov ah,2
int 21h
mov dl,10
int 21h ;换行
sub cl,30h ;播放次数
jz play
pop ax
dec al
call music ;播放al指定的乐曲cl次
jmp play
;--------------添加乐曲------------------
addm:
;功能未添加
lea dx,dtishi
mov ah,9
int 21h
mov ah,7
int 21h ;按任意键返回
jmp Begin
;--------------删除乐曲------------------
del:
;功能未添加
lea dx,dtishi
mov ah,9
int 21h
mov ah,7
int 21h ;按任意键返回
jmp Begin
;--------------退出程序------------------
exit:
lea dx,dquest2
mov ah,9
int 21h
mov ah,1
int 21h
cmp al,79h
jz ende
cmp al,59h
jnz Begin
ende:
mov ax,4300h
int 21h ;返回Dos
main endp
;------------播放音乐函数----------------
music proc near
push si
push di
push bp
push bx
mov ch,0
mov bl,100
mul bl ;求频率/时间地址偏离freqtab/timetab的大小
conti:
lea si,freqtab
lea bp,timetab
add si,ax ;si-频率地址
add bp,ax ;bp-时间地址
freq:
mov di,[si]
cmp di,-1
jz end_mus ;频率值为-1则乐曲结束
mov bx,[bp]
call soundf
add si,2
add bp,2
jmp freq
end_mus:
loop conti ;重复播放cx次
pop bx
pop bp
pop di
pop si
ret
music endp
;------------播放声音函数----------------
soundf proc near
push ax
push bx
push cx
push dx
push di
mov al,0b6h
out 43h,al ;发送控制信号
mov dx,12h
mov ax,348ch
div di
out 42h,al ;设置计数次数
mov al,ah
out 42h,al
in al,61h
mov ah,al
or al,3
out 61h,al ;接通扬声器
swait:
mov cx,663
call waitf
dec bx
jnz swait ;发声bx个10ms长的时间
mov al,ah
out 61h,al ;还原PPI的值
pop di
pop dx
pop cx
pop bx
pop ax
ret
soundf endp
;------------延时函数------------------
waitf proc near
push ax
wwait:
in al,61h
and al,10h
cmp al,ah
jz wwait
mov ah,al
loop wwait ;暂停cx个15.8us长的时间
pop ax
ret
waitf endp
code ends
end Start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -