📄 pingpang_game.txt
字号:
ORG 0000H
LJMP START
0RG 0003H
LJMP INT0
ORG 000BH
LJMP TIME0
;-----------------------------------------------端口地址
QIUOUT EQU 8100H
PCOMM EQU 8706H
LOUT EQU 8702H ;定义行输出接口(注:如果使用8279,这两个接口地址可能右所变化)
CIN EQU 8700H ;和列输入接口的设备地址
;-----------------------------------------------相关标志位
SAIZHI EQU 10H.0 ;0为11分制,1为21分制
FAQIUQ EQU 10H.1 ;0表示该A发球,1表示该B发球
FAQIUM EQU 10H.2 ;0表示未发球,1表示已发球
JIQIUF EQU 10H.3 ;0表示A击球,球往右移,1表示B击球,球往左移
AAJIAN EQU 10H.4 ;为1时,A按下相应按键
BAJIAN EQU 10H.5 ;为1时,B按下相应按键
DEFENA EQU 10H.6 ;为1时,A得分了
DEFENB EQU 10H.7 ;为1时,B得分了
;----------------------------------------------暂存单元设置
QIUSUD EQU 11H ;球移动的速度
ADEFEN EQU 12H ;A的得分
BDEFEN EQU 13H ;B的得分
ASHENG EQU 14H ;A的获胜局数
BSHENG EQU 15H ;B的获胜局数
FAQIUS EQU 16H ;连续发球的计数器
LEDDAT EQU 17H ;LED管显示球路的数据
;---------------------------------------------赛制信息
ZONGFE EQU 18H ;赛制下的局总分
HUANFA EQU 19H ;赛制下的换发球次数
HUOSJS EQU 20H ;赛制下获胜需要的获胜局数
;----------------------------------------------------初始化
START:MOV 10H,#0
MOV 11H,#5
MOV 12H,#0
MOV 13H,#0
MOV 14H,#0
MOV 15H,#0
MOV 16H,#0
MOV 17H,#01H
;---------------------------------------读入赛制信息,确定比赛比分,换发球次数,获胜局数
MOV A,#FFH
MOV P1,A
MOV A,P1
JB ACC.0,SA
MOV 18H,#11
MOV 19H,#2
MOV 20H,#3
SJMP SB
SA:MOV 18H,#21
MOV 19H,#5
MOV 20H,#4
;---------------------------------------------初始化8279数码管显示程序
SB:MOV DPTR,#COM8279
MOV A,#0D3H
SC:MOVX A,@DPTR
JB ACC.7,SC
MOV A,#34H
MOVX @DPTR,A
MOV A,#10H
MOVX @DPTR,A
;-------------------------------------------
B-SD:MOV R0,QIUSUD ;R0标志:定时10个50ms为0.5S ,读入球速信息
LCALL QIULED ;输出显示LED管
LCALL FENLED ;显示当前比分,若为初始化则为0
MOV TMOD,#01H
MOV TL0,#0
MOV TH0,#76 ;定时器0送初值(50ms定时)
SETB TR0
SETB ET0
SETB EA ;允许定时中断
;--------------------------------------------------键盘扫描子程序,若没有键按下,则一直循环扫描
KEY:MOV DPTR,#PCOMM
MOV A,#90H
MOVX @DPTR,A ;将8255的A口设置为方式0输入,B口设置为方式0输出
LCALL KEYIN
MOV A,R7
CJNE A,#00H,KEY1 ;根据键值确定按键按下的为哪个??
SETB AAJIAN ;0键按下,即击球按键A被按下 ,事实上,A,B不能被同时按下,如果被同时按下则认为A按下
SJMP KEY2
KEY1:CJNE A,#06H,KEY2
SETB BAJIAN ;6键按下,即击球按键B被按下
KEY2:CJNE A,#02H,KEY3
MOV A,QIUSUD ;2键按下,减速键
CJNE A,#2,SK1 ;球移动速度的下限值是0.1s=50*2
SJMP KEY4
SK1:SUBB A,#02H
MOV QIUSUD,A
KEY3:CJNE A,#03H,KEY4
MOV A,QIUSUD ;3键按下,加速键
CJNE A,#10,SK2 ;球移动速度的上限值是0.5s=50*10
SJMP KEY4
SK2:ADD A,#02H
MOV QIUSUD,A ;修改后(加或者减)的速度值重新存回SUDU中
KEY4:JB AAJIAN,ACHULI ;
JB BAJIAN,BCHULI ;有键按下转处理程序
JB DEFENA,ACHULI3 ;无键按下或者按下的是其他键
JB DEFENB,BCHULI3 ;有A,B得分标志则清标志转相应的处理单元
SJMP KEY ;则循环查询键盘
;--------------------------------------------------
;注意:即使AB均没有按键,仍有可能得分,所以得分判断不应该尽在按键时才有,在某方未能及时击球,也应该置位相应标志位,并给予处理
;--------------------------------------------------
;对按键A按下时做出以下的判断
ACHULI:CLR AAJIAN ;清按键A标志
JB FAQOIM,AHCULI1 ;若已发球,则转ACHULI1
JB FAQIUQ,KEY ;若未发球,且A没有发球权,则不判分转KEY
SETB FAQIUM ;未发球,且A有发球权,则按下A键后即表示A发球,置已发球标志
CLR JIQIUF ;置击球标志:A击球,球往右移动
;---------------------------------发球计数控制
INC FAQIUS
MOV A,FAQIUS
CJNE A,HUANFA,SE1
MOV FAQIUS,#0 ;超过发球数,则清零发球计数器,取反发球权标志位
CPL FAQIUQ
SJMP SE2
SE1:MOV FAQIUS,A
SE2:MOV LEDDAT,#01H ;A的预发球状态
SJMP KEY ;判分结束转KEY
ACHULI1:MOV A,LZHI ;发球状态下,A键按下,表示A试图在接球,判断A是否合法击球
CJNE A,#01H,ACHULI2 ;若23H中值(LED显示值)不为#01H,则转ACHULI2(失分)(A提前击球)
CLR JIQIUF ;置击球标志:A击球,且满足回球规则,为合法击球,清击球标志位,继续读键盘按键
SJMP KEY ;A准确击球转判分结束
ACHULI2:SETB DEFENB ;A未能准确击球失分,则B得分置B得分标志
;----------------------------------B得分,判断比赛获胜局,局比分,比赛结束否?
ACHULI3:INC BDEFEN
CLR DEFENB
MOV A,BDEFEN
CJNE A,ZONGFE,PFEND1 ;B得分未超过11,则转判分结束PFEND1
MOV FENA,#00H
MOV FENB,#00H ;清空当局得分
INC BSHENG ;
MOV A,BSHENG
CJNE A,HUOSJS,PFEND1
LJMP WIN1 ;B得分到11,则转主程序重新开始游戏
;-----------------------------------------------------------------------
对按键B按下时做出以下的判断
BCHULI:CLR JIANB
JB FAQIUM,BCHULI1 ;若已发球,则转BCHULI1
JNB FAQIUQ,KEY ;若未发球,且B没有发球权,则不判分转KEY
SETB FAQIUM ;未发球,且B有发球权,则B按键发球,同时置已发球标志
SETB JIQIUF ;置击球标志:B击球
;----------------发球计数控制
MOV A,FAQIUS
INC A
CJNE A,HUANFA,SF1
MOV FAQIUS,#0
CPL FAQIUQ
SJMP SF2
SF1:MOV FAQIUS,A
SF2:MOV LEDDAT,#01H
MOV LEDDAT,#80H
SJMP KEY ;判分结束转KEY
BCHULI1:MOV A,LZHI ;
CJNE A,#80H,BCHULI2 ;若23H中值(LED显示值)不为#80H,则转PFENB2(失分)(B提前击球)
SETB JIQIUF ;置击球标志:B击球
SJMP KEY ;判分结束不需要重新开始游戏转KEY
BCHULI2:SETB DEFENA ;B失分即A得分置A得分标志
;----------------------------
BCHULI3:INC ADEFEN
CLR DEFENA
MOV A,ADEFEN
CJNE A,ZONGFE,PFEND1 ;A得分未超过11,则转判分结束PFEND1,继续比赛
MOV FENA,#00H ;A得分超过11,则清A得分计数器
MOV FENB,#00H ;清空当局得分
INC BIFENA ;A的获胜局数自增1,转而判断获胜局是否超过4
MOV A,BIFENA
CJNE A,#03H,PFEND1 ;A比分未到3,转
LJMP WIN1 ;A比分到3,则转主程序清比分重新开始游戏
;----------------------------------------------------------------
PFEND1:CLR TR0 ;一局比赛完,关定时中断
CLR FAQIUM ;清空已发标志
JB FAQIUQ,PFEND2 ;根据发球权赋LED值用于显示待发球状态
MOV LEDFAT,#01H ;发球权在A
LJMP B-SD ;
PFEND2:MOV LEDDAT,#80H ;发球权在B
LJMP B-SD ;判分结束需要重新开始游戏转B-SD ;判分结束
;-----------------------------------------------------------------
WIN1: WHATAREYOUFUCKINGDOING? DISPLAY
;----------------------------------------------------------中断服务程序
TIME0: PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
CLR TR0
MOV TH0,#76
MOV TL0,#0
DJNZ R0,TIME4
MOV R0,QIUSUD
JB FAQIUM TIME2
JB FAQIUQ TIME1
CPL LEDDAT.0
LCALL QIULED
SJMP TIME4
TIME1:CPL LEDDAT.7
LCALL QIULED
TIME2:MOV A,LEDDAT
JB JIQIUF,TIME3
CLR C
RLC A
MOV LEDDAT,A
LCALL QIULED
JNC TIME4
SETB DEFENA
SJMP TIME4
TIME3:CLR C
RRC A
MOV LEDDAT,A
LCALL QIULED
JNC TIME4
SETB DEFENB
TIME4:POP DPL
POP DPH
POP PSW
POP ACC
SETB TR0
RETI
;-----------------------------------------------读键盘子程序
MS20: MOV R3,#128 ;延时20ms子程序
MS1: MOV R4,#70
DJNZ R4, $
DJNZ R3, MS1
RET
KEYIN: MOV R7,#16 ;2×8键盘处理子程序,预设置无效键值
MOV DPTR,#LOUT ;先向行接口输出“全0”数据
MOV A,#0FCH
MOVX @DPTR, A
MOV DPTR,#CIN ;再读入列接口数据
MOVX A,@DPTR
CPL A ;判是否有键被按下?
JZ K05 ;没有,执行返回操作
ACALL MS20 ;可能有,执行延时去抖动
MOVX A,@DPTR ;重新读入列接口数据
CPL A ;判是否确实有键被按下
JZ K05 ;没有,执行返回操作
MOV R6,#0 ;有,初始化行计数器
MOV R5,#0FEH ;设置行扫描初值
K01: MOV DPTR,#LOUT ;输出行扫描数据
MOV A,R5
MOVX @DPTR,A
MOV DPTR,#CIN ;并读入列数据
MOVX A,@DPTR
CPL A ;判当前行是否有键被按下?
JNZ K02 ;有,进行后续处理
INC R6 ;无,增量行计数器
MOV A,R5 ;并变换行扫描数据
RL A
MOV R5,A
CJNE R6,#2,K01 ;判是否扫描完了全部行,若未完就再扫描下一行
RET ;完了,返回主调程序
K02: MOV R5, #0FFH ;初始化列计数器
K03: INC R5 ;增量列计数器
RR A ;将读入的列数据循环右移1位
JNB ACC.7,K03 ;判当前列是否为所按键的列号,若不是则继续以上动作
MOV A,R6 ;是,利用公式
RL A ;键值=行编号×8+列编号
RL A
RL A
ADD A, R5 ;计算出键值
MOV R7, A
MOV DPTR,#LOUT ;向行接口输出“全0”数据
MOV A, #0FCH
MOVX @DPTR, A
MOV DPTR,#CIN ;等待用户松开按键
K04: MOVX A, @DPTR
CPL A
JNZ K04
ACALL MS20
MOVX A,@DPTR
CPL A
JNZ K04
K05: RET ;返回主调程序
;--------------------------------------------------------
QIULED:MOV DPTR,#QIUOUT
MOV A,LEDDAT
MOV @DPTR,A
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -