汇编梦幻钢琴程序设计报告.docx
《汇编梦幻钢琴程序设计报告.docx》由会员分享,可在线阅读,更多相关《汇编梦幻钢琴程序设计报告.docx(45页珍藏版)》请在冰豆网上搜索。
汇编梦幻钢琴程序设计报告
《汇编语言程序设计》
综合程序设计实验报告
题目:
梦幻钢琴
1、项目简介
利用汇编语言设计一个模拟钢琴演奏程序。
在显示器上显示出钢琴的键盘,以计算机键盘的相应键模拟钢琴键盘进行乐曲的演奏。
在PC机键盘上按键,屏幕上对应的钢琴键出现跳动,并发出相应音符的声音,例如:
按字母“A”, 发C大调 do
按字母“S”, 发C大调 re
按字母“D”, 发C大调 me
按字母“F”, 发C大调fa
……
按下f1、f2、f3、f4、f5会依次播放程序中所添加的歌曲;如果想要使该歌曲加速播放,可以同时按住“shift”键和“+”键;若要减速播放,则按“shift”键和“-”键。
在弹奏钢琴曲时,直接按动“A”、“S”、“D”、“F”、“G”、“H”、“J”键表示的是中音区,高音区用右shift键加以上键弹奏,低音区用左shift键加以上键弹奏,也可以通过C、D转换是弹奏变为C大调或D大调。
二、小组成员具体分工
1、界面设计-刘静
(1)、屏幕设置
MOVAH,00H
MOVAL,0DH
INT10H
MOVAH,0BH;11号功能,设置背景颜色
MOVBL,00H
INT10H
(2)、钢琴绘制,绘制键盘时的坐标的确定:
白色琴键坐标:
ST_LXDW50,61,72,83,94,105,116;起点横坐标
ST_MXDW127,138,149,160,171,182,193
ST_HXDW204,215,226,237,248,259,270
ST_YDW50;起点纵坐标
ED_LXDW60,71,82,93,104,115,126;终点纵坐标
ED_MXDW137,148,159,170,181,192,203
ED_HXDW214,225,236,247,258,269,280
ED_YDW90;终点纵坐标
黑色琴键坐标
BT_XDW57,68,90,101,112;起点横坐标
DW134,145,167,178,189
DW211,222,244,254,265
BT_YDW50;起点纵坐标
BD_XDW64,75,97,108,119;终点横坐标
DW141,152,174,185,196
DW218,229,251,262,273
BD_YDW70;终点纵坐标
宏定义绘制填充矩形:
DRAWMACROSTART_X,START_Y,END_X,END_Y,COLOR
宏定义绘制不填充矩形:
DRAWSQREMACROSTART_X,START_Y,END_X,END_Y,COLOR
最后在主程序INITPROCNEAR调用以上定义的宏来绘制琴键。
(3)、琴键绘制PIANO_DRAWPROCNEAR
(4)、屏幕显示字符SHOW_CHARPROCNEAR、SHOW_TEXTPROCNEAR
2、功能调试-刘铸辉
通过调用子程序来实现各个功能:
(1)、手动演奏GEN_HANDPROCNEAR
(2)、自动播放发声程序GEN_AUTOPROCNEAR
(3)、延时程序WAITFPROCNEAR
(4)、自动播放歌曲SCAN_SONGPROCNEAR、PLAY_SONGPROCNEAR
(5)、C/D调及对应的低、中、高频率分别载入LOAD_AUDIOPROCNEAR
(6)、C/D调判断及其状态在屏幕上的显示SCAN_TUNEPROCNEAR;
三、需求分析与设计
1、钢琴绘制。
这部分主要实现画钢琴键盘键身的功能。
它是由二十一个白色的长方块和十五个黑色的长方块构成的,要在屏幕上画出有立体效果的长方形白色和黑色键盘,我们需要用BIOS调用编织线使程序。
显示适配器都自带显示服务的BIOS,利用它所提供的BIOS调用来编写程序,对于我们编程应用者来说是透明的,我们只需要调用显示驱动程序INT 10H。
钢琴主要是由矩形、直线等规则几何形状构成,通过画点、画线等基本程序完成钢琴的绘制。
对于绘制钢琴键盘,为使其有立体感,还需要先在excel表中绘制一个简单的钢琴键盘,准确对应其各个边界的坐标。
钢琴键盘的动态显示则是同步于键盘的按键有按下和弹起的动画。
这部分功能需要也可以用绘制钢琴的方法来实现这个效果。
绘制琴键:
PIANO_DRAWPROCNEAR
白色琴键:
LEASI,ST_LX;取白色琴键起始点有效地址
LEADI,ED_LX;取白色琴键结束点有效地址
MOVCX,21;白色琴键数目21
NEXT_DRAW:
DRAW[SI],ST_Y,[DI],ED_Y,0FH;调用宏定义画白键
DRAW[SI],90,[DI],93,07H;阴影
ADDSI,2;下一个键
ADDDI,2
LOOPNEXT_DRAW;CX-1不为0继续画
黑色琴键:
LEASI,BT_X;取黑色琴键起始点的有效地址
LEADI,BD_X;取黑色琴键结束点的有效地址
MOVCX,15;黑色琴键15个
NEXT_BLOCK:
DRAW[SI],BT_Y,[DI],BD_Y,00H;调用宏定义画黑色琴键
ADDSI,2;下一个键
ADDDI,2
LOOPNEXT_BLOCK;CX-1不为0继续画黑键
2、发声程序。
该发生程序是在修改BEEP发声程序的基础上,以实现为8088/86编写一个任意频率和任意持续时间的通用发声程序。
该程序包括以下三个步骤:
(1)在8253/54中的43端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使得定时器2准备接受计数初值。
(2)在8253/54中的42H端口装入一个16位计数值,已建立将要产生的声音频率。
(3)把输出端口61H的0、1两位置1,发出声音。
具体实现如下:
GEN_HANDPROCNEAR;手动演奏发声程序
;IN:
DI
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHDI
;定时器初始化程序
MOVAL,0B6H;定时器初始化,
;选择计数器2,工作在方式3OUT43H,AL
;OUT43H,AL;向定时器送初值
MOVDX,12H;1.1931Mhz/给定的频率=12348h/给定频率=计数初值
MOVAX,348CH;12348h存入DX:
AX中,商存AX,余数存DX
DIVDI;DI为给定的频率
OUT42H,AL;定时器送处值
INAL,61H;开扬声器
MOVAL,AH;给定时器2写入AX中存放的计数初值
OUT42H,AL
INAL,61H
MOVAH,AL;把8255输出端的61H的0、1位置1,并把端口状态写入AH
ORAL,3
OUT61H,AL
WAIT1:
CALLWAITF;调用延时程序
INAL,60H;读取键盘扫描码,按下和放开都有相应的扫描码,放开码=按下码+80h>80h
TESTAL,80H;查询键是否放开
JZWAIT1;未放开继续查询,AL不等于80H则继续延时
MOVAL,AH;恢复8255端口61H的状态(即按键放开),关扬声器
OUT61H,AL;通过监控端口61H的PB4固定不变的触发时间来产生延迟时间
POPDI;恢复寄存器状态
POPDX
POPCX
POPBX
POPAX
RET
GEN_HANDENDP
3、延时程序。
80x86的各种处理器采取了6~66MHz的工作频率,loop指令的执行时间在这些处理器上也不相同。
为了建立一个与处理器无关的延时,IBM采用了一种利用硬件产生时间延时的方法,即通过监控端口61H和PB4,使PB4每15.08微秒触发一次,一产生一个固定不变的时间基准。
在IBMPCATBIOS的WAITF子程序,就是一个产生Nx15.08微秒时间演示的程序。
调用WAITF子程序时,CX寄存器必须装入15.08微秒的倍数N。
利用WAITF子程序能获得任意的时间延时,而不必在考虑CPU的型号和工作频率。
具体实现如下:
WAITFPROCNEAR
;延时程序
PUSHAX
MOVCX,DELAY_TIME
WAITF1:
INAL,61H
ANDAL,10H;检查PB4口
CMPAL,AH;判断AL变化否
JEWAITF1;没有变化则等待AL变化
MOVAH,AL;保存PB4的新状态(AL中)
LOOPWAITF1;CX-1不为0就回到WAITF1
POPAX;AX出栈
RET
WAITFENDP
4、音符的演奏。
在PC系列机上,8254的三个计数器各有其作用,计数器0用于维护系统时钟;计数器1用于周期性的向DMA发送数据请求信号,供存储器刷新使用;计数器2接到扬声器用来产生声音。
各计数器的输入时钟脉冲频率均为1.19318MHz。
通过设置计数值可以产生各种频率的声音。
与此同时,许多输入输出操作都是由8255A可编程外设接口来控制的。
利用CPU支持的外围电路8254与8255,通过汇编程序改变8255的PB0,PB1口,接通扬声器,使得计算机能够发出一定频率的声音,同时通过8254的与8255连接的2号计数器控制指定频率,从而达到控制扬声器的音调的效果。
具体实现如下:
GEN_HANDPROCNEAR;手动演奏发声程序
;IN:
DI
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHDI
;定时器初始化程序
MOVAL,0B6H;定时器初始化,
;选择计数器2,工作在方式3OUT43H,AL
;OUT43H,AL;向定时器送初值
MOVDX,12H;1.1931Mhz/给定的频率=12348h/给定频率=计数初值
MOVAX,348CH;12348h存入DX:
AX中,商存AX,余数存DX
DIVDI;DI为给定的频率
OUT42H,AL;定时器送处值
INAL,61H;开扬声器
MOVAL,AH;给定时器2写入AX中存放的计数初值
OUT42H,AL
INAL,61H
MOVAH,AL;把8255输出端的61H的0、1位置1,并把端口状态写入AH
ORAL,3
OUT61H,AL
WAIT1:
CALLWAITF;调用延时程序
INAL,60H;读取键盘扫描码,按下和放开都有相应的扫描码,放开码=按下码+80h>80h
TESTAL,80H;查询键是否放开
JZWAIT1;未放开继续查询,AL不等于80H则继续延时
MOVAL,AH;恢复8255端口61H的状态(即按键放开),关扬声器
OUT61H,AL;通过监控端口61H的PB4固定不变的触发时间来产生延迟时间
POPDI;恢复寄存器状态
POPDX
POPCX
POPBX
POPAX
RET
GEN_HANDENDP
5、自动播放歌曲。
(1)、为所要播放的乐曲的定义一个频率表和节拍表。
以所播放的第二首歌曲两只老虎为例:
频率表:
MUS_FREQ2DW262,294,330,262,262,294,330,262;两只老虎
DW330,349,392,330,349,392,392,440
DW392,349,330,262,392,440,392,349
DW330,262,294,196,262,294,196,262
DW262,294,330,262,262,294,330,262
DW330,349,392,330,349,392,392,440
DW392,349,330,262,392,440,392,349
DW330,262,294,196,262,294,196,262
DW0
节拍表:
MUS_TIME2DW25,25,25,25,25,25,25,25,25,25
DW50,25,25,50,12,12,12,12,25,25
DW12,12,12,12,25,25,25,25,50,25,25,50
DW25,25,25,25,25,25,25,25,25,25
DW50,25,25,50,12,12,12,12,25,25
DW12,12,12,12,25,25,25,25,50,25,25,50
(2)、分表将两个表的偏移地址放入SI和BP中
LEABP,MUS_TIME2
LEASI,MUS_FREQ2
(3)、从表中读出的音符频率放入DI中,取出音符的持续时间(10s的倍数)放入BX中。
MOVDI,[SI]
MOVBX,[BP]
(4)、最后调用GEN_AUTO子程序发出声音。
6、C、D调的转换。
从C调向D调进行转换,先判断当前音符为哪种调,若为C调,则进行跳转,跳转的过程中开D灯,关C灯;反之同原理。
调用的是SCAN_TUNE子程序。
SCAN_TUNEPROCNEAR;
;C/D调判断及其状态在屏幕上的显示
;IN:
DL键盘扫描码
;OUT:
TUNE
CMPDL,2EH;判断是C否
JNZNEXT_D;不是则判断是D否
MOVTUNE,'C'
DRAW55,38,60,41,0EH;关D灯
DRAW65,38,70,41,0AH;开C灯
JMPTUNE_END;结束
NEXT_D:
CMPDL,20H;判断D否
JNZTUNE_END
MOVTUNE,'D'
DRAW55,38,60,41,0AH;开D灯
DRAW65,38,70,41,0EH;关C灯
TUNE_END:
RET
SCAN_TUNEENDP
4、代码及分析
;宏定义
DRAWMACROSTART_X,START_Y,END_X,END_Y,COLOR
LOCALDRAW_NEXT
;local:
避免宏重复调用时,标号的重复
;功能:
画填充的矩形
;使用条件:
START_XPUSHAX
PUSHBX
PUSHCX
PUSHDX
MOVAH,0CH;写像素点,12号功能,写图形像素
MOVAL,COLOR;设置颜色,像素值
MOVBH,0;选用页号0
MOVCX,START_X;列起始点
MOVDX,START_Y;行起始点
DRAW_NEXT:
INT10H;画点
INCCX;开始画横线
CMPCX,END_X;比较行是否画完
JNEDRAW_NEXT;画另一行
MOVCX,START_X;另一行的起始点
INCDX;下一行
CMPDX,END_Y;比较列是否画完
JNEDRAW_NEXT;未完继续画
POPDX;出栈
POPCX
POPBX
POPAX
ENDM
DRAWSQREMACROSTART_X,START_Y,END_X,END_Y,COLOR
LOCALROW_UP,ROW_DOWN,RANK_LEFT,RANK_RIGHT
;功能:
画不填充的矩形
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHSI
MOVAH,0CH;写像素点
MOVAL,COLOR;设置颜色
MOVBH,0;选用页号0
MOVCX,START_X;列起始点
MOVDX,START_Y;行起始点
ROW_UP:
;画上边
INT10H;画点
INCCX;画横线
CMPCX,END_X;比较行是否画完
JNEROW_UP;画另一边
RANK_RIGHT:
;画右边
INT10H;画点
INCDX;画横线
CMPDX,END_Y;比较行是否画完
JNERANK_RIGHT;画另一边
MOVCX,START_X;下边起始点
MOVSI,END_X
INCSI
ROW_DOWN:
;画下边
INT10H;画点
INCCX;画横线
CMPCX,SI;比较行是否画完
JNEROW_DOWN;画另一边
MOVDX,START_Y;右边起始点
MOVCX,START_X
RANK_LEFT:
;画右边
INT10H;画点
INCDX;画横线
CMPDX,END_Y;比较行是否画完
JNERANK_LEFT;画另一边
POPSI
POPDX
POPCX
POPBX
POPAX
ENDM
;数据段
DATASEGMENT
;定义在屏幕绘制字
START_COLDB?
;存储起始行
TEXTDB13;起始行
DB4;起始列
DB0AH
DB'*********ThisisPiano**********',0FFH,'***Welcome!
Haveagoodtime!
***',0FFH;字体颜色,设置颜色
DB'DreamPiano',0FFH,'LiuZhuHuiANDLiuJing2013-11-22',0FFH,0FFH;显示字
DB0FFH,'1a.s.d.f.g.h.jTOMAKEMUSIC'
DB0FFH,'2F2~F5TOPLAYAMUISC'
DB0FFH,'3shiftand+/-TOup/downTHEMUSIC'
DB0FFH,'4L/RSHIFTTOHIGHT/LOW.'
;DB10DUP(4DUP(0DBH),4DUP(20H)),0FFH;颜色交叉矩形
;DB10DUP(4DUP(20H),4DUP(0DBH)),0FFH
;DB10DUP(2DUP(0DBH),2DUP(20H)),0FFH
;DB10DUP(2DUP(20H),2DUP(0DBH)),0FFH
;DB10DUP(2DUP(0DBH),2DUP(20H)),0FFH
;DB10DUP(2DUP(20H),2DUP(0DBH)),0FFH
DB00
;白色琴键坐标
ST_LXDW50,61,72,83,94,105,116;起点横坐标
ST_MXDW127,138,149,160,171,182,193
ST_HXDW204,215,226,237,248,259,270
ST_YDW50;起点纵坐标
ED_LXDW60,71,82,93,104,115,126;终点纵坐标
ED_MXDW137,148,159,170,181,192,203
ED_HXDW214,225,236,247,258,269,280
ED_YDW90;终点纵坐标
;黑色琴键坐标
BT_XDW57,68,90,101,112;起点横坐标
DW134,145,167,178,189
DW211,222,244,254,265
BT_YDW50;起点纵坐标
BD_XDW64,75,97,108,119;终点横坐标
DW141,152,174,185,196
DW218,229,251,262,273
BD_YDW70;终点纵坐标
;音乐频率值
LOWDDW131
LOWDDDW221,248,278,294,330,371,416;低音
MIDDW262
MIDDDW441,495,556,589,661,742,833;中音
HGHDW523
HGHDDW882,990,1112,1178,1322,1484,1665;高音
KEYFLAGDB1;标记低(0)、中
(1)、高
(2)音键
KEYNUMDW1;存储1~7,按键编号缓存,提取对应的按键位置
DELAY_TIMEDW7000;延时缓存,用于播放时存如BX计数
SONGDW100;保存所选的自动演奏的曲目
TUNEDW1;标记c调或d调,按键状态缓存
AUDIODW1;标记低音{1},中音{2},高音{3}
;自动演奏的歌曲频率和延时
MUS_FREQ1dw196,220
dw262,262,262,262,262,220,196
dw262,262,262,262,294,262,220,262
dw294,294,294,294,294,262,220
dw294,294,294,294,330,294,330,392
dw440,440,392,440,392,330
dw294,294,330,294,262,220,196,220
dw262,262,262,262,262,220
dw262,196,220
dw440,440,392,440,524,440
dw392,330,294,262,220,196,220
dw262,262,262,262,294,262
dw262,330,392
dw440,440,440,440,524,440
dw392,392,392,440,392,330,294
dw262,262,262,262,294
dw330,330,294
dw262,262,262,262,524,440
dw392,392,392,440,392,330,392
dw440,524,524,440,392
dw392,330,392
dw440,440,440,440,524,440
dw392,392,392,440,392,330,294
dw262,262,262,262,392
dw330,330,294
dw262,262,262,262,294,330
dw392,392,330,392,330,392
dw440
dw9,9,196,660,294,294,262
dw262,-1
MUS_TIME1dw40,40
dw40,20,40,40,80,40,40
dw40,20,40,20,20,80,40,40
dw40,20,40,40,80,40,40
dw40,20,40,20,20,80,40,40
dw4