Browse Source

recipes/rc2014/ps2: implement scan code buffer

pull/10/head
Virgil Dupras 5 years ago
parent
commit
3cdb25bfda
1 changed files with 41 additions and 16 deletions
  1. +41
    -16
      recipes/rc2014/ps2/ps2ctl.asm

+ 41
- 16
recipes/rc2014/ps2/ps2ctl.asm 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

Loading…
Cancel
Save