INCLUDE yinyue.inc
.386P
IOY1 EQU 3040H
IOY0 EQU 3000H ;片选IOY0对应的端口始地址
MY8254_COUNT0 EQU IOY0+00H*4 ;8254计数器0端口地址
MY8254_COUNT1 EQU IOY0+01H*4 ;8254计数器1端口地址
MY8254_COUNT2 EQU IOY0+02H*4 ;8254计数器2端口地址
MY8254_MODE EQU IOY0+03H*4 ;8254控制寄存器端口地址
STACK1 SEGMENT STACK
DW 256 DUP(?)
STACK1 ENDS
DATA SEGMENT USE16
A DW 0,441,495,556,589,661,742,833
B DW 0,495,556,624,661,742,833,935
C DW 0,262,294,330,350,393,441,495
D DW 0,294,330,371,393,441,495,556
E DW 0,371,416,441,467,525,589,661
F DW 0,350,393,441,467,525,589,661
G DW 0,393,441,495,525,589,661,742
MES1 DB '--usage:',0AH,0DH,' first, you should input A,B...or G to chose the tone' ,0AH,0DH,' second,click 1(do) ..7(si)to play music',0AH,0DH,' third,if you want to quit playing,please click ESC or click ENTER to chose the tone again',0AH,0DH,, '$'
STR1 DB 'please input A,B,C,D,E,F, 0R G',0AH,0DH, '$'
STR2 DB 0AH,0DH,'you can play music',0AH,0DH, '$'
B1 DW 0
ADDR DW 0
YIN DW 0
LB DB ?
DATA ENDS
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET MES1 ;show message
MOV AH,09H
INT 21H
MOV ADDR,OFFSET HZDOT
BEGIN:MOV DX,OFFSET STR1
MOV AH,09H
INT 21H ;输出字符串1
MOV SI,OFFSET A ;装入频率表A起始地址
MOV AH,01H
INT 21H
AND AL,0FH
SUB AL,1
MOV BL,16
MUL BL
ADD SI,AX ;A..G起始地址
MOV B1,SI
MOV DX,OFFSET STR2
MOV AH,09H
INT 21H ;输出字符串2
PLAY: MOV DX,MY8254_MODE ;初始化8254工作方式
MOV AL,36H ;定时器0、方式3
OUT DX,AL
MOV AH,01H
INT 21H
;读取键盘上输入的数字
CMP AL,27
JZ QUIT ;ESC的时候退出
CMP AL,13 ;点击ENTER ,选调
JZ BEGIN
AND AL,0FH
MOV BL,AL
SUB BL,1
MOV LB,BL
XOR AH,AH ;获得哪个音1-7
MOV BL,2
MUL BL
ADD SI,AX ;把偏移量给SI
MOV DX,0FH ;输入时钟为1.0416667MHz,1.0416667M = 0FE502H
MOV AX,0E502H
DIV WORD PTR [SI] ;取出频率值计算计数初值,0F4240H / 输出频率
MOV DX,MY8254_COUNT0
OUT DX,AL ;装入计数初值
MOV AL,AH
OUT DX,AL
XOR AH,AH
MOV AL,LB
MOV BL,32
MUL BL
MOV YIN,AX
CALL DALLY
MOV AX,ADDR
ADD AX,YIN
MOV SI,AX
MOV CX,29H ;控制一屏显示时间
LOOP2:CALL DSPLMSC
SUB SI,32
LOOP LOOP2
MOV DX,MY8254_MODE
MOV AL,01H
OUT DX,AL
MOV SI,B1
JMP PLAY
QUIT: MOV DX,MY8254_MODE ;设置8254为方式0,out0置0
MOV AL,10H
OUT DX,AL
MOV AX,4C00H ;结束程序退出
INT 21H
DALLY PROC ;延时子程序
D0: MOV CX,0F00H
D1: MOV AX,0FFFFH
D2: DEC AX
JNZ D2
LOOP D1
JNZ D0
RET
DALLY ENDP
DALLY1 PROC
MOV AX,0FFFFH
D3: DEC AX
JNZ D3
RET
DALLY1 ENDP
DSPLMSC PROC ;显示 1 屏汉字子程序
PUSH CX
MOV CX,16
MOV BX,0FFFEH
LOOP1: MOV AL,BYTE PTR[SI]
MOV AH,BYTE PTR[SI+1]
ROL EAX,16
MOV AX,BX
ADD SI,2
ROL BX,1
NOT EAX
MOV DX,IOY1
OUT DX,EAX
CALL DALLY1
L1: LOOP LOOP1
POP CX
RET
DSPLMSC ENDP
CODE ENDS
END START
yinyue.inc
DATA SEGMENT
C444F EQU 00000H;DO
C5245 EQU C444F+1;RE
C4D49 EQU C5245+1;MI
C4641 EQU C4D49+1;FA
C534F EQU C4641+1;SO
C4C41 EQU C534F+1;LA
C5349 EQU C4C41+1;SI
HZDOT:
;DO C444F
DB 000H,000H,000H,000H,01FH,01CH,036H,036H,066H,063H,066H,063H,066H,063H,066H,063H
DB 066H,063H,066H,063H,036H,036H,01FH,01CH,000H,000H,000H,000H,000H,000H,000H,000H
;RE C5245
DB 000H,000H,000H,000H,03FH,07FH,066H,066H,066H,046H,066H,016H,03EH,01EH,036H,016H
DB 066H,006H,066H,046H,066H,066H,067H,07FH,000H,000H,000H,000H,000H,000H,000H,000H
;MI C4D49
DB 000H,000H,000H,000H,063H,03CH,077H,018H,07FH,018H,07FH,018H,06BH,018H,063H,018H
DB 063H,018H,063H,018H,063H,018H,063H,03CH,000H,000H,000H,000H,000H,000H,000H,000H
;FA C4641
DB 000H,000H,000H,000H,07FH,008H,066H,01CH,046H,036H,016H,063H,01EH,063H,016H,07FH
DB 006H,063H,006H,063H,006H,063H,00FH,063H,000H,000H,000H,000H,000H,000H,000H,000H
;SO C534F
DB 000H,000H,000H,000H,03EH,01CH,063H,036H,063H,063H,006H,063H,01CH,063H,030H,063H
DB 060H,063H,063H,063H,063H,036H,03EH,01CH,000H,000H,000H,000H,000H,000H,000H,000H
;LA C4C41
DB 000H,000H,000H,000H,00FH,008H,006H,01CH,006H,036H,006H,063H,006H,063H,006H,07FH
DB 006H,063H,046H,063H,066H,063H,07FH,063H,000H,000H,000H,000H,000H,000H,000H,000H
;SI C5349
DB 000H,000H,000H,000H,03EH,03CH,063H,018H,063H,018H,006H,018H,01CH,018H,030H,018H
DB 060H,018H,063H,018H,063H,018H,03EH,03CH,000H,000H,000H,000H,000H,000H,000H,000H
DATA ENDS