📄 down4.asm
字号:
基于硬件tpc-h试验平台,用到8253,8255
功能:1 弹音乐 a s d f g h j---dou re mi fa sou la xi
2 同时按shift-----左对应高音,右对应低音
3 按1键----播放千里之外
4 按2键----播放另一首歌
5 按3键----播放自己刚才弹奏的曲子
6 按+/- ---在播放过程中加速或减速播放
7 按enter--结束播放
8 数码管随弹奏,播放 闪烁
9 界面按键随着音乐起伏
注; 此程序与网上经典代码相比,多了不少功能,且更适合硬件实现。
代码;
;////////////////for computer //////////////
; ---------------画填充的矩形
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: ;画上边
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
;-----------------------------------------------------------------------
; --------------------------数据段
DATA SEGMENT ;定义在屏幕绘制字
START_COL DB (?) ;存储起始行
TEXT DB 16 ;起始行
DB 2 ;起始列
DB 01H ;字体颜色
DB 0FFH,'1-PRESS Q.W.E.R.T.Y.U TO MAKE MUSIC'
DB 0FFH,'2-PRESS 1,2 TO PLAY A MUISC'
DB 0FFH,'3-PRESS 3 TO REPLAY THE MUSIC'
DB 0FFH,'4-PRESS L/R SHIFT TO HIGHT/LOW.'
DB 0FFH,0FFH,0FFH,0FFH ;显示字
DB ' MY FINAL WORK--PIANO!',0FFH
DB 00
ST_LX DW 50,61,72,83,94,105,116 ;白色琴键坐标
ST_MX DW 127,138,149,160,171,182,193
ST_HX DW 204,215,226,237,248,259,270
ST_Y DW 50
ED_LX DW 60,71,82,93,104,115,126
ED_MX DW 137,148,159,170,181,192,203
ED_HX DW 214,225,236,247,258,269,280
ED_Y DW 90
BT_X DW 57,68,90,101,112 ;黑色琴键坐标
DW 134,145,167,178,189
DW 211,222,244,254,265
BT_Y DW 50
BD_X DW 64,75,97,108,119
DW 141,152,174,185,196
DW 218,229,251,262,273
BD_Y DW 70
LOWD DW 131 ;音乐频率值
LOWDD DW 147,165,175,196,220,247
MID DW 262
MIDD DW 294,330,349,392,440,494
HGH DW 523
HGHD DW 587,659,797,783,879,987,1046
KEYFLAG DB 1 ;标记低(0)、中(1)、高(2)音键
KEYNUM DW 1 ;存储1~7
DELAY_TIME DW 60000 ;延时
SONG DW 100 ;保存所选的自动演奏的曲目
AUDIO DW 1 ;标记低(1)、中(2)、高音(3)
TUNE DW 1 ;默认为c调
COUNT_TIME DW 0 ;计数时间
COUNT_NUM DW 0 ;计数值
MUS_FREQ1 DW 392,587,587,587,659,587,523,523,392,440
DW 523,523,523,587,659,587,587,587,659,587
DW 523,392,440,523,523,523,659,659,587,587
DW 392,587,587,587,659,587,523,523,392,440
DW 523,523,523,587,659,587,587,587,523,523
DW 587,587,587,523,523,440,523,523,440,523
DW 523
DW -1
MUS_TIME1 DW 12,25,10,25,25,12,12,12,25,25
DW 25,12,25,25,100,25,12,25,25,25
DW 12,25,25,25,12,25,25,12,12,50
DW 12,25,12,25,25,12,12,12,25,25
DW 25,12,25,25,100,25,12,25,12,25
DW 25,12,25,12,25,25,12,120,25,12
DW 150
MUS_FREQ2 DW 262,262,294,330,330,349,392,440,392,330
DW 392,349,330,294,349,330,294,262
DW 262,262,294,330,330,349,392,440,392,330
DW 392,349,330,294,330,294,262,196
DW 392,349,330,294,196,196,349,330,294,262
DW 392,349,330,294,196,196,349,330,294,262
DW 262,262,294,330,330,349,392,440,392,330
DW 392,349,330,294,330,294,262
DW -1
MUS_TIME2 DW 3 DUP(25,2 DUP(12)),50
DW 2 DUP(25,2 DUP(12),50)
DW 3 DUP(25,2 DUP(12)),50
DW 2 DUP(25,2 DUP(12)),2 DUP (50)
DW 3 DUP(25,2 DUP(12)),50
DW 3 DUP(25,2 DUP(12)),50
DW 3 DUP(25,2 DUP(12)),50
DW 2 DUP(25,2 DUP(12)),50
MUS_FREQ3 DW 10000 DUP(-1)
MUS_TIME3 DW 10000 DUP(?)
DATA ENDS
;------------------------------------------------------------------------------
CODE SEGMENT ;代码段
ASSUME DS:DATA,CS:CODE
MAIN PROC FAR ;主程序
START:
CALL INIT ;调用初始化程序
NEW_SCAN:
CALL SCAN_KEY ;扫描所按下的键
CMP SONG,100 ;判断是否按下了自动播放的歌曲键
JE HAND_PLAY ;若不是,继续判断
CALL PLAY_SONG ;若是,演奏音乐
JMP NEW_SCAN ;演奏结束,重新扫描有无键按下
HAND_PLAY:
CMP KEYNUM,100 ;判断是否手动演奏
JZ NEW_SCAN ;若不是,重新扫描有无键按下
PUSH BX ;若是,进行按键处理
MOV BX,KEYNUM
CALL KEY_DOWN ;在屏幕上显示按下状态31
POP BX
CALL LOAD_AUDIO ;判断高低音32、并装入对应频率段地址到BX中
PUSH SI
MOV SI,KEYNUM
MOV DI,[BX+SI]
CALL GEN_HAND ;发声41
POP SI
PUSH BX
MOV BX,KEYNUM ;在屏幕上显示弹起状态51
CALL KEY_UP
POP BX
JMP NEW_SCAN ;重新扫描有无键按下,直到按下ESC键
MAIN ENDP
;-----------------------------------------------------------------------
GEN_HAND PROC NEAR ;手动演奏发声程序
PUSH AX ;IN:DI
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV AL,80H ;初始化外部55
MOV DX,28BH
OUT DX,AL
MOV AL,36H ;定时器初始化
MOV DX,283H
OUT DX,AL
MOV DX,0FH ;2M CLOCK
MOV AX,4340H
DIV DI
MOV DX,280H
OUT DX,AL ;定时器送处值
;开扬声器
MOV AL,AH
MOV DX,280H
OUT DX,AL
MOV DX,288H
IN AL,DX
MOV AH,AL
OR AL,3
MOV DX,288H
OUT DX,AL
MOV AX,DATA
MOV DS,AX
MOV AX,DI
LEA BX,MUS_FREQ3
PUSH SI
MOV SI,COUNT_NUM
MOV [BX+SI],AX
POP SI
MOV AX,DI
CMP AX,262
JNZ DOU1
MOV AL,01
MOV DX,28AH
OUT DX,AL
DOU1: CMP AX,294
JNZ RUA1
MOV AL,02
MOV DX,28AH
OUT DX,AL
RUA1: CMP AX,330
JNZ MI1
MOV AL,04
MOV DX,28AH
OUT DX,AL
MI1: CMP AX,349
JNZ FA1
MOV AL,08
MOV DX,28AH
OUT DX,AL
FA1: CMP AX,392
JNZ SOU1
MOV AL,16
MOV DX,28AH
OUT DX,AL
SOU1: CMP AX,440
JNZ LA1
MOV AX,32
MOV DX,28AH
OUT DX,AL
LA1: CMP AX,494
JNZ XI1
MOV AL,64
MOV DX,28AH
OUT DX,AL
XI1: CMP AX,523
JNZ WAIT1
MOV AL,128
MOV DX,28AH
OUT DX,AL
WAIT1:
CALL WAITF ;调用延时程序411
IN AL,60H
TEST AL,80H ;查询键是否放开
JZ WAIT1
PUSH AX
MOV AX,COUNT_TIME
PUSH BX
LEA BX,MUS_TIME3
PUSH SI
MOV SI,COUNT_NUM
MOV [BX+SI],AX
MOV AX,COUNT_NUM
ADD AX,2
MOV COUNT_NUM,AX
POP SI
POP BX
POP AX
MOV AL,AH ;放开则关扬声器
MOV DX,288H
OUT DX,AL
MOV AX,0
MOV COUNT_TIME,AX
POP DI
POP DX
POP CX
POP BX
POP AX
RET
GEN_HAND ENDP
;---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -