📄 1212.asm
字号:
ioport equ 0c800h-0280h
a_8253 equ ioport+280h
b_8253 equ ioport+281h
c_8253 equ ioport+282h
d_8253 equ ioport+283h
a_8255 equ ioport+288h
b_8255 equ ioport+289h
c_8255 equ ioport+28ah
d_8255 equ ioport+28bh
row1 equ ioport+290h ;red
row2 equ ioport+298h ;yellow
col equ ioport+2a0h
data segment
str DB 0DH,0AH,'*** Welcome to the system!$'
str1 db 0dh,0ah,'*** The program is designed by *********** ! $'
str2 db 0dh,0ah,'*** you should press the botton after the red led light! $'
str4 db 0dh,0ah,'*** Please use the k7 to start(or restart)!$'
str5 db 0dh,0ah,'*** The player A,Congratulations! You win!$'
str6 db 0dh,0ah,'*** The player B,Congratulations! You win!$'
str7 db 0dh,0ah,'*** The player Aand the player B,Congratulations! You both win!$'
str8 db 0dh,0ah,'*** The player A,I am sorry! You fail !$'
str9 db 0dh,0ah,'*** The player B,I am sorry! You fail !$'
str10 db 0dh,0ah,'*** The player A and the player B,I am sorry! You both fail !$'
str11 db 0dh,0ah,'*** I am sorry! someone got out of the line!$'
str12 db 0dh,0ah,'*** I am sorry! nobody attend in time!$'
str13 db 0dh,0ah,'*** Continue? (y/n)$'
rowdata db 0feh,82h,82h,0feh ;0
db 0feh,0,0,0 ;1
db 0f2h,92h,92h,9eh ;2
db 0feh,92h,92h,92h ;3
db 0feh,1,1,0f0h ;4
db 9eh,92h,92h,0f2h ;5
db 9eh,92h,92h,0feh ;6
db 0feh,80h,80h,80h ;7
db 0feh,92h,92h,0feh ;8
db 0feh,92h,92h,0f2h ;9
rowwrong db 81h,42h,24h,18h,18h,24h,42h,81h ;显示X
coldata db 1,2,4,8,16,32,64,128
led db 6fh,7fh,07h,7dh,6dh,66h,4fh,5bh,06h,3fh
buffer1 db 0,0 ;led显示十位、个位
num dw 0 ;
bz dw ? ;位码
freq dw 262,330,392,392,440,392,330,262,392,392,392,330,262
freq1 dw 200 ; 响音频率
tim dw 400
data ends
SSEG SEGMENT STACK
DW 256 DUP (?)
SSEG ENDS
code segment
assume cs:code,ds:data
begin:
mov ax,data
mov ds,ax
LEA DX,str ;显示版权
MOV AH,9
INT 21H
LEA DX,STR1
MOV AH,9
INT 21H
LEA DX,STR2
MOV AH,9
INT 21H
start:
LEA DX,STR13 ;开始信号
MOV AH,9
INT 21H
mov ah,1
int 21h
cmp al,'y'
je over
;jmp start
mov ah,4ch
int 21h
over: mov dx,d_8255 ;初始化8255
mov al,90h ;A口入,B、C口出
out dx,al
LEA DX,STR4 ;开始信号
MOV AH,9
INT 21H
mov al,0
mov dx,c_8255
out dx,al
; mov al,1
; mov bl,16
; call whowin
; jmp start
mov dx,d_8253 ;CNT0
mov al,36h
out dx,al
mov ax,1000
mov dx,a_8253
out dx,al
mov al,ah
out dx,al
mov dx,d_8253 ;CNT1
mov al,76h
out dx,al
mov ax,1000
mov dx,b_8253
out dx,al
mov al,ah
out dx,al
mov dx,d_8253 ;CNT2
mov al,9Ah ;工作在方式5
out dx,al
call rand1
mov al,bl
;mov al,2
mov dx,c_8253
out dx,al
mov dx,a_8255
a7: in al,dx
and al,80h ;读a7=1?,是否开始?
jz a7 ;未开始不断重读
;jnz start
mov dx,c_8255
out dx,al ;为CNT2口送一个脉冲,延时 (送到GATE2)
mov al,0
mov dx,b_8255 ;将b口清零
out dx,al
call delay
mov dx,a_8255
a6: in al,dx
test al,40h ;读a6=1?,(N是否计满)(方式5 0为满)
ja cm ;未计满不断重读
jz a6
jmp continue ;无,则继续
cm: mov dx,c_8255 ;led输出显示违规者对应led
out dx,al ;屏蔽高四位
LEA DX,STR11 ;电脑显示出错
MOV AH,9
INT 21h
jmp start ;重新开始
continue: call rand2 ;随机子程序(黄40h、红20h、绿10h)
mov al,bl
mov ah,bl
mov dx,c_8255
out dx,al
;jmp start
mov si,0 ;同时十秒倒计时
inout: mov dx,b_8255 ;b口输出
mov al,led[si]
out dx,al
inc si
cmp si,10 ;计满退出
;je ord
je theend
call intdelay ;读按钮状态
cmp dx,1
jne inout ;有人已抢答?
; ord: mov al,1
call whowin ;8*8点阵显示反应时间
call sound1 ;发出声音
jmp start
theend:
LEA DX,STR12
MOV AH,9
INT 21H
call sound1
call wrongshow
jmp start
intdelay proc near ;(读选手按钮状态)
mov cx ,100
intl1: push cx
mov cx,2000 ;2000
intl2: push cx
mov cx,5000 ;5000
intl3: loop intl3
mov dx,a_8255 ;读选手按钮状态
in al,dx
and al,0fh ;有按钮按下吗?
jnz intnext2
pop cx
loop intl2
pop cx
loop intl1
jmp e ;每秒一次
intnext2:
mov dx,c_8255 ;输出选手的选择
or al,bl
out dx,al
pop cx
pop cx
mov bx,100 ;记录反应时间
sub bx,cx ;bx存.00秒
mov cx,10
sub cx,si ;cx存00秒
mov dx,1 ;结束标志
e: ret
intdelay endp
timeshow proc ;8*8点阵显示反应时间
mov si,0
mov di,0
push bx
mov bx,cx
mov cx,4000
next :push cx
mov ax,bx ;00位
mov cl,10
div cl
mov dx,ax ;保存结果
mov al,4 ;个位
mul dh ;选择对应的rowdata[i]
mov cx,dx ;保存十位
push si ;保存SI
add si,ax ;找对应的rowdata[i]
mov dx,row1
mov al,rowdata[si]
out dx,al
pop si
mov dx,col
mov al,coldata[si]
out dx,al
inc si
cmp si,4
je n
call delay2
jmp next
n:
mov al,4 ;十位(将左边的数的位称为十位)
mul cl
push si ;保存SI
add si,ax
mov dx,row1
mov al,rowdata[si-4] ;必须减去4
out dx,al
pop si
mov dx,col
mov al,coldata[si]
out dx,al
inc si
cmp si,8
jne l
mov si,0
call delay2 ;下面显示.00
pop cx
loop next
pop bx
mov cx,4000
next1:push cx
mov ax,bx ;.00位 处理同上
mov cl,10
div cl
mov dx,ax ;保存结果
mov al,4
mul dh
mov cx,ax ;选择
push di ;保存DI
add di,ax ;找
mov dx,row2
mov al,rowdata[di]
out dx,al
pop di
mov dx,col
mov al,coldata[di]
out dx,al
inc di
cmp di,4
jne m1
n1: mov al,4
mul cl
push di
add di,ax
mov dx,row2
mov al,rowdata[di-4]
out dx,al
pop di
mov dx,col
mov al,coldata[di]
out dx,al
inc di
cmp di,8
jne ll
mov di,0
pop cx
loop next1
jmp time
m1: call delay2
jmp next1
ll: call delay2
jmp n1
l: call delay2
jmp n
time: ret
timeshow endp
delay2 proc near ;延时(对应上面的timeshow)
push cx
mov cx,300
q2: push cx
mov cx,3000
q1 : loop q1
pop cx
loop q2
pop cx
ret
delay2 endp
delay proc near ;延时(对应C7输出的延时)
push cx
mov cx,3000
p2: push cx
mov cx,3000
p1 : loop p1
pop cx
loop p2
pop cx
ret
delay endp
io_8253 proc ;初始化8253
mov dx,d_8253 ;CNT0
mov al,36h
out dx,al
mov ax,1000
mov dx,a_8253
out dx,al
mov al,ah
out dx,al
mov dx,d_8253 ;CNT1
mov al,76h
out dx,al
mov ax,1000
mov dx,b_8253
out dx,al
mov al,ah
out dx,al
mov dx,d_8253 ;CNT2
mov al,92h ;工作在方式5
out dx,al
call rand1
mov al,2
mov dx,c_8253
out dx,al
ret
io_8253 endp
rand1 proc ;随机数产生子程序(决定灯亮前时间)
push cx
push dx
push ax
sti
mov ah,0 ;读时钟计数器的值
int 1ah
mov ax,dx ;清高六位
mov ah,3
mov dl,13 ;除13,产生0~12余数
div dl
mov bl,ah
add bl,3
pop ax
pop dx
pop cx
ret
rand1 endp
rand2 proc ;随机数产生子程序(决定灯亮颜色)
push cx
push dx
push ax
sti
mov ah,0 ;读时钟计数器的值
int 1ah
mov ax,dx ;清高六位
mov ah,1
mov dl,3 ;除3,产生0~2余数
div dl
mov bl,ah
test bl,0fh
jnz yellow
mov bl,4
yellow:
mov cl,4
shl bl,cl ;(10h,20h,40h)
pop ax
pop dx
pop cx
ret
rand2 endp
sound1 proc ;响音子程序
mov si,0
again1:mov di,freq1[si]
mov bx,tim
call gen
add si,2
cmp si,2
jnz again1
ret
sound1 endp
sound proc
; mov cx,2
a:mov si,0
again:mov di,freq[si]
mov bx,tim
call gen
add si,2
cmp si,26
jnz again
; loop a
ret
sound endp
gen proc near
push cx
mov al,0b6h
out 43h,al
mov dx,12h
mov ax,12928; DX AX=896*533h=18*65536+12928=1.19M
div di
out 42h,al
mov al,ah
out 42h,al
in al,61h
mov ah,al
or al,3
out 61h,al
wait1:mov cx,0h
gdelay:mov ax,20
gdelay2:nop
nop
dec ax
jnz gdelay2
loop gdelay
dec bx
jnz wait1
mov al,ah
out 61h,al
pop cx
ret
gen endp
whowin proc ;判断谁获得胜利(失败)
;mov bl,ah
and al,0fh
jp ab ;是否同时按下
push cx
cmp al,3
ja b
mov cl,4 ;A先按下,A左移4位
shl al,cl
cmp al,ah ;按对了?
je awin ;A赢
afail: call wrongshow
LEA DX,STR8
MOV AH,9
INT 21H
jmp whoend
awin: call timeshow
LEA DX,STR5
MOV AH,9
INT 21H
jmp whoend
b: mov cl,2 ;B先按下,B左移2位
shl al,cl
cmp al,ah ;按对了?
je bwin
bfail: call wrongshow
LEA DX,STR9
MOV AH,9
INT 21H
jmp whoend
bwin: call timeshow
LEA DX,STR6
MOV AH,9
INT 21H
jmp whoend
ab: test al,00001010b ;A,B选择相同?
jp absame
and al,03h
mov cl,4
shl al,cl
cmp al,ah
je awin ;A win
jmp bwin ;B win
absame: and al,03h
mov cl,4
shl al,cl
cmp al,ah
je abwin
abfail: call wrongshow
LEA DX,STR10
MOV AH,9
INT 21H
jmp whoend
abwin: call timeshow
LEA DX,STR7
MOV AH,9
INT 21H
whoend: pop cx
ret
whowin endp
wrongshow proc near
mov si,0
mov cx,4000
wrnext :
mov dx,row1
mov al,rowwrong[si]
out dx,al
mov dx,col
mov al,coldata[si]
out dx,al
inc si
cmp si,8
jne wrm
mov si,0
wrm: call delay2
loop wrnext
ret
wrongshow endp
code ends
end begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -