📄 200.asm
字号:
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 + -