📄 td1.asm
字号:
;处理开始界面和主界面间的延时的宏
DELAY1 MACRO
PUSH CX
PUSH DX
MOV DX,9000
DL11:
MOV CX,0FFFFH
DL12:
LOOP DL12
DEC DX
JNZ DL11
POP DX
POP CX
ENDM
;处理下降延时时的宏
DELAY2 MACRO
LOCAL DL21
LOCAL DL22
PUSH CX
PUSH DX
MOV DX,2000
DL21:
MOV CX,0FFFFH
DL22:
LOOP DL22
DEC DX
JNZ DL21
POP DX
POP CX
ENDM
;处理打出字幕延时的宏
DELAY3 MACRO
PUSH CX
PUSH DX
MOV DX,200
DL31:
MOV CX,0FFFFH
DL32:
LOOP DL32
DEC DX
JNZ DL31
POP DX
POP CX
ENDM
;敲击的的音乐宏
mus macro hz
push ax
push bx
push ds
mov ax,0
mov ds,ax ;段地址为000h
in al,61h ;打开定时器和扬声器
or al,3 ;置pb0和pb1
out 61h,al
mov bx,hz ;选用1000HZ音调
call far ptr beep
in al,61h ;关闭扬声器
xor al,3 ;清除pb0和pb1
out 61h,al
pop ds
pop bx
pop ax
endm
date segment
table db 'qpalzmxnskwieudjcnvbfhrytqscgyjmkopzoxicvubhnymtgrfjrekqdfghyuiopmbeswzaqwqpbncxmalalpnqcxzqetnclgfpoxzewe'
hour db 0 ;要初始化
minute db 0
second db 0
right db 0
total dw 0
date ends
stack segment stack
db 800 dup(0)
stack ends
code segment
assume ds:date,ss:stack,cs:code
start: mov ax,date
mov ds,ax
lea si,table
call mpc
call music
call topword
call enter
call down
mov ax,total
; call far ptr num_char
exit:
call music
mov ah,4ch
int 21h
;显示游戏开始界面的子程序
;入口参数---------------------空
;出口参数---------------------产生游戏开始界面
mpc proc
mov ah,0
mov al,3
int 10h
mov ah,15
int 10h
mov dx,0000h
mov ah,2
int 10h
mov al,08h
mov bh,0
mov cx,80 ;显示上眉
mov ah,0ah
int 10h
mov cx,1
mov dx,0100h ;显示左披
left: mov ah,2
int 10h
mov al,08h
mov ah,0ah
int 10h
inc dh
cmp dh,24
jb left
mov dl,79 ;显示右披
rightb: mov ah,2
int 10h
mov al,08h
mov ah,0ah
int 10h
dec dh
ja rightb
mov dx,1701h
mov ah,2
int 10h
mov al,01h
mov cx,78
mov ah,0ah
int 10h
mov dx,1800h
mov ah,2
int 10h
mov al,08h
mov cx,80 ;显示下眉
mov ah,0ah
int 10h
ret
mpc endp
;游戏开始时的音乐程序
music proc
push ax
push bx
push cx
push ds
mov ax,0
mov ds,ax ;段地址为000h
mov cx,2 ;计数值为3
in al,61h ;打开定时器和扬声器
or al,3 ;置pb0和pb1
out 61h,al
main1: mov bx,1800 ;选用1800HZ音调
call far ptr beep
mov bx,2000 ;选用2000HZ音调
call far ptr beep
mov bx,1000 ;选用1000HZ音调
call far ptr beep
mov bx,1600
call far ptr beep
mov bx,1200 ;选用1200HZ音调
call far ptr beep
mov bx,1400 ;选用1400HZ音调
call far ptr beep
loop main1 ;重复3次
in al,61h ;关闭扬声器
xor al,3 ;清除pb0和pb1
out 61h,al
pop ds
pop cx
pop bx
pop ax
ret
music endp
beep proc far
push ax
push bx
push dx
mov ax,34dch ;ax=1,193,180
mov dx,12h
div bx ;计算出相应音调的计数值
out 42h,al
mov al,ah ;对定时器2用计数值编程
out 42h,al
DELAY2 ;延时
pop dx
pop bx
pop ax
ret
beep endp
; 显示游戏界面上方字母的子程序
;入口参数-----------------si
;出口参数-----------------显示游戏界面上方字母
topword proc
mov cx,1
mov dx,0101h ;预制光标位置
con:
mov ah,2
int 10h
mov ah,0ah
mov al,table[si]
int 10h
; mus 1000
delay3
inc si
inc dl
cmp dl,79
jb con ;显示的字母不足78个转
ret
topword endp
;游戏界面子程序和游戏子程序间的等待ENTER输入的子程序
enter proc
push ax
push cx
push dx
mov al,0
again: mov ah,8
int 21h
cmp al,0ah ;有输入时比较输入是否为enter键
je out2
cmp al,0dh
jne again
out2: mov ah,2ch ;为enter键则读取游戏开始时刻
int 21h
mov hour,ch
mov second,cl
mov minute,dh
pop dx
pop cx
pop ax
ret
enter endp
;建立一个随机数发生程序,用于控制字母下降的位置的随机变化
;出口参数------------bl,存放一个小于79大于0的随机数
random proc far
push ax
push cx
push dx
mov ah,2ch
int 21h
cmp dl,78
ja above
cmp dl,0
ja zero1
inc dl
zero1: mov bl,dl
jmp ok
above: cmp dh,0
ja nzero
inc dh
nzero: mov bl,dh
ok: pop dx
pop cx
pop ax
ret
random endp
;游戏界面上方字母随机下落的子程序
;入口参数--------------主程序中的字母表table
;出口参数--------------键盘的输入值ax
down proc
PUSH CX
PUSH DX
PUSH AX
ANOTHER:MOV CX,1
MOV BH,0
MOV DH,1
CALL RANDOM
MOV DL,BL ;bl为random产生的随机数
INC TOTAL ;下降的字符个数的计数器增一
REPTD0: MOV AH,2
INT 10H ; set cursor position
MOV SI,BX
MOV AL,TABLE[SI]
MOV AH,10
INT 10H ; display spade
DELAY2
MOV AL,0
MOV AH,10
INT 10H
push dx
MOV DL,0FFH
MOV AH,6 ;判断控制台(键盘)是否有输入
INT 21H
pop dx
JZ CONDN ;无输入时转字符继续下落
CALL FAR PTR SPEKEY ;有输入时转特殊键处理
CONDN: INC DH
INC DH
CMP DH,23
JNE REPTD0
JE RECOVER
RECOVER:MOV DH,1
MOV DL,BL
MOV AH,2
INT 10H ;recover the top character
MOV SI,BX
MOV AL,TABLE[SI]
MOV AH,10
INT 10H
JMP ANOTHER
POP AX
POP DX
POP CX
RET
DOWN ENDP
;判断输入是否ESC、ENTER、TAB等特殊键,若是则进行处理否则转comkey子程序进行处理
;入口参数------------键盘输入的值ax
;出口参数------------对特殊键处理完毕,非特殊键给后面的comkey子程序处理
spekey proc far
cmp al,'Q'
jne notq
jmp exit ;为'Q'键则结束游戏
notq: cmp al,1bh
jnz concmp
; call far ptr time
JMP START ;为ESC键跳转到主程序头,调出主界面
concmp: cmp al,20h
jz istap
call far ptr comkey ;非特殊键转一般键处理
jmp gback
istap: ; call far ptr time ;为TAB键则暂停计时
call far ptr tapkey
gback: ret
spekey endp
;判断键盘是否有输入,记下输入,并与当前正在下落的字母比较
;人口:-------------------当前下落的字母序号放在bl中
;入口:-------------------键盘输入的字母放在ax中
comkey proc far
mov bh,0
mov si,bx
cmp al,table[si] ;有输入时比较输入是否和当前下落字母一致
jne back
inc right
call far ptr redown ;击中则调用另一字母下落子程序
back: mus 3000 ;没有击中后发出刺耳的音乐
ret
comkey endp
;击中后,修复顶部字母下落后的空缺,然后让另一字母开始下落
;人口:-------------------当前下落的字母序号放在bl中
;出口:-------------------另一字母开始下落
redown proc far
MOV DH,1
MOV DL,BL
MOV AH,2
INT 10H ;recover the top character
MOV AL,TABLE[SI]
MOV AH,10
INT 10H
MUS 300 ;击中后发出和悦的音乐
CALL DOWN
ret
redown endp
;实现按下tab键游戏暂停,并统计前段所用时间,再按下tab键游戏继续的子程序
;入口参数:-------------输入的tab键
tapkey proc far
push ax
push cx
push dx
MOV SI,BX
MOV AL,TABLE[SI]
MOV AH,10
INT 10H ; display spade
waittap:mov ah,8
int 21h
cmp al,20h ;有输入时比较输入是否为空格
jne waittap
MOV SI,BX ;为空格则清除当前光标所在字符
MOV AL,0
MOV AH,10
INT 10H
mov ah,2ch ;为空格则读取当前时刻
int 21h
mov hour,ch ;重置当前时刻
mov second,cl
mov minute,dh
pop dx
pop cx
pop ax
ret
tapkey endp
code ends
end start
;函数功能:将某一数按十进制输出
;入口参数: ax---存贮一字
;出口参数: 转换后的数字在显示器上输出
;所用寄存器:bx----地址逆计数器
data2 segment
numchar db 6 dup(0)
cout equ $-numchar
pot2 db ?
data2 ends
stack2 segment stack
db 100 dup(0)
stack2 ends
pro2 segment
assume cs:pro2,ds:data2,ss:stack2
num_char proc far
push si
push di
push ds
push cx
push dx
mov cx, data2 ;将numchar与数据段联系起来
mov ds,cx
mov bx,cout ;地址逆计数器
dec bx
lea si,numchar
mov ch,'$'
mov [bx+si],ch
mov pot2,0h ;预置pot2=0代表ax为正
mov cx,10
mov dx,0 ;ax扩展待用
cmp ax,0 ;判断待输出的数字正负性
jns pov ;ax为正转
mov pot2,'-'
neg ax ;将负数转换成对应相反数
pov: idiv cx
add dl,30h
dec bx
mov [bx+si],dl
cmp ax,0
jne not_end
jmp exit2
not_end:mov dx,0
jmp pov
exit2: dec bx
mov al,pot2
mov [bx+si],al
mov dx,bx
mov ah,9
int 21h
pop dx
pop cx
pop ds
pop di
pop si
ret
pro2 ends
num_char endp
;统计游戏有效时间的子程序
;入口参数:主程序记录上一当前时刻的hour,minute,second
;出口参数:子程序统计实际所用时间的zhour,zminute,zsecond
;注意每次重新启动计时功能前需将hour,minute,second即时化
tdata segment
zhour db 0
zminte db 0
zsecond db 0
tdata ends
tstack segment stack
db 100 dup(0)
tstack ends
tcode segment
assume ds:tdata,ss:tstack,cs:tcode
time proc far
push ax
push bx
push cx
push dx
mov ah,2ch ;读取当前时刻
int 21h
mov ah,ch ;存储当前时刻
mov al,cl
mov bh,dh
cmp dh,second
jns setsec
dec cl
add dh,60
setsec: sub dh,second ;设置秒数
add zsecond,dh
cmp zsecond,60
jb dealmin
sub zsecond,60
inc zminute
dealmin:cmp cl,minute
jns setmin
del ch
add cl,60
setmiu: sub cl,minute ;设置分钟数
add zminute,cl
cmp zminute,60
jb dealhou
sub zminute,60
inc zhour
dealhou:cmp ch,hour
jnb sethou
add ch,24
sethou: sub ch,hour ;设置小时数
add zhour,ch
mov hour, ah
mov minute,al
mov second,dh
pop dx
pop cx
pop bx
pop ax
ret
time endp
tcode ends
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -