📄 200.asm
字号:
RET
; 1.check validity of R1
; 2.key debounce
; 3.matrix image update
; 4.combine (key offset) & (F0: key pushed or released)->pushed into FIFO
ValidityTest:
MOV CHANGES,A ; save XOR result
MOV A,TL0 ; additional software watchdog tests
NOP ; make sure timer is still running
NOP ; delay to allow timer to increment
XRL A,TL0 ; see if timer value changed
JZ InitVect ; no change abort
MOV A,R1 ; now check range of image pointer
ADD A,#-(ImgHigh+1) ; CY=1 if A>ImgHigh
JC InitVect ; reboot if R1>ImgHigh
MOV A,R1
ADD A,#-ImgLow ; CY=1 if A>=ImgLow
JC ValidImage ; reboot if R1<ImgLow
InitVect:
SETB WarmStart
CLR DoAAH
JMP MAIN
ValidImage:
MOV R0,#90 ; delay before validity check
DJNZ R0,$
PUSH DPH
PUSH DPL
PUSH ACC
MOV DPTR,#Xmem
MOV A,#0FFH
MOVX @DPTR,A
POP ACC
POP DPL
POP DPH
CALL ScanColumn ; test the current col. again
ANL A,CHANGES ; compare old changes with new
JNZ NewKeys ; if nothing changed,
JMP NextColumn ; go test next col
NewKeys:
MOV CHANGES,A ; else, save the valid changes
MOV ChgMask,#1 ; set up a mask for testing keys that changed
MOV A,R1 ; calculate key offset
ADD A,#-(ImgLow) ; based on column# in image
SWAP A ; column# = R1 - ImgLow
RR A ; offset row0 key of column = column# * 8
MOV KEY_OFFSET,A ; low 3 bits will later become row number
MOV A,ChgMask ; get key change mask
TstKeys:
ANL A,CHANGES ; if key in this row changed
JNZ KeyChg ; go process
TestMore:
MOV A,CHANGES ; else, test if no more changed
JZ NextColumn ; go scan next col
MOV A,ChgMask ; else, rotate mask and try next row
CLR C
RLC A
MOV ChgMask,A
JNC DoMore ; if last row in col
JMP NextColumn ; go try next column
DoMore: ; above code is designed for 8 keys per column
INC KEY_OFFSET ; else, adjust offset for next row
JMP TstKeys ; do all 8 rows
KeyChg: ; mask has identified a changed key
JNB FifoFul,KEYC ; if the fifo is full, quit the scan
JMP ScanDone
KEYC:
MOV A,ChgMask ; else
CPL A
ANL A,CHANGES
MOV CHANGES,A ; clear out the detected bit in CHANGES
MOV A,ChgMask
ANL A,@R1 ; find out if key was up or down before
JNZ KeyUp1 ; if key was up, then it went down
KeyDown:
MOV A,ChgMask ; process the down key
ORL A,@R1 ; make the image RAM status for this key
MOV @R1,A ; match the current state
SETB DelayFlag ; flag timer0 that a key went on the Delay_Que
INC DebncPtr ; push the key offset value onto the delay que
MOV A,DebncPtr ; test pointer for overflow
ADD A,#-(DebncTop+1) ; CY=1 if A>DebncTop
JNC DebncOk ; if overflow
MOV DebncPtr,#DebncBot ; set to bottom of que
DebncOk:
MOV R0,DebncPtr ; put pointer in index
MOV @R0,KEY_OFFSET ; store the key offset in the que
MOV A,KEY_OFFSET ; now push the key offset onto the FIFO
CLR F0 ; flag as a down code
CALL PushKey ; call the push routine
SETB P1.4;>> buzzer on for 50msec
MOV BuzzerCounter,#50
JMP TestMore ; then go back and test some more keys
KeyUp1:
MOV R0,#DebncBot ; if the key is in the que
STKTST:
MOV A,KEY_OFFSET ; don't let it go up yet
XRL A,@R0 ; search the que
JZ TestMore ; if found in que, go test more
INC R0 ; inc and test R0
MOV A,R0
ADD A,#-(DebncTop+1) ; C=1 if ACC > DebncTop
JNC STKTST ; loop until R0 > DebncTop
; key not found in delay que, okay to send up
MOV A,ChgMask ; clear the key's bit in image RAM
XRL A,@R1
MOV @R1,A
MOV A,KEY_OFFSET ; then push the key offset value
SETB F0 ; marked as an up code
CALL PushKey ; onto the FIFO
JMP TestMore
;*****************************
;(2) Push Key onto FIFO
;*****************************
; background
PushKey:
MOV R0,A ; save byte-key offset
MOV A,HeadPntr
JB FifoFul,POK ; if fifo full, dump byte
ADD A,#-(BufrLow-1)
ANL A,#KeyMask ; 7
ADD A,#BufrLow ; inc and adjust headpntr
XCH A,R0
MOV C,F0 ; put up/down flag in msbit of offset
MOV ACC.7,C
MOV @R0,A ; store byte in FIFO
MOV A,R0
CJNE A,TailPntr,POK ; is FIFO full
ORL A,#80H ; set full flag
POK:
MOV HeadPntr,A
RET
;******************************
;(3) Keycode Buffer Pop
;******************************
PopKey:
MOV A,TailPntr ; compare tail pointer with head
CJNE A,HeadPntr,NotEmpty ; to see if FIFO is empty
SETB C ; if empty, set carry bit and exit
RET
NotEmpty:
ADD A,#-(BufrLow-1) ; else
ANL A,#KeyMask ; force tail pointer to be in
ADD A,#BufrLow ; range (software watch), then increment
MOV R0,A ; and store value in R0
MOV A,@R0 ; retrieve key-offset from FIFO
MOV C,ACC.7 ; retrieve Up/Down flag from the msb
MOV F0,C ; of data, and store in flag 0
CLR ACC.7 ; clear flag out of data
MOV TailPntr,R0 ; save new tail pointer
CLR FifoFul ; clear FIFO full flag, if it was set
CLR C ; clear carry to show pop was successful
RET
;******************************************
;>>(4) Process Key Information Routine
;******************************************
DecodeKey_SendToHost:
JB KbIsAble,DoIt
JMP TestDone
; get key offset
DoIt:
;------------sea-----------
; JNB shift_ok,sea80
; CLR shift_ok
; MOV A,#64
; JMP SUCCESS
;sea80:
;------------sea----------
CALL PopKey ; pop key offset from FIFO
JNC SUCCESS ; c = 0 means PopKey was successful
JMP TestRepeating ; if FIFO is empty, go test for repeating key
SUCCESS:
; check key offset for "shift" key and set led
CJNE A,#ShiftKeyOffset,NotShiftKey ; 33
;sea01:
JB F0,ShiftUp_DoNothing
CPL P1.0
CPL ShiftPushed
ShiftUp_DoNothing:
JMP TestDone
; now we want DPTR to point to key code in table. there are 2 bytes per key
; in the key scan code table, so offset must be multiplied by 2 to get the no.
; of bytes from start of table.this is then added to the table base address.
NotShiftKey:
MOV R1,A ; save the offset for later use
MOV B,#TableCol ; 2 - number of bytes per key in table
MUL AB
JNB ShiftPushed,NonShft1
ADD A,#LOW (ShiftKeyBase) ; if shift key depressed
JMP NonShft2
NonShft1:
ADD A,#LOW (KeyBase) ; if shift key not depressed
NonShft2:
MOV DPL,A
MOV A,B
JNB ShiftPushed,NonShft3
ADDC A,#HIGH (ShiftKeyBase) ; add carry into high byte of address
CLR ShiftPushed
SETB P1.0
JMP NonShft4
NonShft3:
ADDC A,#HIGH (KeyBase)
NonShft4:
MOV DPH,A ; DPTR = Base + 2(key offset)
; if key code is 0 e.g. DEAD POSITION exit
CLR A
MOVC A,@A+DPTR ; get key scan code from the table
MOV R7,A ; save key code temporarily
JNZ SendPrefixes
JMP DecodeRet
; else send prefixes first depending on key (low,high,special)
SendPrefixes:
MOV A,#BitByteOffset ; 1
MOVC A,@A+DPTR ; read bit byte for this key
JNB ACC.0,SpecialOrHigh
MOV A,#0F0H
CALL ToHost
MOV A,#59H ; right shift key is up(low)
CALL ToHost
JMP WentUpOrDown?
SpecialOrHigh:
JB ACC.5,SPECIAL
MOV A,#59H ; right shift key is down(high)
CALL ToHost
JMP WentUpOrDown?
SPECIAL: ; cursors,insert,home,page up/dn,delete,end
MOV A,#0E0H ; cursor keys on the AT send this code first
CALL ToHost ; so that keys are not affected by numlock
WentUpOrDown?:
JNB F0,JustKeyCode
MOV A,#0F0H ; up code
CALL ToHost ; send it
JustKeyCode:
MOV A,R7 ; key code
CALL ToHost ; send key scan code
; check autoRepeating now
MOV A,LastDown ; see if this key should be autorepeating
XRL A,R1 ; compare this to last key down offset
JB F0,KEYUP ; if key gone down and LastDown != new key
JZ DecodeRet ; then repeat this key
MOV LastDown,R1 ; load matrix offset as last key down
MOV RptCtr,RepeatDelay ; load repeat delay into counter
SETB REPEATING ; and start autorepeating
JMP DecodeRet ; timer0 int. controls repeat delay and rate
KEYUP:
JNZ DecodeRet
CLR REPEATING ; if LastDown == R1 and gone up stop repeating
MOV LastDown,#0FFH
JMP DecodeRet
TestRepeating:
; add here to prevent send last byte while host is initializing
JB HostReset,TestDone
JNB REPEATING,TestDone ; if a key is repeating
MOV A,RptCtr ; get repeat count
JNB ACC.7,DecodeRet ; test for delay complete
ADD A,RepeatRate ; if delay complete
MOV RptCtr,A ; reload with repeat rate
MOV A,LastDown ; and send host the down code again
CLR F0 ; with down flag
JMP SUCCESS ; go send repeating key
TestDone:
MOV RptCtr,RepeatDelay ; if not repeating, keep RptCtr near 0
DecodeRet:
RET
;**********************************
;(5) Upload to Host Routine
;**********************************
; send the command response byte in the acc
SendResponse:
MOV RptCtr,RepeatDelay
SETB RESPONDING ; sending a command response
JMP TOH1
; resend the data byte in the acc
; used after transmission was interrupted by a command request
RESEND:
MOV A,RptCtr ; adjust repeat counter
JNB ACC.7,RES1 ; if necessary
MOV RptCtr,#5
RES1:
MOV A,RESEND_BYTE ; get byte back and try to send it again
ToHost: ; synchronous data transfer to host
CLR RESPONDING ; show this is not a command response
SETB UpLoading ; show us sending to the host
; all send entry points end up here
TOH1:
CLR EA ; disable interrupts during this routine
MOV C,P ; get parity of byte from PSW bit P
CPL C ; convert 8051 even parity to odd for host
MOV R0,A ; save data
MOV TEMP,A ; preserve it for later
MOV TxCtr,#9 ; initial transmit bit counter
MOV A,#40 ; set up loop counter
TOH2:
SETB ClkIn ; assure transmit and receive
SETB DataIn ; clock and data bits are in proper
SETB DataOut ; drive and receive sense
SETB ClockOut ; software watch
JB DataIn,TOH4 ; jump out if host wants to send
TOH3:
JMP ToHAbort
TOH4:
JB ClkIn,TOH5 ; wait 40 loops for host to get unbusy
DJNZ ACC,TOH2
JMP ToHAbort ; if still busy, abort send
TOH5:
CLR DataOut ; set data line low for start bit
CALL Clock20 ; delay for lines to settle (half clock cycle)
CLR ClockOut ; set clock line low
CALL Clock40 ; delay for one clock period
SETB ClockOut ; set clock high
CALL Clock20
JNB ClkIn,ToHAbort ; if clock stays low, host busy, abort TX
SendLp:
MOV A,R0 ; get data byte we are transmitting
RRC A ; rotate current bit to transmit into carry
MOV R0,A ; save remainder and parity (that was in carry)
MOV DataOut,C ; move carry bit value to data output bit
CALL Clock20 ; then delay a half clock cycle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -