📄 music.asm
字号:
;数据段--------------------------------------------------------------
data segment
;声调标志tone:0为High Tone, 1为Normal Tone, 2为Low Tone
;速度标志speed:0为High Speed,1为Normal Speed,2为Low Speed
tone dw 1
speed dw 1
;显示菜单界面的字符串
out1 db '************MENU***************',0ah,0dh
db '* *',0ah,0dh
db '* 1.Zhi Pa Bu Di Kang *',0ah,0dh ;1.只怕不抵抗
db '* 2.Jie Fang Qu De Tian *',0ah,0dh ;2.解放区的天
db '* 3.Da Dao Jin Xing Qu *',0ah,0dh ;3.大刀进行曲
db '* *',0ah,0dh
db '* 4.High Tone *',0ah,0dh ;4.高声调
db '* 5.Normal Tone *',0ah,0dh ;5.正常声调
db '* 6.Low Tone *',0ah,0dh ;6.低声调
db '* *',0ah,0dh
db '* 7.High Speed *',0ah,0dh ;7.高速
db '* 8.Normal Speed *',0ah,0dh ;8.正常速度
db '* 9.Low Speed *',0ah,0dh ;9.低速
db '* *',0ah,0dh
db '* 0.EXIT *',0ah,0dh ;0.退出
db '* *',0ah,0dh
db '*******************************',0ah,0dh,'$'
;显示功能选择的字符串
out2 db 0ah,0dh,0ah,0dh,'Please choice 0-9 :$'
;提示音乐开始演奏的字符串
out3 db 0ah,0dh,0ah,0dh,' Now music playing...$'
;提示按任意键继续
tishi1 db 0ah,0dh,0ah,0dh,'press any key to continue.$'
;----简谱低八度音符:d1..d7---
d1 equ 131
d2 equ 147
d3 equ 165
d4 equ 175
d5 equ 196
d6 equ 220
d7 equ 247
;----简谱中度音符:z1..z7-----
z1 equ 262
z2 equ 294
z3 equ 330
z4 equ 349
z5 equ 392
z6 equ 440
z7 equ 494
;----简谱高八度音符:g1..g7---
g1 equ 524
g2 equ 588
g3 equ 660
g4 equ 698
g5 equ 784
g6 equ 880
g7 equ 984
;--------节拍节奏------------
t1 equ 100
t2 equ 200
t3 equ 300
t4 equ 400
t5 equ 500
t6 equ 600
t7 equ 700
t8 equ 800
t9 equ 1200
t0 equ 1600
;----------------------------
;第1段音乐的音符表和节奏表
yf1 dw z3,z3,z3,z1,z2, d6,z3,d6,z3,z2
dw z1,z2,z1,z1,d5, d6,d5,d6,z1,d5
dw z3,z3,z3,z5,z2, z3,z5,z3,z5,z1
dw z3,z3,z4,z5,z3, z3,z3,z1,z3,z2
dw z1,z2,z1,z3,z1, z3,z5,z3,d6,z1
dw z3,z3,z3,z1,z2, d6,z3,d6,z3,z2
dw z1,z2,z1,z1,d5, d6,d5,d6,z1,d5
dw z1,z2,z1,z3,z1, z3,z5,z3,d6,z1
dw d6,z1,z3,z2,z1
dw -1
jz1 dw t8,t8,t8,t8,t9, t2,t4,t2,t4,t0
dw t8,t8,t8,t8,t0, t4,t4,t4,t4,t0
dw t8,t8,t9,t4,t9, t4,t0,t9,t4,t0
dw t4,t4,t4,t4,t9, t4,t4,t4,t4,t0
dw t4,t4,t4,t4,t9, t4,t8,t8,t8,t0
dw t8,t8,t8,t8,t9, t2,t4,t2,t4,t0
dw t8,t8,t8,t8,t0, t4,t4,t4,t4,t0
dw t4,t4,t4,t4,t9, t4,t8,t8,t8,t0
dw t4,t8,t6,t2,t0
dw 400,400,400,400
;第2段音乐的音符表和节奏表
yf2 dw g3,g3,g3,g2,g3,g2,g1,g1,z3,z5
dw g3,g3,g3,g2,g3,g3,g1,g1,z5
dw z6,z5,z6,z5,z6,g1,z3,z5
dw z6,z6,z6,z5,z6,z6,z5,g1,g1,z2
dw z3,z5,g1,z6,z5,z3,z5
dw z6,g1,g2,g1,g2, g3,g2,g1
dw g2,g2,z5,z6,g1,g3, g2,g1,z6,g1
dw -1
jz2 dw t2,t2,t2,t2,t6,t2,t4,t2,t2,t8
dw t2,t2,t2,t2,t4,t4,t4,t4,t8
dw t6,t2,t6,t2,t4,t4,t4,t4
dw t2,t2,t2,t2,t4,t4,t4,t4,t4,t6
dw t2,t4,t4,t2,t2,t4,t8
dw t6,t2,t6,t2,t8, t6,t2,t8
dw t4,t4,t6,t2,t4,t4, t2,t2,t4,t8
dw 400,400,400,400
;第3段音乐的音符表和节奏表
yf3 dw g1,g1,g1,z5,z6,z5,z3,z1,z3,z5,z6
dw z6,z6,z6,z5,z6,z3,z5,z2
dw z2,z2,z2,z1,z2,z3,z2,z5
dw g1,g1,g1,g2,g1,z6,g1,z5
dw z2,z2,z3,z6,z6,z3,z5,z5,z5
dw z6,z6,z5,g1,z7,z6,z5,z6,z3
dw z5,z6,g1,z7,z6,z5,z2,z3,z5,z5
dw z6,z5,z6,g1,g1, z6,z5,g1,g1, z6,z5,g2,g2
dw g1,g1,g1,z5,z6,z5,z3,g1,g3,g2,g1
dw -1
jz3 dw t6,t9,t0,t6,t2,t6,t2,t9,t4,t0,t0
dw t6,t2,t4,t2,t2,t9,t4,t0
dw t8,t6,t2,t9,t4,t6,t2,t8
dw t4,t8,t4,t9,t4,t8,t8,t0
dw t8,t6,t2,t8,t6,t2,t9,t4,t0
dw t4,t8,t4,t8,t6,t2,t8,t8,t8
dw t2,t2,t6,t2,t4,t4,t9,t4,t4,t9
dw t8,t6,t2,t4,t9, t2,t2,t4,t8, t2,t2,t4,t0
dw t4,t9,t0,t6,t2,t6,t2,t9,t4,t0,t0
dw 400,400,400,400
data ends
;代码段----------------------------------------------------
code segment
assume cs:code,ds:data
;主程序----------------------------------------------
main proc far
;数据段地址装入数据段寄存器
mov ax,data
mov ds,ax
;显示菜单界面
lea dx,out1
mov ah,9
int 21h
;显示功能选择
lea dx,out2
mov ah,9
int 21h
repeat: mov ah,7
int 21h ;等待键盘输入,无回显
cmp al,'0'
jb repeat
cmp al,'9'
ja repeat ;输入不为0-9,重新输入
mov dl,al
mov ah,2
int 21h ;输入正确,显示输入数字
cmp al,'0'
jz p0 ;输入为'0',退出
cmp al,'1'
jz p1 ;输入为'1',演奏第1段音乐
cmp al,'2'
jz p2 ;输入为'2',演奏第2段音乐
cmp al,'3'
jz p3 ;输入为'3',演奏第3段音乐
cmp al,'4' ;输入为'4',高声调
jz p4
cmp al,'5' ;输入为'5',正常声调
jz p5
cmp al,'6' ;输入为'6',低声调
jz p6
cmp al,'7' ;输入为'7',高速
jz p7
cmp al,'8' ;输入为'8',正常速度
jz p8
cmp al,'9' ;输入为'9',低速
jz p9
p0: mov ah,4ch
int 21h
p1: ;取第1段音乐的音符表和节奏表
mov si,offset yf1
mov di,offset jz1
call play1 ;调用play1,演奏音乐
jmp repeat1
p2: ;取第2段音乐的音符表和节奏表
mov si,offset yf2
mov di,offset jz2
call play1 ;调用play1,演奏音乐
jmp repeat1
p3: ;取第3段音乐的音符表和节奏表
mov si,offset yf3
mov di,offset jz3
call play1 ;调用play1,演奏音乐
jmp repeat1
p4: mov tone,0
jmp repeat1
p5: mov tone,1
jmp repeat1
p6: mov tone,2
jmp repeat1
p7: mov speed,0
jmp repeat1
p8: mov speed,1
jmp repeat1
p9: mov speed,2
jmp repeat1
repeat1:
;press any key to continue
lea dx,tishi1
mov ah,9
int 21h
mov ah,7
int 21h
call cls
;显示菜单界面
lea dx,out1
mov ah,9
int 21h
;显示功能选择
lea dx,out2
mov ah,9
int 21h
jmp repeat
ret
main endp
;演奏音乐------------------------------------------
play1 proc near
push ax
push bx
push cx
push dx
;press any key to continue
lea dx,tishi1
mov ah,9
int 21h
mov ah,7
int 21h
call cls
;提示音乐开始演奏
lea dx,out3
mov ah,9
int 21h
;演奏该段音乐
rep1: mov cx,[si] ;cx存放音符
cmp cx,-1
je exit ;已经到音符表表尾,演奏结束
mov bx,[di] ;bx存放节拍节奏
;一对音符和节拍节奏的发声处理
;-------------------------------------------------------------------------
mov al,0b6h ;向计数器写控制字
out 43h,al ;方式3、双字节写和二进制计数方式写到控制口
;预设被除数(dx,ax)的值
mov dx,12h
mov bp,tone
cmp bp,0
jz sp0
cmp bp,2
jz sp2
jmp sp1
sp0: mov dx,4h
jmp sp1
sp2: mov dx,20h
sp1: mov ax,348CH
div cx ;除以频率,其商ax为计数值
out 42h,al ;计数值先送低8位
mov al,ah
out 42h,al ;计数值后送高8位
in al,61h ;取得设备控制寄存器的开关量
mov ah,al ;原开关量保存到ah
or al,3 ;第0位和第1位置1
out 61h,al ;现开关量输出以接通扬声器
push ax
;循环持续(bx)*(dx,ax)次
;预设(dx,ax)的值
rep2: mov dx,7
mov bp,speed
cmp bp,0
jz sp00
cmp bp,2
jz sp22
jmp sp11
sp00: mov dx,4
jmp sp11
sp22: mov dx,10
sp11: mov ax,0
rep3: sub ax,1
sbb dx,0
jnz rep3
dec bx
jnz rep2
pop ax
mov al,ah
out 61h,al ;原开关量写回设备控制寄存器
;-------------------------------------------------------------------------
add si,2 ;取下一频率值
add di,2 ;取下一时间节拍值
jmp rep1
;音乐演奏结束
exit:
pop dx
pop cx
pop bx
pop ax
ret
play1 endp
;清屏-------------------------------------------
cls proc near
push ax
push bx
push cx
push dx
;清屏
mov ah,6
mov al,0
mov bh,7
mov ch,0
mov cl,0
mov dh,24
mov dl,79
int 10h
;光标到开始
mov dx,0
mov ah,2
mov bh,0
int 10h
pop dx
pop cx
pop bx
pop ax
ret
cls endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -