_8NOTE EQU 0FFFH ;定义八分音符的延时时长(计数) _4NOTE=_8NOTE*2 ;四分音符
_4DNOTE=_4NOTE+_8NOTE ;四分附点音符 _2NOTE=_4NOTE*2 ;二分音符
_2DNOTE=_2NOTE+_4NOTE ;二分附点音符 _1NOTE=_2NOTE*2 ;全音符 PAUS=04FFH ;每个音之间的小间隔
CLK EQU 32000 ;时钟频率
;B3~C5音所对应的计数初值,由时钟频率/音频率得到 B3=CLK/247 C4=CLK/262 D4=CLK/294 E4=CLK/330 F4=CLK/349 G4=CLK/392 A4=CLK/440 B4=CLK/494 C5=CLK/523
;低音XI到高音DO的数码管显示码 XI_=63H DO=21H RE=0F4H MI=0F1H FA=39H SO=0D9H LA=0DDH XI=61H DO_P=23H
EMPT=10H ;休止符-
;《送别》音高谱
MUSIC DB G4,E4,G4,C5 ,A4,C5,G4 ,G4,C4,D4,E4,D4,C4,D4 ,1 ;1为无声,休止
DB G4,E4,G4,C5 ,B4,A4,C5,G4 ,G4 ,D4,E4,F4,B3,C4 ,1 COUNT EQU $-MUSIC
;《送别》简谱(数字显示) MUSIC_DISP DB SO,MI,SO,DO_P ,LA,DO_P,SO ,SO,DO,RE,MI,RE,DO,RE ,EMPT DB SO,MI,SO,DO_P ,XI,LA,DO_P,SO ,SO,RE,MI,FA ,XI_,DO ,EMPT
;《送别》音长谱
MUSIC_T DW _4NOTE,_8NOTE,_8NOTE,_2NOTE,_4NOTE,_4NOTE,_2NOTE DW _4NOTE,_8NOTE,_8NOTE,_4NOTE,_8NOTE,_8NOTE,_2DNOTE,_4NOTE DW _4NOTE,_8NOTE,_8NOTE,_4DNOTE,_8NOTE,_4NOTE,_4NOTE,_2NOTE DW _4NOTE,_8NOTE,_8NOTE,_4DNOTE,_8NOTE,_1NOTE,_2NOTE DATA ENDS
STACK SEGMENT STACK 'STACK' DB 200 DUP(?) STACK ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
DELAY PROC FAR ;延时子程序,时长由DS:[BP]的数据(音长谱)决定 PUSHF PUSH CX
MOV CX,DS:[BP] LOOP1: PUSH CX MOV CX,_4NOTE LOOP2:
LOOP LOOP2 POP CX LOOP LOOP1 POP CX POPF RETF DELAY ENDP
DELAY0 PROC FAR ;小间断延时子程序 PUSHF PUSH CX
MOV DX,0EE23H ;重置8253,即停止发音 MOV AL,00010110B OUT DX,AL MOV CX,PAUS LOOP3: PUSH CX MOV CX,PAUS LOOP4:
LOOP LOOP4 POP CX LOOP LOOP3 POP CX
POPF RETF DELAY0 ENDP
PLAY PROC FAR ;播放单音子程序 MOV DX,0EE20H
MOV AL,DS:[SI] ;输出DS:[SI](音高谱)作为计数初值 OUT DX,AL MOV DX,0EE00H
MOV AL,DS:[SI+COUNT] ;输出对应的数字码,在数码管1位上显示 OUT DX,AL RETF PLAY ENDP START:
MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX XOR AX,AX
MOV DX,0EE23H ;初始化8253
MOV AL,00010110B ;方式3,二进制计数,分频比小于255 OUT DX,AL
MOV DX,0EE03H ;初始化8255,A,B口均为方式0输出 MOV AL,80H OUT DX,AL
MOV DX,0EE01H ;数码管位选,固定为只有最右边的数码管显示 MOV AL,01H OUT DX,AL
MOV DX,0EE00H ;显示清空 MOV AL,00H OUT DX,AL
MUS: ;Music Start!
MOV SI,OFFSET MUSIC ;SI指向音高数据 MOV BP,OFFSET MUSIC_T ;BP指向音长数据 MOV CX,COUNT RUN:
CALL PLAY ;输出计数值播放单音,显示对应的数字 CALL DELAY ;延时相应的时长 CALL DELAY0 ;小间隔
INC SI ;SI、BP指向下一个音符 ADD BP,2
MOV AH,0BH ;检测键盘输入 INT 21H
OR AL,AL ;按任意键退出 JNZ EXIT
LOOP RUN ;否则继续循环播放 JMP MUS EXIT:
MOV DX,0EE23H ;重置8253 MOV AL,00010110B OUT DX,AL
MOV AH,4CH ;退出 INT 21H
CODE ENDS END START
因篇幅问题不能全部显示,请点此查看更多更全内容