parent
302e49a9f7
commit
45dce42475
@ -1,23 +0,0 @@
|
|||||||
;;********************************************************************************
|
|
||||||
;; @module keyboard
|
|
||||||
;; @type drive
|
|
||||||
;; @details:
|
|
||||||
;; Support for a PS2 Keyboard using the shift register of a 6522 VIA
|
|
||||||
;; Pressing a key causes 11 bits to be sent: 1 start - 8 keycode - 1 parity - 1 stop
|
|
||||||
;; The VIA is set up to interrupt after 8 bits have been shifted into the shift register
|
|
||||||
;; from the external clock pulses of the keyboard (additional hardware required to
|
|
||||||
;; address the hardware bug of the VIA, where bit get lost when the external clock
|
|
||||||
;; transition happens during falling edge of PHI2). After reading the shift register,
|
|
||||||
;; the VIAs T2 timer is set to interrupt after the last 3 bits have been shifted in,
|
|
||||||
;; which takes about ~230ms.
|
|
||||||
;;********************************************************************************
|
|
||||||
.ifndef INCLUDE_KEYBOARD
|
|
||||||
INCLUDE_KEYBOARD = 1
|
|
||||||
.include "system.h65"
|
|
||||||
|
|
||||||
.scope kb
|
|
||||||
Import kb,init,irq_shift_reg_handler,irq_timer_handler,keycode,key_read
|
|
||||||
KB_IO = IO1
|
|
||||||
|
|
||||||
.endscope
|
|
||||||
.endif
|
|
@ -1,106 +0,0 @@
|
|||||||
.include "keyboard.h65"
|
|
||||||
.include "string.h65"
|
|
||||||
.include "lcd.h65"
|
|
||||||
Export kb,init,irq_shift_reg_handler,irq_timer_handler,keycode,key_read
|
|
||||||
|
|
||||||
.bss
|
|
||||||
key_read: .res 2
|
|
||||||
keycode: .res 1
|
|
||||||
|
|
||||||
.code
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Initialize the PS2 keyboard
|
|
||||||
;; @modifies: A
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc init
|
|
||||||
; - use the shift register interrupts to read the first 8 bits
|
|
||||||
; set shift register to shift in under external clock on CB1
|
|
||||||
; - configure timer for timing the read of the last 3 bits
|
|
||||||
; timer 2 one shot mode is sufficient, leaves T1 available
|
|
||||||
lda #(IO::ACR::SR_SIN_PHIE | IO::ACR::T2_IRQ_LOAD)
|
|
||||||
tsb kb::KB_IO + IO::ACR
|
|
||||||
; the 3 last bits take about 230us, at @1MHz => wait 230 cycles and then the shift register
|
|
||||||
; (this could be shorter since the it takes a few cycles after the interrupt)
|
|
||||||
lda #230
|
|
||||||
sta kb::KB_IO + IO::T2CL
|
|
||||||
stz key_read
|
|
||||||
stz key_read+1
|
|
||||||
|
|
||||||
; enable SR interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; load SR to reset
|
|
||||||
lda kb::KB_IO + IO::SR
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Read the first 8 bits an
|
|
||||||
;; @modifies: A
|
|
||||||
;; @details
|
|
||||||
;; - read shift register
|
|
||||||
;; - disable shift register interrupts
|
|
||||||
;; - reset shift register
|
|
||||||
;; - enable timer 2 interrupts
|
|
||||||
;; - start timer 2
|
|
||||||
;; IO::SR has to be read before the next bit is shifted in, which happens ~75us after the irq
|
|
||||||
;; at 1MHz, handling this interrupt takes about 50us (without any additional debug code),
|
|
||||||
;; so it should work
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc irq_shift_reg_handler
|
|
||||||
lda kb::KB_IO + IO::SR
|
|
||||||
sta key_read
|
|
||||||
stz kb::KB_IO + IO::SR
|
|
||||||
|
|
||||||
; disable SR interrupts
|
|
||||||
lda #IO::IRQ::SR
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; enable timer interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::T2)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; start timer, low order count already in latch after init
|
|
||||||
lda #1
|
|
||||||
sta kb::KB_IO + IO::T2CH
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
|
|
||||||
;;********************************************************************************
|
|
||||||
;; @function Read the last 3 bits after after timer 2 is up
|
|
||||||
;; @modifies: A
|
|
||||||
;; @details
|
|
||||||
;; - read shift register
|
|
||||||
;; - disable timer 2 interrupts
|
|
||||||
;; - enable shift register interrupts
|
|
||||||
;; - reset shift register
|
|
||||||
;;********************************************************************************
|
|
||||||
.proc irq_timer_handler
|
|
||||||
lda kb::KB_IO + IO::SR
|
|
||||||
sta key_read + 1
|
|
||||||
|
|
||||||
lda kb::KB_IO + IO::T2CL ; clear interrupt flag
|
|
||||||
|
|
||||||
; disable timer interrupts
|
|
||||||
lda #(IO::IRQ::T2)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; enable shift register interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
||||||
sta kb::KB_IO + IO::IER
|
|
||||||
; reset SR
|
|
||||||
stz kb::KB_IO + IO::SR
|
|
||||||
|
|
||||||
; rotate bit 2 (last bit of keycode) into the carry
|
|
||||||
lda key_read+1
|
|
||||||
ror
|
|
||||||
ror
|
|
||||||
ror
|
|
||||||
lda key_read ; not affecting carry
|
|
||||||
rol ; rotate carry into byte, rotate startbit into carry
|
|
||||||
; TODO byte is inverted, maybe consider wasting 256 bytes for a bit reverse lookup table?
|
|
||||||
sta keycode
|
|
||||||
|
|
||||||
stz key_read
|
|
||||||
stz key_read+1
|
|
||||||
rts
|
|
||||||
.endproc
|
|
Loading…
Reference in New Issue
Block a user