Function implementation is a whack-a-mole game
Principle of output is about 8255 a mouth as LED lights, as switch input port B, C as digital tube display
10 to 50 hz interrupt for a cycle, each interrupt to judge whether the switch change, if change compared with leds, consistent and scoring,
Ten Chinese break into the next cycle, lights up a light bulb,
Where don't understand:
1. Code snippet SET_NMI_INT, seems to be 8259 interrupt, but did not use 8259 chip, the test can't delete the code according to the logic operation,
2. The code segment UPDATE_LED, refresh the LED logic is he here?
DATA SEGMENT
I8253_1 EQU 0288 h
I8253_2 EQU 028 ah
I8253_MODE EQU 028 eh
I8255_A EQU 0280 h
I8255_B EQU 0282 h
I7SEG_1 EQU 0284 h
I8255_MODE EQU 0286 h
3 fh SYMBOL_7SEG DB, 6 h, 5 bh, 4 fh, 66 h, 6 dh, 7 dh, 7 h, 7 fh, 6 fh
Who leads the DB 0
RANDOM_NUMBER DB?
LED the DB 1
SWITCH the DB?
INT_TIMES DB 1
The DATA ENDS
Sports a SEGMENT STACK
1024 DB DUP (0)
Sports a ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA, SS: sports a
START:
MOV AX, DATA
MOV DS, AX
MOV AX, sports a
MOV SS, AX
MOV DX, I8255_MODE; Initialize the 8255 works
MOV AL, 82 h
The OUT DX, AL
MOV DX, I8255_A; A output
MOV AL, 0
The OUT DX, AL
MOV [RANDOM_NUMBER], 47
MOV DX, I8255_B; B enter
IN AL, DX
MOV [SWITCH], AL
CALL SET_NMI_INT
CALL PRINT_SCORE
CALL SET_TIMER
@ WAIT:
JMP @ WAIT
SET_TIMER PROC NEAR
MOV DX, I8253_MODE; Initialize the 8254 works
MOV AL, 00100101 b
The OUT DX, AL
MOV DX, I8253_1
MOV AL, 01 h
The OUT DX, AL
MOV DX, I8253_MODE
MOV AL, 01100101 b
The OUT DX, AL
MOV DX, I8253_2
MOV AL, 10 h
The OUT DX, AL
RET
SET_TIMER ENDP
SET_NMI_INT PROC NEAR
PUSH the DS
MOV AX, CS
MOV DS, AX
MOV DX, OFFSET NMI_HANDLER; Using indirect modification method, set the interrupt vector
MOV AX, 250 bh. Setting the corresponding interrupt vector
INT 21 h
IN AL, 21 h. Read the interrupt mask register, register 21 h is the port number
AND AL, 0 f7h; Interruption of open, allowing the interrupt application
OUT of 21 h, AL
STI
POP the DS
RET
SET_NMI_INT ENDP
UPDATE_LED PROC NEAR
XOR AX, AX
MOV AL, [RANDOM_NUMBER]
PUSH AX
MOV DL, 8
DIV DL
MOV CL, AH
MOV BL, 1
SHL BL, CL
MOV [LED], BL
POP AX
MOV DL, 23
The MUL DL
MOV DL, 97
DIV DL
MOV [RANDOM_NUMBER], AH
MOV DX, I8255_A
MOV AL, BL
The OUT DX, AL
RET
UPDATE_LED ENDP
ADD_SCORE PROC NEAR; Scoring program
MOV AL, [who]
INC AL; If the score score + 1
CMP AL, 10
JNZ @ ADD_SCORE_NEXT; Digital tube is not equal to 10 jump, otherwise jump back to 0
MOV AL, 0
@ ADD_SCORE_NEXT:
MOV [who], AL; Update the results after scoring
RET
ADD_SCORE ENDP
PRINT_SCORE PROC NEAR; Digital tube scores show
MOV DL, [who]
MOV DH, 0
MOV DI, OFFSET SYMBOL_7SEG
The ADD DI, DX
MOV DX, I7SEG_1
MOV AL, BYTE PTR (DI)
The OUT DX, AL
RET
PRINT_SCORE ENDP
UPDATE the PROC NEAR; Update
DEC [INT_TIMES]; Remaining flush time - 1
JNZ @ UPDATE_ELSE; Not to 0 jump determine whether score
MOV [INT_TIMES], 10; Accumulated in a side to enter the next lights
CALL UPDATE_LED
@ UPDATE_ELSE:
MOV DX, I8255_B; Switch input
IN AL, DX
MOV CH, [SWITCH]; The light bulb output
MOV [SWITCH], AL
XOR AL, CH. Switch between two interrupt have change
XOR AL [LED]; Change the switch to light up the light bulb is uniform
JNZ @ UPDATE_NO_SCORE; Switch didn't change or isn't score
CALL ADD_SCORE; Otherwise the score
CALL PRINT_SCORE
@ UPDATE_NO_SCORE:
RET
The UPDATE ENDP
NMI_HANDLER:
MOV AX, DATA
MOV DS, AX
MOV AX, sports a
MOV SS, AX
CALL the UPDATE
MOV AL, 20 h; A EOI end interrupts to address of the PC NaZhu piece of 20 h
OUT of 20 h, AL
IRET
CODE ENDS
The END START
CodePudding user response:
SET_NMI_INT should be called DOS modify the keyboard interrupt vectorUPDATE_LED should be calculated by a random number control led lights?