📄 piano.asm
字号:
;画填充矩形
;-------------------------------------------
DRAW MACRO START_X,START_Y,END_X,END_Y,COLOR
LOCAL DRAW_NEXT
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0CH ;写像素点
MOV AL,COLOR ;设置颜色
MOV BH,0 ;选用页号0
MOV CX,START_X ;列起始点
MOV DX,START_Y ;行起始点
DRAW_NEXT:
INT 10H ;画点
INC CX ;画横线
CMP CX,END_X ;比较行是否画完
JNE DRAW_NEXT ;画另一行
MOV CX, START_X ;另一行的起始点
INC DX
CMP DX,END_Y ;比较列是否画完
JNE DRAW_NEXT ;未完继续画
POP DX
POP CX
POP BX
POP AX
ENDM
;-----------------------------------------------
;画不填充的矩形
;-----------------------------------------------
DRAWSQRE MACRO START_X,START_Y,END_X,END_Y,COLOR
LOCAL ROW_UP,ROW_DOWN,RANK_LEFT,RANK_RIGHT
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV AH,0CH
MOV AL,COLOR
MOV BH,0
MOV CX,START_X
MOV DX,START_Y
ROW_UP:MOV AH,0CH ;画上边
INT 10H
INC CX
CMP CX,END_X
JNE ROW_UP
RANK_RIGHT: ;画右边
INT 10H
INC DX
CMP DX,END_Y
JNE RANK_RIGHT
MOV CX, START_X ;下边起始点
MOV SI,END_X
INC SI
ROW_DOWN: ;画下边
INT 10H
INC CX
CMP CX,SI
JNE ROW_DOWN
MOV DX,START_Y ;右边起始点
MOV CX,START_X
RANK_LEFT: ;画左边
INT 10H
INC DX
CMP DX, END_Y
JNE RANK_LEFT
POP SI
POP DX
POP CX
POP BX
POP AX
ENDM
DATAS SEGMENT
WHITE DB 0FFH
BLACK DB 0
YELLOW DB 0EEH
GRAY DB 8
CHOSE DB 'Chose the tone:C,F',0AH,0DH,'$'
ANSWER DB 0AH,0DH,'You have chosed the tone,Now enjoy the game!$'
;TABFA DW 441,495,556,589,661,742,833
;TABFB DW 495,556,624,661,742,833,935
TABFC DW 192,294,330,350,393,441,495
;TABFD DW 294,330,371,393,441,495,556
;TABFE DW 330,371,416,441,495,556,624
TABFF DW 350,393,441,467,525,589,661
;TABFG DW 393,441,495,525,589,661,742
ZERO DW -1
BUFFER DW 0
DTIME DW 10
TONEF DW 0
WL DW 0,146,196,246,296,346,396,446
WR DW 0,195,245,295,345,395,445,495
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
CALL INIT
CALL OPEN
;主界面
;-----------------------------------------------------
DRAW 146,340,494,359,GRAY
DRAW 146,141,494,359,WHITE
DRAWSQRE 144,139,496,361,YELLOW
DRAW 175,141,215,259,BLACK
DRAW 225,141,265,259,BLACK
DRAW 325,141,365,259,BLACK
DRAW 375,141,415,259,BLACK
DRAW 425,141,465,259,BLACK
;-----------------------------------------------------
;键盘分割线
;------------------------------------------------------
MOV DX,141
MOV CX,195
MOV AH,0CH
MOV AL,BLACK
DRAWLINE:
INT 10H
INC DX
CMP DX,359
JNA DRAWLINE
MOV DX,141
ADD CX,50
CMP CX,494
JNA DRAWLINE
;-------------------------------
;提示选择信息
;-------------------------------
MOV AH,09H
MOV DX,OFFSET CHOSE
INT 21H
;---------------------------------
INPUT:
MOV AH,01H
INT 21H
;------------------------------
CMP AL,'C'
JZ CTONE
;----------------------------
CMP AL,'F'
JZ FTONE
JMP INPUT
;-------------------------------
;C调,F调
;--------------------------------
CTONE:
MOV DI,OFFSET TABFC
JMP ANS
FTONE:
MOV DI,OFFSET TABFF
;------------------------
ANS:
MOV TONEF,DI ;把选择的音调标号存储在TONEF中
MOV DX,OFFSET ANSWER
;PUSH AX
MOV AH,09H
INT 21H
;POP AX
;-------------------------------------
;获取弹奏的音符
;-------------------------------------
SCAN:
MOV AH,00H
INT 16H
CMP AL,37H ;ASCII>37H,退出
JA EXIT
CMP AL,31H ;ASCII<31H,退出
JC EXIT
;PUSH DI
AND AX,000FH ;将ASCII码转换成数字
MOV BUFFER,AX ;将数字存储在内存空间BUFFER中
PLAY:
MOV DI,TONEF
DEC AX
ADD AX,AX ;TABFx为双字表,需要将获得的ASCII符*2
ADD DI,AX
MOV BX,[DI] ;根据按键获取的ASCII码得到相应的频率值
;--------------------------------------------------------
MOV DX,12H
MOV AX,34DEH ;1.193182MHZ/BX
DIV BX
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
PAINTKEY:
MOV AX,BUFFER
MOV SI,OFFSET WL
MOV DI,OFFSET WR
ADD AX,AX
ADD SI,AX
ADD DI,AX
MOV SI,WORD PTR[SI]
MOV DI,WORD PTR[DI]
;----------------------------------------
DRAW SI,339,DI,359,WHITE
DRAW SI,339,DI,359,WHITE
;------------------------------------
CALL DELAY
MOV AX,12H
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
JMP SCAN
EXIT:
CALL CLOSE
MOV AH,1
INT 21H
MOV AH,4CH
INT 21H
;--------------------------------------------------------
DELAY PROC
MOV AH,2DH
MOV CX,0
MOV DX,0
INT 21H ;设置系统时间
READ:
MOV AH,2CH
INT 21H
MOV AL,100
MUL DH
MOV DH,0
ADD AX,DX
CMP AX,DTIME
JC READ
RET
DELAY ENDP
;---------------------------------------
OPEN PROC
PUSH AX
IN AL,61H
OR AL,03H
OUT 61H,AL
POP AX
RET
OPEN ENDP
;-----------------------------------------
CLOSE PROC
PUSH AX
IN AL,61H
AND AL,0FCH
OUT 61H,AL
POP AX
RET
CLOSE ENDP
;------------------------------------------
INIT PROC
MOV AH,00H
MOV AL,12H ;640*480 彩色图形
INT 10H
MOV AL,80H ;对8255进行初始化工作,A口、B口均为输出状态工作与方式0
OUT 63H,AL
MOV AL,0B7H ;对计数器8254进行初始化工作,选2号计数器,且先读写低8位后高8位,工作与模式3
OUT 43H,AL
RET
INIT ENDP
CODES ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -