📄 typewriter.asm
字号:
;Assembly Language
;Compile:MASM
.model small
.stack 256
.data
ESCAPE=1bh
PAUSE=20h
mess1 db "1.be suit for the first time to practice",0dh,0ah,'$'
mess2 db "2.The speed make you an inprove",0dh,0ah,'$'
mess3 db "3.The speed you may have a try!",0ah,0ah,'$'
mess4 db "4.I recommand on you not!",0dh,0ah,'$'
choice db "Please make a choice(1~4):",'$'
endmess1 db "Your speed is:",'$'
speed db 0
endmess2 db "(letters/min)",'$'
endtotal db "The number you have hitted is:",'$'
endcorrect db "The number you have hitted correctly is:",'$'
endrate db "The correcting rate:",'$'
commons db "Press any key to countinue or ESCAPE to exit!",'$'
attention db "Make sure the CAPS LOCK key you have pressed before you starting......",'$'
records db 4 dup (0)
curchar db 4 dup (0) ;current characters
curposition dw 10,25,35,70 ;current positions
;
hour db 0
minite db 0
second db 0
;
sleep dw 0 ;standard time
total dw 0
correct dw 0
stoax dw 0 ;store the regesister ax
.code
main proc far
start:
mov ax,@data
mov ds,ax ;set the current data segment
mov correct,0 ;no character has been pressed
call clear ;clear the screen
call message
mov ah,8
int 21h ;getch
cmp al,ESCAPE
jz out_game
call clear
call initial ;let the first group of characters to fall
process:
mov cx,4
inc_row:
mov si,cx
dec si
shl si,1 ;get the number as word
mov dx,curposition[si]
inc dh
cmp dh,23
jb adjust
mov dh,0 ;get the next row to display
call random
shr si,1
mov curchar[si],dl ;if the chararacter fall down the buttom,
shl si,1 ;generate anther character
add dl,37
cmp dl,80 ;get the next volume to display
jb adjust
sub dl,80
adjust:
mov curposition[si],dx
loop inc_row ;increase one row
call showchar ;display the characters one time
cmp al,ESCAPE
jz over
call showtime ;display the time
;mov ah,1
;int 16h
;jz process
;mov ah,0
;int 16h
;cmp al,ESCAPE
;jz over
jmp process ;the process of characters fall down
over:call clear
call complete
mov ah,8
int 21h
cmp al,ESCAPE ;getch
jnz start
call clear
out_game:
mov ax,4c00h
int 21h
main endp
;
;in:
;out:
;function:print the prompt message
message proc
push ax
push bx
push dx
mov ah,2
mov dh,8 ;set the bar to show the message at the
mov dl,15 ;center of the screen
mov bh,0
int 10h ;(15,8)
push dx
mov dx,offset mess1
mov ah,9
int 21h
pop dx
mov ah,2
inc dh
int 10h
push dx
mov dx,offset mess2
mov ah,9
int 21h
pop dx
mov ah,2
inc dh
int 10h
push dx
mov dx,offset mess3
mov ah,9
int 21h
pop dx
mov ah,2
inc dh
int 10h
push dx
mov dx,offset mess4
mov ah,9
int 21h
pop dx
mov ah,2
inc dh
int 10h
push dx ;store current position
mov dx,offset choice
mov ah,9
int 21h
wait_hit: ;wait to hit a key
mov ah,8
int 21h
cmp al,'1'
jz get_ret
cmp al,'2'
jz get_ret
cmp al,'3'
jz get_ret
cmp al,'4'
jz get_ret
cmp al,ESCAPE
jz get_ret
jmp wait_hit
get_ret:
mov dl,al
mov ah,2
int 21h
sub al,30h
sub al,5
neg al
xor ah,ah
mov cl,150
mul cl
mov sleep,ax ;set standard time
pop dx
inc dh
push dx
mov bh,0
mov ah,2
int 10h ;row+1,colume maintain
mov ah,9
mov al,20h
mov bh,0
mov bl,1Ah
mov cl,50
int 10h
mov dx,offset commons
mov ah,9
int 21h ;print the message to arouse attention
mov ah,2
pop dx
inc dh
inc dh
mov dl,8
mov bh,0
int 10h
mov ah,9
mov al,20h
mov bh,0
mov bl,1Ah
mov cx,70
int 10h
mov dx,offset attention
mov ah,9
int 21h
pop dx
pop bx
pop ax
ret
message endp
;in:
;out:
;function:initial the character to fall at the first time
initial proc
push ax
push bx
push cx
push dx
mov ah,2ch
int 21h
mov hour,ch
mov minite,cl
mov second,dh ;get the start time
mov cx,4
cycle_init: ;set the position at start
mov si,cx
dec si
call random
mov curchar[si],dl
call showchar
push cx
push si
mov cx,5
fori: pop si
push si
forj:
shl si,1
mov dx,curposition[si]
inc dh
mov curposition[si],dx
shr si,1 ;row+1
inc si
cmp si,4
jb forj
call showchar
loop fori
pop si
pop cx
mov dx,sleep
mov dx,50
call delay ;delay the sleep time
loop cycle_init ;cycle to print the character with same delay
pop dx
pop cx
pop bx
pop ax
ret
initial endp
;in:
;out:
;function:make the character in the array of curchar display one time
showchar proc
push bx
push cx
push dx
push si
call showtime
mov cx,4
cycle_show:
push cx
mov si,cx
dec si ;set the output pointer
mov ah,2
shl si,1
mov dx,curposition[si]
shr si,1
mov bl,0
int 10h ;set the current position
mov ah,9
mov al,curchar[si]
mov bh,0
mov bl,1Eh
mov cx,1
int 10h
pop cx
loop cycle_show ;show 4 characters
test_show:
mov ah,1 ;test the keybord
int 16h
jz put_off
mov stoax,0 ;store the pressed key to return
mov ah,0
int 16h
inc total
xor ah,ah
mov stoax,ax
cmp al,ESCAPE ;return the exit sign
jz board ;escape to return
mov cx,4 ;cycle to test the key pressed
compare: mov si,cx
dec si
cmp al,curchar[si]
jnz continue ;hit the wrong key
inc correct
mov ah,2 ;current position
shl si,1
mov dx,curposition[si]
shr si,1
mov bh,0
int 10h
push cx
mov ah,9 ;change the color of the correct character
mov al,curchar[si]
mov bh,0
mov bl,1Ch ;black_red
mov cx,1
int 10h
pop cx
mov records[si],1 ;record the position of character pressed
continue:loop compare
jmp test_show ;make sure no chararacter is in keybord buffer
board: jmp exit_ret ;a jump board
put_off: mov ah,2
xor dx,dx
mov bh,0
int 10h ;remove the bar
mov dx,sleep
call delay ;put off the standard time
call showtime
mov cx,4
cycle_dis:
push cx
mov si,cx
dec si
mov ah,2 ;current position
shl si,1
mov dx,curposition[si]
shr si,1
mov bh,0
int 10h
mov ah,9
mov al,curchar[si]
mov bh,0
mov bl,11H ;show the characters as the background color
mov cx,1
int 10h
pop cx
loop cycle_dis ;dipose the current character
mov cx,4
convert: mov si,cx
dec si
or records[si],0
jz next_vert
push cx
call random
mov curchar[si],dl ;set the next character that will be displayed
shl si,1
mov dx,curposition[si]
mov dh,0
add dl,29
cmp dl,80
jb next_col
sub dl,80
next_col:mov curposition[si],dx
;set the position of the next character diplay
shr si,1
mov records[si],0
pop cx
next_vert:loop convert
call showtime
exit_ret:
pop si
pop dx
pop cx
pop bx
ret
showchar endp
;in:
;out:
;function:put the time show at the buttom of screen
showtime proc
push ax
push bx
push cx
push dx
mov ah,2
mov dh,24
mov dl,36
mov bh,0
int 10h ;display at (36,24)
xor al,al
mov ah,2ch
int 21h ;get the current system time
sub ch,hour
sub cl,minite
dec cl
sub dh,second
add dh,60
cmp dh,60
jae next_add1
jmp next_show
cmp cl,60
jae next_add2
jmp next_show
next_add1:
sub dh,60
inc cl
jmp next_show
next_add2:
sub cl,60
inc ch
next_show:
mov al,ch ;deal with the hour
xor ah,ah
mov bl,10d
div bl
push ax
add al,30h
mov dl,al
mov ah,2
int 21h
pop ax
add ah,30h
mov dl,ah
mov ah,2
int 21h
mov dl,':'
mov ah,2
int 21h
mov al,cl ;deal with the minite
xor ah,ah
div bl
push ax
add al,30h
mov dl,al
mov ah,2
int 21h
pop ax
add ah,30h
mov dl,ah
mov ah,2
int 21h
mov dl,':'
mov ah,2
int 21h
mov al,dh ;deal with the second
xor ah,ah
div bl
push ax
add al,30h
mov dl,al
mov ah,2
int 21h
pop ax
add ah,30h
mov dl,ah
mov ah,2
int 21h
pop dx
pop bx
pop cx
pop ax
ret
showtime endp
;in:
;out:
;function:clear the screen with the attribe blue_cyan
clear proc
push ax
push bx
push cx
push dx
mov ah,6
mov al,0
mov bl,0
mov bh,1Eh
mov cl,0
mov ch,0
mov dh,24
mov dl,79
int 10h ;clear the creen
mov ah,2
mov dh,0
mov dl,0
mov bl,0
int 10h ;set bar at (0,0)
pop dx
pop cx
pop bx
pop ax
ret
clear endp
;in:dx=a number >0
;out:
;function:delay the CPU's operating time
delay proc
push cx
no_del:mov cx,0ffffh
noop: loop noop
or dx,dx
dec dx
jnz no_del
pop cx
ret
delay endp
;in:
;out:dx=the character generated
;function:generate a character
random proc
push ax
push bx
push cx
mov cx,100
cycle: push cx
mov ah,2ch
int 21h
cmp ax,0
jz add_dom
mov cx,dx
xor ch,ch
xor dx,dx
mul cx
add_dom:
add ax,dx
mov cx,0ffffh
no_op: loop no_op
pop cx
loop cycle
mov cx,26
xor dx,dx
div cx
xor dh,dh
add dl,41h
pop cx
pop bx
pop ax
ret
random endp
;in:
;out:
;function:deal with the the result and display the relevant information
complete proc
push ax
push cx
push dx
mov ah,2ch
int 21h ;get the complete time
sub ch,hour ;ch=hour
sub cl,minite ;cl=minite
sub dh,second ;dh=second
cmp second,30
jb next_sub
inc cl ;second>=30 as one minite
next_sub:
xor ch,ch
cmp cl,0
jnz next_div
inc cl
next_div:
mov ax,correct
xor dx,dx
div cx ;caculate the speed(ax)
mov speed,al
mov ah,2 ;(22,10)
mov dh,10
mov dl,22
mov bl,0
int 10h ;show the result at the center of screen
push dx
mov dx,offset endtotal
mov ah,9
int 21h
mov dx,total
call decimal
pop dx
inc dh
push dx
mov bh,0
mov ah,2
int 10h ;(22,11)
mov dx,offset endcorrect
mov ah,9
int 21h
mov dx,correct
call decimal
mov ah,2
pop dx
inc dh
push dx
mov bh,0
int 10h ;(22,12)
mov dx,offset endrate
mov ah,9
int 21h
mov ax,correct
xor dh,dh
mov cx,100
mul cx
mov cx,total
div cx ;computer the correcting rate
mov dx,ax
call decimal
mov dl,"%"
mov ah,2
int 21h
mov ah,2
pop dx
inc dh
push dx
mov bh,0
int 10h ;(22,13)
mov dx,offset endmess1
mov ah,9
int 21h
mov dl,speed
xor dh,dh
call decimal
mov dx,offset endmess2
mov ah,9
int 21h ;print the end message
pop dx
mov ah,2 ;(23,14)
inc dh
mov bh,0
int 10h
mov ah,9
mov al,20h
mov bh,0
mov bl,1Ah
mov cl,50
int 10h
mov dx,offset commons
mov ah,9
int 21h
pop dx
pop cx
pop ax
ret
complete endp
;in:
;out:
;function:display a number as a decimal number
decimal proc
push ax
push bx
push cx
push dx
mov ax,dx
mov cx,10
mov dx,-1
push dx ;the exit paremeter of the stack
next_de:xor dx,dx
div cx
add dx,30h
push dx
or ax,ax
jnz next_de
dis_de: pop dx
or dx,dx
jz dis_de
cmp dx,-1
jnz deal_de
mov dx,30h
mov ah,2
int 21h
ret
deal_de:mov ah,2
int 21h
pop dx
cmp dx,-1
jnz deal_de
pop dx
pop cx
pop bx
pop ax
ret
decimal endp
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -