⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 200.asm

📁 用8051实现的PS2协议的PC键盘
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	JNC TOH6            ; if data bit output is high
	JNB DataIn,ToHAbort ; and data in is low, host is ready to send
TOH6:
        CLR ClockOut        ; else, clock line low
	CALL Clock40        ; delay a full clock cycle
	SETB ClockOut
	CALL Clock20
	JNB ClkIn,ToHAbort  ; if clock stays low, host busy, abort TX
	DJNZ TxCtr,SendLp   ; decrement bit count, loop again if not done

	SETB DataOut        ; send stop bit, data high
	CALL Clock20        ; delay half clock cycle
	JNB DataIn,ToHAbort ; check for host wanting to send
	CLR ClockOut        ; clock out stop bit
	CALL Clock40
	SETB ClockOut
	SETB DataOut
	CLR C               ; flag byte as sent (carry clear)
	CALL Clock40        ; delay for lines to go high
TOH7:
        SETB EA             ; restart interrupts
	JC TOH8             ; if send was successful
	MOV A,TEMP          ; and byte sent
	XRL A,#0FEH         ; not a RESEND command
	JZ TOH8             ; then save data byte as last one sent to host
	MOV LastSent,TEMP
TOH8:
        JNB RESPONDING,TOH9 ; if this was a command response
	MOV A,TEMP          ; retrieve data we tried to send before
	CLR RESPONDING      ; clear the command response flag
	RET                 ; and return with carry set (send aborted)
TOH9:
        JNC TOH10           ; if byte was not sent successfully
	MOV A,TEMP          ; retrieve byte we tried to send
	MOV RESEND_BYTE,A   ; and save to be resent
	JMP FromHost?       ; then try to receive data from host
TOH10:
        CLR UpLoading       ; else, GOOD TRANSMISSION, clear upload flag
	RET
ToHAbort:                   ; transmission aborted.
	SETB DataOut        ; send data line high,
	SETB C              ; set flag to indicate TX was aborted
	JMP TOH7            ; and try to RESEND or receive
;(6,7)**************************
Clock40: ;>> full clock cycle delay, 40 usec-background
	NOP  ; 1-   27+23+4 machine cycles x 0.75 usec = 40 usec
	NOP  ; 2    2 machine cycles for CALL, 2 for RET
	NOP  ; 3
	NOP  ; 4
	NOP  ; 5
	NOP  ; 6
       	NOP  ; 7  
	NOP  ; 8
	NOP  ; 9
 	NOP  ; 10 
	NOP  ; 11
	NOP  ; 12
	NOP  ; 13
	NOP  ; 14
	NOP  ; 15
	NOP  ; 16
	NOP  ; 17
	NOP  ; 18
	NOP  ; 19
	NOP  ; 20
	NOP  ; 21
	NOP  ; 22
	NOP  ; 23
	NOP  ; 24
	NOP  ; 25
	NOP  ; 26
	NOP  ; 27
Clock20: ; half clock cycle delay, 20 usec
	NOP  ; 1-  23+4 machine cycles x 0.75usec = 20usec
	NOP  ; 2
	NOP  ; 3
	NOP  ; 4
	NOP  ; 5 
	NOP  ; 6
	NOP  ; 7
	NOP  ; 8
	NOP  ; 9      
	NOP  ; 10
	NOP  ; 11
	NOP  ; 12
	NOP  ; 13
	NOP  ; 14
	NOP  ; 15
	NOP  ; 16
	NOP  ; 17
	NOP  ; 18
	NOP  ; 19
	NOP  ; 20
	NOP  ; 21
	NOP  ; 22
	NOP  ; 23
	RET
;****************************************
;(8)   Receive Data from Host Routine
;****************************************
RecvIt: ; background 
        MOV RptCtr,#127        ; keep timer watchdog happy
	JNB ClkIn,RecvIt       ; prevents hang
	JB DataIn,RecvIt
	CALL RcvDat
	JNB BadParity,RECV2    ; if parity okay, exit
        MOV A,#0FEH            ; else, do resend command
	CALL SendResponse
	JMP RecvIt             ; and get response
; Receive from the AT
RcvDat:
        SETB Cmd2ndByte
	JMP REC1
RXEXIT:
	JNB UpLoading,RECV2    ; if we were not sending before, just exit
	JMP RESEND             ; else, go try to RESEND last byte
RECV2:
        RET
FromHost?: ; background
	CLR ReceivingCommand   ; let timer0 allow scanning 			
	JB DataIn,RXEXIT       ; to Receive, clock must be high, data low	
	JNB ClkIn,RXEXIT       ; if clock is low, AT is busy, exit		
	JB DataIn,RXEXIT       ; if data is high, exit
	CLR Cmd2ndByte         ; else, o.k. to receive				
REC1:
        SETB ReceivingCommand  ; show timer0 we are receiving			
	CLR EA                 ; stop interrupts while we receive
	MOV TxCtr,#8           ; set up receive counter
	MOV TEMP,#0            ; initial receive registers
	CLR C
REC2:										
        CLR ClockOut           ; the high to low clock sets up for		
	CALL Clock40           ; next bit in transmission
	SETB ClockOut          ; bit ready					
	MOV C,DataIn           ; read bit on low to high clock transition
	MOV A,TEMP             ; retrieve data received so far
	RRC A                  ; and rotate this bit into it
	MOV TEMP,A             ; then save it for the next			
	CALL Clock20
	DJNZ TxCtr,REC2        ; loop until all 8 bits of data read
; Data received, clock in and check parity
	CLR ClockOut
	CALL Clock40           ; clock in parity
	SETB ClockOut
	MOV C,DataIn           ; get odd parity					
	CALL Clock40           ; and save in carry bit
	CLR ClockOut           ; and clock in stop bit
	CALL Clock40
	SETB ClockOut
	CALL Clock40           ; clock out acknowledge
	CLR DataOut            ; send data line low
	CALL Clock40
	CLR ClockOut           ; send clock line low
	CALL Clock40
	SETB ClockOut          ; data low, clock high
	SETB DataOut           ; data and clock high
	MOV A,TEMP             ; get data we received
	CLR BadParity          ; assume parity is okay
	JC REC3                ; and check it's parity
	JB P,REC5              ; If received parity (odd) is clear
	SETB BadParity         ; and internal parity (even) clear, parity bad
	JMP REC5
REC3:
        JNB P,REC5             ; else if received parity (odd) is set
	SETB BadParity ; and internal parity (even) is set parity is bad
REC5:
        SETB EA                ; allow interrupts again
	JNB Cmd2ndByte,RCVCMD							
	CLR Cmd2ndByte         ; return with the data in acc
	RET
RCVCMD:
        JNB BadParity,AT_COMMAND ; else, if stop or parity bad,
	MOV A,#0FEH            ; request a RESEND of the data
	JMP SendOut            ; else, decode command
;*******************************************
;       Host Command Processing Routine
;*******************************************
; DESCRIPTION
; when a command is received from the host, it must be checked for
; correct value. It is then acted upon depending on the nature of the
; command. These routines perform that function.
;*******************************************
AT_COMMAND: ; background
	CLR C                  ; command received from the AT
	SUBB A,#0EDH           ; check it's value				
	JNC AtMs3              ; if command < 0EDH (makes an offset, too),
	MOV A,#0FEH            ; bad command, send re-transmit command
	JMP SendOut
AtMs3:
        XCH A,TEMP             ; if command is RESEND				
	CJNE A,#0FEH,AtMs4
	MOV A,LastSent         ; get last data sent out to host
	JMP SendOut            ; and RESEND it
AtMs4:
        CJNE A,#0EEH,AtMs5     ; if command is ECHO				
        MOV A,#0EEH
	JMP SendOut            ; send ECHO (0EEH) to host
AtMs5:
        XCH A,TEMP             ; retrieve offset value computed above
	PUSH ACC               ; and save it on the stack
	CALL ACK               ; send the ACK response to the command		
	POP ACC                ; get the offset back off the stack
	JNC AtMs6              ; if ACK transmission not successful
	JMP FromHost?          ; try to receive again
; decode host command
AtMs6:										
        PUSH DPH               ; else, find command processing routine
	PUSH DPL
	MOV DPTR,#CmdTable     ; get jump table base address
	MOV R0,A               ; table has 3 bytes for each command
	RL A                   ; so offset must be multiplied by 3
	ADD A,R0               ; to get correct instruction
	JMP @A+DPTR            ; jump to the proper jump instruction
CmdTable:
	JMP SetLed             ; ED - STATUS					
	JMP NOOP               ; EE - ECHO 					
	JMP NOOP               ; EF - NO OPERATION
	JMP NOOP               ; F0 - NO OPERATION
	JMP NOOP               ; F1 - NO OPERATION
	JMP IdOut              ; F2 - ABH,83H					
	JMP SetRpt             ; F3 - TYPEMATIC					
	JMP SetScan            ; F4 - ENABLE SCANNING
	JMP SetOff             ; F5 - DISABLE SCANNING
	JMP SetDefa            ; F6 - DEFAULT
	JMP NOOP               ; F7 - NO OPERATION
	JMP NOOP               ; F8 - NO OPERATION
	JMP NOOP               ; F9 - NO OPERATION
	JMP NOOP               ; FA - NO OPERATION
	JMP NOOP               ; FB - NO OPERATION
	JMP NOOP               ; FC - NO OPERATION
	JMP NOOP               ; FD - NO OPERATION
	JMP NOOP               ; FE - RESEND LAST BYTE 				
	JMP DoReset            ; FF - RESET					
NOOP:
        POP DPL
        POP DPH
	JMP FromHost?
; SetLed makes the LEDs for Caps, Num, and Scroll lock match
; the host. None are displayed in this example.
SetLed:	
	POP DPL
	POP DPH
;sea	CALL RecvIt            ; get next byte containing the LED		
;sea	CLR C                  ; state status
;sea	SUBB A,#0ECH           ; if this byte is
;sea	MOV A,TEMP             ; a command
;sea	JC SETL1
	JMP AT_COMMAND         ; process command
;SETL1:
;       CPL A                  ; else set the keyboard LED status
;	MOV C,ACC.0
;	MOV SCROLL_LOCK,C      ; scroll lock bit
;	MOV C,ACC.1
;	MOV NUM_LOCK,C         ; num lock bit
;	MOV C,ACC.2
;	MOV CAPS_LOCK,C        ; caps lock bit
;SETL0:
;       MOV A,#0FAH            ; send the ACK command response			
;	JMP SendOut            ; to show we processed the data byte
; Send ID code (Not an original IBM requirement)
IdOut:										
        POP DPL
	POP DPH
ID0:
        MOV A,#0ABH            ; send ID code (ABH)
	CALL SendResponse
        CLR HostReset
        ORL P1,#0EFH ;>>				
        CLR REPEATING
	JNC ID1
	SETB ClockOut          ; software watch
	SETB DataOut
	SETB ClkIn
	SETB DataIn
	JNB ClkIn,ID0          ; if host was busy, try to send again
	JB DataIn,ID0          ; if host wants to send, go receive
	JMP FromHost?
ID1:
        MOV A,#83H             ; send 83H code
	JMP SendOut
; SetRpt sets the keyboard repeat delay and repeat rate.
SetRpt:
	POP DPL
        POP DPH
	CLR REPEATING
	MOV LastDown,#0FFH
SETRP0:
        CALL RecvIt            ; receive the second byte of the command
	JB ACC.7,SETRP5        ; if most significant bit set, go see if another
	PUSH ACC               ; command
	CALL ACK               ; save data and send out the acknowledge
        POP ACC
	JNC SETRP1             ; if acknowledge not successful, go see if
	JMP FromHost?          ; host wanted to send
SETRP1:
        MOV TEMP,A             ; save the data
	ANL A,#01100000B       ; get the delay bits
        SWAP A
	RR A                   ; shift the bits into the 0-1 position
	INC A                  ; add one
        MOV B,#25              ; compute the delay
        MUL AB                 ; Delay * 25
	MOV RepeatDelay,A      ; and save it (SHOULD BE 25, 50, 75 OR 100)
	MOV A,TEMP             ; get the raw data again
	ANL A,#00000111B       ; single out the A bits
	ADD A,#8               ; A+8 (should be 8 - 15)
	MOV B,A
	MOV A,TEMP
	ANL A,#00011000B       ; single out the B bits
        RL A
	SWAP A                 ; shift B into bits 1,0
	INC A                  ; adjust for exponentiation
        MOV R0,A
        CLR A
        SETB C
SETRP2:
        RLC A

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -