139 lines
4.5 KiB
Plaintext
139 lines
4.5 KiB
Plaintext
.include "keyboard.h65"
|
|
.include "string.h65"
|
|
.include "lcd.h65"
|
|
Export kb,init,irq_shift_reg_handler,irq_timer_handler,scancode,key_read
|
|
Export kb, CHARS_NOMOD, CHARS_MODSHIFT
|
|
ExportZp kb,status
|
|
|
|
.zeropage
|
|
status:
|
|
.bss
|
|
key_read: .res 2
|
|
scancode: .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
|
|
stz scancode
|
|
stz status
|
|
|
|
; 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 #0
|
|
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
|
|
|
|
; reset SR
|
|
; disabling shifting in acr seems necessary to reset - otherwise
|
|
; it continues counting and interrupts after the first 5 bits of the next keypress
|
|
lda #(IO::ACR::SR_SIN_PHIE | IO::ACR::T2_IRQ_LOAD)
|
|
trb kb::KB_IO + IO::ACR
|
|
tsb kb::KB_IO + IO::ACR
|
|
stz kb::KB_IO + IO::SR
|
|
; enable shift register interrupts
|
|
lda #(IO::IRQ::IRQ | IO::IRQ::SR)
|
|
sta kb::KB_IO + IO::IER
|
|
|
|
lda key_read+1
|
|
ror
|
|
ror
|
|
ror
|
|
lda key_read ; not affecting carry
|
|
rol ; rotate carry into byte, rotate startbit into carry
|
|
Reverse A
|
|
sta scancode
|
|
|
|
rts
|
|
.endproc
|
|
|
|
.rodata
|
|
.align 256
|
|
CHARS_NOMOD:
|
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00"
|
|
.byte "\x00\x00\x00\x00\x00q1\x00\x00\x00ysaw2\x00"
|
|
.byte "\x00cxde43\x00\x00 vftr5\x00"
|
|
.byte "\x00nbhgz6\x00\x00\x00mju78\x00"
|
|
.byte "\x00,kio09\x00\x00.-l\xEFp\xE2\x00"
|
|
.byte "\x00\x00\xE1\x00\xF5`\x00\x00\x00\x00\x00\x00\x00#\x00\x00"
|
|
.byte "\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
|
|
.align 256
|
|
CHARS_MODSHIFT:
|
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xDF\x00"
|
|
.byte "\x00\x00\x00\x00\x00Q!\x00\x00\x00YSAW\"\x00"
|
|
.byte "\x00CXDE$\xED\x00\x00 VFTR%\x00"
|
|
.byte "\x00NBHGZ&\x00\x00\x00MJU/(\x00"
|
|
.byte "\x00;KIO=)\x00\x00:_L\xEFP\xE2\x00"
|
|
.byte "\x00\x00\xE1\x00\xF5`\x00\x00\x00\x00\x00\x00\x00'\x00\x00"
|
|
.byte "\x00>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
|
.byte "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|