📄 piano.asm
字号:
;-------------------------------------------------------- 堆栈段定义
stack segment stack'stack'
db 64 dup('0')
bs1 equ 60
bs2 equ 40
bs3 equ 34
stack ends
;-------------------------------------------------------- 数据段定义
data segment
piano_view db ' WELCOME TO USE THE PIANO ' ;主界面
db 0dh,0ah,' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
db 0ah,0dh,' * Operate: Stop: S Quit: q *'
db 0ah,0dh,' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
db 0dh,0ah,'please choose the music(1~4): $'
stop db 'Stop? (s): $'
error db 0dh,0ah,'The number is not define.Please input again!',0dh,0ah,'$'
again db 0dh,0ah,'Please input again!',0dh,0ah,'$'
music1_name db 0dh,0ah,'Marry had a little lamb!$' ;显示歌名
music2_name db 0dh,0ah,'Happy birthday to you $'
music3_name db 0dh,0ah,'Ju hua tai$' ;音符频率设定
play db 0dh,0ah,' ******************************************************' ;按键部分提示界面
db 0dh,0ah,' *Playing the piano yourself* '
db 0dh,0ah,' * low_key: a(do),s(ri),d(mi),f(fa),j(so),k(la),l(xi)*'
db 0dh,0ah,' *hight_key:z(do),x(ri),c(mi),v(fa),b(so),n(la),m(xi)*'
db 0dh,0ah,' input esc to exit! '
db 0dh,0ah,' ****************************************************** $'
out_view db 0dh,0ah,' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' ;退出界面
db 0dh,0ah,' THANKS TO USE THE PIANO '
db 0dh,0ah,' veikin 制作 ** '
db 0dh,0ah,' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $'
music1_freq dw 330,294,262,294,3 dup(330)
dw 3 dup(294),330,392,392
dw 330,294,262,294,4 dup(330)
dw 294,294,330,294,262,-1
music1_time dw 6 dup(100*bs1),200*bs1 ;延迟时间
dw 2 dup(100*bs1,100*bs1,200*bs1)
dw 12 dup(100*bs1),100*bs1
music2_freq DW 262,262,294,262,349,330
DW 262,262,294,262,392,349
DW 262,262,523,440,349,330,294
DW 466,466,440,262,392,349,-1
music2_time DW 2 dup(200*bs2),3 dup(400*bs2),200*bs2
DW 2 dup(200*bs2),3 dup(400*bs2),200*bs2
DW 2 dup(200*bs2),4 dup(400*bs2),300*bs2
DW 2 dup(200*bs2),3 dup(400*bs2),200*bs2
music3_freq dw 262,330,330,294,330,330,392,330,294,330
dw 262,262,294,330,392,330,294,294,262,294
dw 330,392,330,440,392,440,392,392,330,392,262
dw 330,294,294,392,330,3 dup(294),262,294,-1
music3_time dw 400*bs3,100*bs3,2 dup(200*bs3),200*bs3,4 dup(200*bs3),200*bs3
dw 100*bs3,4 dup(200*bs3),100*bs3,100*bs3,50*bs3,50*bs3,200*bs3
dw 150*bs3,25*bs3,25*bs3,50*bs3,150*bs3,4 dup(200*bs3),150*bs3,50*bs3
dw 3 dup(400*bs3,50*bs3,200*bs3),200*bs3
data ends
;--------------------------------------------------------代码段定义
code segment
assume cs:code,ss:stack,ds:data
;*****定义宏*****
show macro b
lea dx,b
mov ah,09h ;显示字符串
int 21h
endm
;**********************
music proc far
mov ax,data
mov ds,ax
mov ah,0 ;设置字符显示方式
mov al,2
int 10h
mov ah,15 ;读取显示页号
int 10h
mov ah,2 ;设置光标位置
mov dx,0101h
int 10h
mov ah,6 ;窗口定义
mov al,0
mov ch,0
mov cl,0
mov dh,30
mov dl,100
mov bh,70h ;背景和字体颜色定义
int 10h
show piano_view
input: mov ah,01h ;键盘输入,中断退出
int 21h
cmp al,'q'
je A
;je end_mus
cmp al,'Q'
je A
;je end_mus
play_mus1: cmp al,'1' ;选择要播放的歌曲
jnz play_mus2
show music1_name
mov ah,2 ;实现换行
mov dl,0DH
int 21h
mov dl,0AH
int 21h
show stop
lea si,music1_freq
lea bp,ds:music1_time
jmp freq
play_mus2: cmp al,'2'
jnz play_mus3
show music2_name
mov ah,2 ;实现换行
mov dl,0DH
int 21h
mov dl,0AH
int 21h
show stop
lea si,music2_freq
lea bp,ds:music2_time
jmp freq
play_mus3: cmp al,'3'
jnz play_yourself
show music3_name
mov ah,2 ;实现换行
mov dl,0DH
int 21h
mov dl,0AH
int 21h
show stop
lea si,music3_freq
lea bp,ds:music3_time
jmp freq
A: jmp end_mus
play_yourself: cmp al,'4'
jnz exit
show play
call piano
mov ah,2 ;实现换行
mov dl,0DH
int 21h
mov dl,0AH
int 21h
mov ah,1
int 21h
cmp al,1bh
je next
jmp freq
exit: show error
jmp input
;------------------------------------------------
freq: mov cx,[si]
cmp cx,-1
je next
mov bx,ds:[bp]
call GENSOUND
add si,2
add bp,2
mov ah,0bh ;中断设置
int 21h
cmp al,00h
jz freq
mov ah,01
int 21h
cmp al,'s'
je next
jmp freq
next: show again
jmp input
end_mus: mov ax,4c00h
int 21h
music endp
;--------------------------------------------------------
;通用发声子程序
GENSOUND PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AL,0B6H ;用8253定时
OUT 43H,AL
MOV DX,12H
MOV AX,533H*896
MOV di, cx
div di
OUT 42H,AL
MOV AL,AH ;向42h口送入发出频率对应的计数值
OUT 42H,AL
IN AL,61H ;通过8255打开扬声器门,发出该频率的声音
MOV AH,AL
OR AL,3
OUT 61H,AL
WAIT1: MOV CX,8FF0H
DELAY: LOOP DELAY ;延迟
DEC BX
JNZ WAIT1
MOV AL,AH
OUT 61H,AL
POP DI
POP DX
POP CX
POP BX
POP AX
RET
GENSOUND ENDP
;--------------------------------------------------------
piano proc
mov ax,data
mov ds,ax
mov ah,0 ;设置字符显示方式
mov al,2
int 10h
mov ah,15 ;读取显示页号
int 10h
mov ah,2 ;设置光标位置
mov dx,0101h
int 10h
mov ah,6 ;窗口定义
mov al,0
mov ch,0
mov cl,0
mov dh,30
mov dl,100
mov bh,34h ;背景和字体颜色定义
int 10h
show play
;-------------------------------------------------------
;自定义弹奏乐曲
low_key1: mov ah,08h
int 21h
cmp al,'a'
jnz low_key2
mov cx,131
call GENSOUND
jmp low_key1
low_key2: cmp al,'s'
jnz low_key3
mov cx,147
call GENSOUND
jmp low_key1
low_key3: cmp al,'d'
jnz low_key4
mov cx,165
call GENSOUND
jmp low_key1
low_key4: cmp al,'f'
jnz low_key5
mov cx,175
call GENSOUND
jmp low_key1
low_key5: cmp al,'j'
jnz low_key6
mov cx,198
call GENSOUND
jmp low_key1
low_key6: cmp al,'k'
jnz low_key7
mov cx,220
call GENSOUND
jmp low_key1
low_key7: cmp al,'l'
jnz hight_key1
mov cx,249
call GENSOUND
jmp low_key1
hight_key1: cmp al,'z'
jnz hight_key2
mov cx,262
call GENSOUND
jmp low_key1
hight_key2: cmp al,'x'
jnz hight_key3
mov cx,294
call GENSOUND
jmp low_key1
hight_key3: cmp al,'c'
jnz hight_key4
mov cx,330
call GENSOUND
jmp low_key1
hight_key4: cmp al,'v'
jnz hight_key5
mov cx,349
call GENSOUND
jmp low_key1
hight_key5: cmp al,'b'
jnz hight_key6
mov cx,392
call GENSOUND
jmp low_key1
hight_key6: cmp al,'n'
jnz hight_key7
mov cx,440
call GENSOUND
jmp low_key1
hight_key7: cmp al,'m'
jnz key
mov cx,483
call GENSOUND
jmp low_key1
key: cmp al,1bh
jz quit
jmp low_key1
quit: show out_view
ret
;---------------------------------------------------------------------------------
piano endp
code ends
end music
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -