recipes/rc2014/ps2: implement scan code buffer

This commit is contained in:
Virgil Dupras 2019-06-29 11:18:37 -04:00
parent 20a7ad231f
commit 3cdb25bfda

View File

@ -33,9 +33,10 @@
; *** Buffering scan codes ***
;
; The whole SRAM (from SRAM_START to RAMEND) is used as a scan code buffer, with
; Z chasing Y. When Y == Z, the buffer is empty. When RAMEND is reached, we go
; back to SRAM_START.
; The buffer starts at SRAM and stops at 0x100. It leaves space for the stack
; and makes overflow check easy. Also, we don't need a very big buffer. In this
; 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 we send a scan code to the 595 (which can't be done when Z == Y
@ -59,7 +60,6 @@
; *** 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
; z80 yet.
; R16: tmp stuff
@ -75,7 +75,7 @@
; R20: data being sent to the 595
; Y: pointer to the memory location where the next scan code from ps/2 will be
; written.
; Z: pointer to last scan code pushed to the 595
; Z: pointer to the next scan code to push to the 595
;
; *** Constants ***
;
@ -104,6 +104,7 @@ hdlPCINT:
sbi PORTB, RCLK
cbi PORTB, RCLK
clr r2 ; 595 is now free
reti
main:
ldi r16, low(RAMEND)
@ -119,7 +120,6 @@ main:
; init variables
clr r1
clr r2
clr r19
clr r18
@ -135,6 +135,12 @@ main:
ldi r16, (1<<PCINT4)
out PCMSK, r16
; Setup buffer
clr YH
ldi YL, low(SRAM_START)
clr ZH
ldi ZL, low(SRAM_START)
; init DDRB
sbi DDRB, SRCLK
cbi PORTB, RCLK ; RCLK is generally kept low
@ -144,8 +150,8 @@ main:
loop:
brts processbit ; flag T set? we have a bit to process
tst r1
brne sendTo595 ; r1 is non-zero? char is ready to send
cp YL, ZL ; if YL == ZL, buffer is empty
brne sendTo595 ; YL != ZL? our buffer has data
rjmp loop
; Process the data bit received in INT0 handler.
@ -165,8 +171,10 @@ processbit:
clr r18 ; happens in all cases
; DATA has to be set
tst r16 ; Was DATA set?
breq loop ; not set? error, don't inc R1
inc r1 ; indicate that value in r17 is good
breq loop ; not set? error, don't push to buffer
; push r17 to the buffer
st Y+, r17
rcall checkBoundsY
rjmp loop
processbits0:
; step 0 - start bit
@ -177,7 +185,6 @@ processbits0:
; DATA is cleared. prepare r17 and r18 for step 1
inc r18
ldi r17, 0x80
clr r1
rjmp loop
processbits1:
@ -201,20 +208,18 @@ processbits2:
inc r18
rjmp loop
; send R17 to 595, MSB.
; send next scan code in buffer to 595, MSB.
sendTo595:
tst r2
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
; is, it has no meaning to us at this point in time and processing it
; might mess things up.
cli
sbi DDRB, DATA
mov r20, r17
clr r1
ld r20, Z+
rcall checkBoundsZ
ldi r16, 8
sendTo595Loop:
@ -239,3 +244,23 @@ sendTo595Loop:
inc r2
sei
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