recipes/rc2014/ps2: implement scan code buffer
This commit is contained in:
parent
20a7ad231f
commit
3cdb25bfda
@ -33,9 +33,10 @@
|
|||||||
|
|
||||||
; *** Buffering scan codes ***
|
; *** Buffering scan codes ***
|
||||||
;
|
;
|
||||||
; The whole SRAM (from SRAM_START to RAMEND) is used as a scan code buffer, with
|
; The buffer starts at SRAM and stops at 0x100. It leaves space for the stack
|
||||||
; Z chasing Y. When Y == Z, the buffer is empty. When RAMEND is reached, we go
|
; and makes overflow check easy. Also, we don't need a very big buffer. In this
|
||||||
; back to SRAM_START.
|
; address space, Z chasing Y. When Y == Z, the buffer is empty. When 0x100 is
|
||||||
|
; reached, we go back to SRAM_START.
|
||||||
;
|
;
|
||||||
; Whenever a new scan code is received, we place it in Y and increase it.
|
; Whenever a new scan code is received, we place it in Y and increase it.
|
||||||
; Whenever we send a scan code to the 595 (which can't be done when Z == Y
|
; Whenever we send a scan code to the 595 (which can't be done when Z == Y
|
||||||
@ -59,7 +60,6 @@
|
|||||||
|
|
||||||
; *** Register Usage ***
|
; *** Register Usage ***
|
||||||
;
|
;
|
||||||
; R1: when set, indicates that value in R17 is valid
|
|
||||||
; R2: When set, indicate that the 595 holds a value that hasn't been read by the
|
; R2: When set, indicate that the 595 holds a value that hasn't been read by the
|
||||||
; z80 yet.
|
; z80 yet.
|
||||||
; R16: tmp stuff
|
; R16: tmp stuff
|
||||||
@ -75,7 +75,7 @@
|
|||||||
; R20: data being sent to the 595
|
; R20: data being sent to the 595
|
||||||
; Y: pointer to the memory location where the next scan code from ps/2 will be
|
; Y: pointer to the memory location where the next scan code from ps/2 will be
|
||||||
; written.
|
; written.
|
||||||
; Z: pointer to last scan code pushed to the 595
|
; Z: pointer to the next scan code to push to the 595
|
||||||
;
|
;
|
||||||
; *** Constants ***
|
; *** Constants ***
|
||||||
;
|
;
|
||||||
@ -104,6 +104,7 @@ hdlPCINT:
|
|||||||
sbi PORTB, RCLK
|
sbi PORTB, RCLK
|
||||||
cbi PORTB, RCLK
|
cbi PORTB, RCLK
|
||||||
clr r2 ; 595 is now free
|
clr r2 ; 595 is now free
|
||||||
|
reti
|
||||||
|
|
||||||
main:
|
main:
|
||||||
ldi r16, low(RAMEND)
|
ldi r16, low(RAMEND)
|
||||||
@ -119,7 +120,6 @@ main:
|
|||||||
|
|
||||||
|
|
||||||
; init variables
|
; init variables
|
||||||
clr r1
|
|
||||||
clr r2
|
clr r2
|
||||||
clr r19
|
clr r19
|
||||||
clr r18
|
clr r18
|
||||||
@ -135,6 +135,12 @@ main:
|
|||||||
ldi r16, (1<<PCINT4)
|
ldi r16, (1<<PCINT4)
|
||||||
out PCMSK, r16
|
out PCMSK, r16
|
||||||
|
|
||||||
|
; Setup buffer
|
||||||
|
clr YH
|
||||||
|
ldi YL, low(SRAM_START)
|
||||||
|
clr ZH
|
||||||
|
ldi ZL, low(SRAM_START)
|
||||||
|
|
||||||
; init DDRB
|
; init DDRB
|
||||||
sbi DDRB, SRCLK
|
sbi DDRB, SRCLK
|
||||||
cbi PORTB, RCLK ; RCLK is generally kept low
|
cbi PORTB, RCLK ; RCLK is generally kept low
|
||||||
@ -144,8 +150,8 @@ main:
|
|||||||
|
|
||||||
loop:
|
loop:
|
||||||
brts processbit ; flag T set? we have a bit to process
|
brts processbit ; flag T set? we have a bit to process
|
||||||
tst r1
|
cp YL, ZL ; if YL == ZL, buffer is empty
|
||||||
brne sendTo595 ; r1 is non-zero? char is ready to send
|
brne sendTo595 ; YL != ZL? our buffer has data
|
||||||
rjmp loop
|
rjmp loop
|
||||||
|
|
||||||
; Process the data bit received in INT0 handler.
|
; Process the data bit received in INT0 handler.
|
||||||
@ -165,8 +171,10 @@ processbit:
|
|||||||
clr r18 ; happens in all cases
|
clr r18 ; happens in all cases
|
||||||
; DATA has to be set
|
; DATA has to be set
|
||||||
tst r16 ; Was DATA set?
|
tst r16 ; Was DATA set?
|
||||||
breq loop ; not set? error, don't inc R1
|
breq loop ; not set? error, don't push to buffer
|
||||||
inc r1 ; indicate that value in r17 is good
|
; push r17 to the buffer
|
||||||
|
st Y+, r17
|
||||||
|
rcall checkBoundsY
|
||||||
rjmp loop
|
rjmp loop
|
||||||
processbits0:
|
processbits0:
|
||||||
; step 0 - start bit
|
; step 0 - start bit
|
||||||
@ -177,7 +185,6 @@ processbits0:
|
|||||||
; DATA is cleared. prepare r17 and r18 for step 1
|
; DATA is cleared. prepare r17 and r18 for step 1
|
||||||
inc r18
|
inc r18
|
||||||
ldi r17, 0x80
|
ldi r17, 0x80
|
||||||
clr r1
|
|
||||||
rjmp loop
|
rjmp loop
|
||||||
|
|
||||||
processbits1:
|
processbits1:
|
||||||
@ -201,20 +208,18 @@ processbits2:
|
|||||||
inc r18
|
inc r18
|
||||||
rjmp loop
|
rjmp loop
|
||||||
|
|
||||||
; send R17 to 595, MSB.
|
; send next scan code in buffer to 595, MSB.
|
||||||
sendTo595:
|
sendTo595:
|
||||||
tst r2
|
tst r2
|
||||||
brne loop ; non-zero? 595 is "busy". Don't send.
|
brne loop ; non-zero? 595 is "busy". Don't send.
|
||||||
; TODO: implement buffering. At this moment, the
|
|
||||||
; scan code is lost.
|
|
||||||
; We disable any interrupt handling during this routine. Whatever it
|
; We disable any interrupt handling during this routine. Whatever it
|
||||||
; is, it has no meaning to us at this point in time and processing it
|
; is, it has no meaning to us at this point in time and processing it
|
||||||
; might mess things up.
|
; might mess things up.
|
||||||
cli
|
cli
|
||||||
sbi DDRB, DATA
|
sbi DDRB, DATA
|
||||||
|
|
||||||
mov r20, r17
|
ld r20, Z+
|
||||||
clr r1
|
rcall checkBoundsZ
|
||||||
ldi r16, 8
|
ldi r16, 8
|
||||||
|
|
||||||
sendTo595Loop:
|
sendTo595Loop:
|
||||||
@ -239,3 +244,23 @@ sendTo595Loop:
|
|||||||
inc r2
|
inc r2
|
||||||
sei
|
sei
|
||||||
rjmp loop
|
rjmp loop
|
||||||
|
|
||||||
|
; Check that Y is within bounds, reset to SRAM_START if not.
|
||||||
|
checkBoundsY:
|
||||||
|
tst YL
|
||||||
|
breq PC+2
|
||||||
|
ret ; not zero, nothing to do
|
||||||
|
; YL is zero. Reset Y
|
||||||
|
clr YH
|
||||||
|
ldi YL, low(SRAM_START)
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Check that Z is within bounds, reset to SRAM_START if not.
|
||||||
|
checkBoundsZ:
|
||||||
|
tst ZL
|
||||||
|
breq PC+2
|
||||||
|
ret ; not zero, nothing to do
|
||||||
|
; ZL is zero. Reset Z
|
||||||
|
clr ZH
|
||||||
|
ldi ZL, low(SRAM_START)
|
||||||
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user