📄 elekeyboard.asm
字号:
MOV AH,02H ;读键盘状态字节
INT 16H
MOV DH,AL ;判断是否是右shift键
AND DH,01H
CMP DH,01H
JE SLOW ;是则进行低音处理
MOV DH,AL ;不是判断是否是左shift键
AND DH,02H
CMP DH,02H
JE SHGH ;是则进行高音处理
JMP SMID ;都不是进行中音处理
SLOW: ;低音处理
MOV AUDIO,1
MOV KEYFLAG,0
JMP KEY_1 ;跳转到音键处理
SHGH: ;高音处理
MOV AUDIO,3
MOV KEYFLAG,2
JMP KEY_1 ;跳转到音键处理
SMID : ;中音处理
MOV AUDIO,2
MOV KEYFLAG,1
KEY_1:
CMP DL,1EH ;是否是1--A
JNE KEY_2 ;继续判断
MOV KEYNUM,0 ;不是则保存标志
JMP SCAN_END ;键扫描结束
KEY_2:
CMP DL,1FH ; 是否是2--S
JNE KEY_3
MOV KEYNUM,2
JMP SCAN_END
KEY_3:
CMP DL,20H ; 是否是3--D
JNE KEY_4
MOV KEYNUM,4
JMP SCAN_END
KEY_4:
CMP DL,21H ; 是否是4---F
JNE KEY_5
MOV KEYNUM,6
JMP SCAN_END
KEY_5:
CMP DL,22H ; 是否是5--G
JNE KEY_6
MOV KEYNUM,8
JMP SCAN_END
KEY_6:
CMP DL,23H ; 是否是6--H
JNE KEY_7
MOV KEYNUM,10
JMP SCAN_END
KEY_7:
CMP DL,24H ; 是否是7---J
JNE SCAN_END
MOV KEYNUM,12
SCAN_END:
RET
SCAN_KEY ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;判断是否是自动播放键(键1~5),并保存标志变量(song)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SCAN_SONG PROC NEAR
;IN: Al 键ASCII
PUSH AX
MOV SONG,100 ;赋初始值
CMP AL,'1' ;与1比较
JB SONG_END ;小于1则结束
CMP AL,'5' ;与5比较
JA SONG_END ;大于则结束
SUB AL,'0' ;转换成1~5
; MOV AL,AH
MOV AH,00H
MOV SONG,AX ;存入标志码
SONG_END:
POP AX
RET
SCAN_SONG ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;选择并播放音乐
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PLAY_SONG PROC NEAR
PUSH BP
PUSH SI
PUSH BX
PUSH DI
PUSH AX
CMP SONG,01H ;判断是否是歌1
JNE GO2 ;不是继续判断
LEA BP,MUS_TIME1 ;载入延时数据首地址
LEA SI,MUS_FREQ1 ;载入频率数据首地址
JMP FREQ
GO2:
CMP SONG,02H ;判断是否是歌2
JNE GO3
LEA BP,MUS_TIME2
LEA SI,MUS_FREQ2
JMP FREQ
GO3:
CMP SONG,03H ;判断是否是歌3
JNE GO4
LEA BP,MUS_TIME3
LEA SI,MUS_FREQ3
JMP FREQ
GO4:
CMP SONG,04H ;判断是否是歌4
JNE GO5
LEA BP,MUS_TIME4
LEA SI,MUS_FREQ4
JMP FREQ
GO5:
CMP SONG,05H ;判断是否是歌5
JNE FREQ
LEA BP,MUS_TIME5
LEA SI,MUS_FREQ5
JMP FREQ
FREQ:
MOV AH,01H ;读键盘缓冲区字符
INT 16H
CMP AH,1CH ;是否是ENTER键
JNZ CONTINUE ;不是继续
JMP PLAY_END ;是结自动播放
CONTINUE:
MOV AH,0CH ;清除键盘缓冲区字符
MOV AL,06H
INT 21H
MOV DL,8
MOV AH,2
INT 21H
MOV DL,' '
INT 21H
MOV DI,[SI]
CMP DI,-1 ;判断结束否
JE PLAY_END
MOV BX,[BP]
CALL GEN_AUTO ;发声
ADD SI,2
ADD BP,2 ;下一频率
JMP FREQ
PLAY_END:
POP AX
POP DI
POP BX
POP SI
POP BP
RET
PLAY_SONG ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;自动播放发声程序
GEN_AUTO 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
IN AL,61H
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL
WAIT2:
CALL WAITF
DEC BX
JNZ WAIT2 ;判断是否播放完毕
MOV AL,AH ;完毕则关闭扬声器
OUT 61H,AL
POP DI
POP DX
POP CX
POP BX
POP AX
RET
GEN_AUTO ENDP
WAITF PROC NEAR
;延时程序
PUSH AX
MOV CX,DELAY_TIME
WAITF1:
IN AL,61H
AND AL,10H ;检查PB4口
CMP AL,AH ;判断AL变化否
JE WAITF1 ;等待AL变化
MOV AH,AL ;保存PB4的新状态(AL中)
LOOP WAITF1
POP AX
RET
WAITF ENDP
LOAD_AUDIO PROC NEAR
;低、中、高频率分别载入
;OUT:BX
;IN:TUNE,AUDIO
TUNE_CL:
MOV TUNE,'C' ;C调处理
CMP AUDIO,1
JNE TUNE_CM
LEA BX,LOWD
JMP AUDIO_END
TUNE_CM:
CMP AUDIO,2
JNE TUNE_CH
LEA BX,MID
JMP AUDIO_END
TUNE_CH:
LEA BX,HGH
AUDIO_END:
RET
LOAD_AUDIO ENDP
SHOW_TEXT PROC NEAR
;在屏幕上显示字符
LEA DI,TEXT ;载入字符串首地址
MOV DH,[DI] ;赋行值
INC DI ;取得列
MOV DL,[DI] ;赋列值
MOV START_COL,DL ;保存开始列
MOV AH,2 ;设置光标位置
MOV BH,0 ;0页
INT 10H
INC DI ;取得颜色值
MOV BL,[DI] ;赋颜色值
CHAR_WRITE:
INC DI ;取得要显示的字符
MOV AL,[DI]
CMP AL,0FFH ;行结束否
JE BUMP_ROW ;下一行
CMP AL,0 ;结束否
JZ END_TEXT
CALL SHOW_CHAR ;显示字符
JMP CHAR_WRITE ;下一个字符
END_TEXT:
RET
BUMP_ROW:
INC DH ;下一行
MOV DL,START_COL ;赋开始列值
MOV AH,2 ;设光标位置
MOV BH,0
INT 10H
JMP CHAR_WRITE
SHOW_TEXT ENDP
SHOW_CHAR PROC NEAR
;显示字符
MOV AH,9 ;显示字符
MOV BH,0 ;0页
MOV CX,1
INT 10H
INC DL
MOV AH,2 ;设置光标位置
MOV BH,0 ;0页
INT 10H
RET
SHOW_CHAR ENDP
INIT PROC NEAR
;初始化屏幕:画琴键
MOV AX,DATA
MOV DS,AX
MOV AH,0 ;设置屏幕
MOV AL,0DH
INT 10H
MOV AH,0BH
MOV BH,0
MOV BL,00H ;背景色
INT 10H
CALL SHOW_TEXT ;显示字符
DRAW 45,30,285,94,05H
DRAWSQRE 45,30,285,94,0DH
DRAWSQRE 49,48,280,49,00H
LEA SI,ST_LX ;画21个白色键
LEA DI,ED_LX
MOV CX,21
INIT_DRAW:
DRAW [SI],ST_Y,[DI],ED_Y,0FH
DRAW [SI],90,[DI],93,07H ;阴影
ADD SI,2
ADD DI,2
LOOP INIT_DRAW
LEA SI,BT_X ;画15个黑色键
LEA DI,BD_X
MOV CX,15
INIT_BLOCK:
DRAW [SI],BT_Y,[DI],BD_Y,00H
ADD SI,2
ADD DI,2
LOOP INIT_BLOCK
RET
INIT ENDP
EXIT PROC NEAR
MOV AH,00H
MOV AL,03H
INT 10H
MOV AH,4CH
INT 21H
RET
EXIT ENDP
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -