wip: keyboard send
This commit is contained in:
parent
aebd813a55
commit
e7bd5096cd
23
main.s65
23
main.s65
@ -42,10 +42,13 @@ irq:
|
|||||||
; DEBUG_LED_ON 2
|
; DEBUG_LED_ON 2
|
||||||
@irq_io1:
|
@irq_io1:
|
||||||
lda IO1 + IO::IFR
|
lda IO1 + IO::IFR
|
||||||
|
and IO1 + IO::IER ; sometimes CB1/2 IFR set even though not enabled in IER
|
||||||
sta irq_via_ifr
|
sta irq_via_ifr
|
||||||
bbr7 irq_via_ifr,@irq_io2 ; skip
|
bbr7 irq_via_ifr,@irq_io2 ; skip
|
||||||
bbs2 irq_via_ifr,@irq_kb1 ; shit reg -> first 8 bits
|
bbs2 irq_via_ifr,@irq_kb_sr
|
||||||
bbs5 irq_via_ifr,@irq_kb2 ; timer -> last 3 bits
|
bbs3 irq_via_ifr,@irq_kb_cb2
|
||||||
|
bbs4 irq_via_ifr,@irq_kb_cb1
|
||||||
|
bbs5 irq_via_ifr,@irq_kb_t2
|
||||||
bra @irq_unknown
|
bra @irq_unknown
|
||||||
@irq_io2:
|
@irq_io2:
|
||||||
lda IO2 + IO::IFR
|
lda IO2 + IO::IFR
|
||||||
@ -56,7 +59,6 @@ irq:
|
|||||||
|
|
||||||
@irq_unknown:
|
@irq_unknown:
|
||||||
; this SHOULD never be reached
|
; this SHOULD never be reached
|
||||||
jsr lcd::clear
|
|
||||||
Print "Unknown IRQ"
|
Print "Unknown IRQ"
|
||||||
; force reset interrupt flags
|
; force reset interrupt flags
|
||||||
lda #$ff
|
lda #$ff
|
||||||
@ -71,14 +73,15 @@ irq:
|
|||||||
bra @irq_return
|
bra @irq_return
|
||||||
; jmp (spi_p::irq_handler)
|
; jmp (spi_p::irq_handler)
|
||||||
; JsrIndirect (spi_p::irq_handler), @irq_return
|
; JsrIndirect (spi_p::irq_handler), @irq_return
|
||||||
@irq_kb1:
|
@irq_kb_sr:
|
||||||
; Print "$3000"
|
; Print "$3000"
|
||||||
jsr $3000
|
JsrIndirect ($3000), @irq_return
|
||||||
bra @irq_return
|
@irq_kb_cb2:
|
||||||
@irq_kb2:
|
JsrIndirect ($3020), @irq_return
|
||||||
; Print "$3100"
|
@irq_kb_cb1:
|
||||||
jsr $3100
|
JsrIndirect ($3040), @irq_return
|
||||||
bra @irq_return
|
@irq_kb_t2:
|
||||||
|
JsrIndirect ($3060), @irq_return
|
||||||
; @irq_dht:
|
; @irq_dht:
|
||||||
; lda IO1 + IO::T1CL ;T1L2 ; clear interrupt flag
|
; lda IO1 + IO::T1CL ;T1L2 ; clear interrupt flag
|
||||||
; bra @irq_return
|
; bra @irq_return
|
||||||
|
285
spicode.s65
285
spicode.s65
@ -5,6 +5,8 @@
|
|||||||
.include "keypad.h65"
|
.include "keypad.h65"
|
||||||
.include "keyboard_handler.h65"
|
.include "keyboard_handler.h65"
|
||||||
.include "chars.h65"
|
.include "chars.h65"
|
||||||
|
.include "parity.h65"
|
||||||
|
.include "sleep.h65"
|
||||||
.import homeloop:absolute
|
.import homeloop:absolute
|
||||||
.import home:absolute
|
.import home:absolute
|
||||||
|
|
||||||
@ -25,37 +27,30 @@ CODE_START:
|
|||||||
DEBUG_LED_OFF 1
|
DEBUG_LED_OFF 1
|
||||||
DEBUG_LED_OFF 2
|
DEBUG_LED_OFF 2
|
||||||
|
|
||||||
StoreDByte kb_irq1, ARG0
|
StoreDByte _process_cmd_answer, $3200
|
||||||
StoreDByte $3000, ARG2
|
|
||||||
; lda #<kb_irq1
|
|
||||||
; sta ARG0
|
|
||||||
; lda #>kb_irq1
|
|
||||||
; sta ARG1
|
|
||||||
; lda #<$3000
|
|
||||||
; sta ARG2
|
|
||||||
; lda #>$3000
|
|
||||||
; sta ARG3
|
|
||||||
ldy #10
|
|
||||||
jsr memcopy
|
|
||||||
|
|
||||||
StoreDByte kb_irq2, ARG0
|
|
||||||
StoreDByte $3100, ARG2
|
|
||||||
; lda #<kb_irq2
|
|
||||||
; sta ARG0
|
|
||||||
; lda #>kb_irq2
|
|
||||||
; sta ARG1
|
|
||||||
; lda #<$3100
|
|
||||||
; sta ARG2
|
|
||||||
; lda #>$3100
|
|
||||||
; sta ARG3
|
|
||||||
ldy #10
|
|
||||||
jsr memcopy
|
|
||||||
|
|
||||||
|
|
||||||
jsr ps2kb::init
|
jsr ps2kb::init
|
||||||
stz kb::status
|
stz kb::status
|
||||||
StoreDByte process_scancode,ps2kb::scancode_handler
|
StoreDByte process_scancode,ps2kb::scancode_handler
|
||||||
jsr ps2kb::begin_receive
|
; jsr ps2kb::begin_receive
|
||||||
|
JsrIndirect @a1, @a2
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
@a1:
|
||||||
|
lda #'1'
|
||||||
|
jsr lcd::print_char
|
||||||
|
rts
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
stp
|
||||||
|
@a2:
|
||||||
|
lda #'2'
|
||||||
|
jsr lcd::print_char
|
||||||
|
|
||||||
lda #'%'
|
lda #'%'
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
@ -84,17 +79,17 @@ CODE_START:
|
|||||||
@noscancode:
|
@noscancode:
|
||||||
bbr5 kb::status, @shift_off
|
bbr5 kb::status, @shift_off
|
||||||
@shift_on:
|
@shift_on:
|
||||||
DEBUG_LED_ON 0
|
; DEBUG_LED_ON 0
|
||||||
bra @check_caps
|
bra @check_caps
|
||||||
@shift_off:
|
@shift_off:
|
||||||
DEBUG_LED_OFF 0
|
; DEBUG_LED_OFF 0
|
||||||
@check_caps:
|
@check_caps:
|
||||||
bbr4 kb::status, @caps_off
|
bbr4 kb::status, @caps_off
|
||||||
@caps_on:
|
@caps_on:
|
||||||
DEBUG_LED_ON 2
|
; DEBUG_LED_ON 2
|
||||||
bra @read_keypad
|
bra @read_keypad
|
||||||
@caps_off:
|
@caps_off:
|
||||||
DEBUG_LED_OFF 2
|
; DEBUG_LED_OFF 2
|
||||||
@read_keypad:
|
@read_keypad:
|
||||||
lda kp::_DEBUG_VAL
|
lda kp::_DEBUG_VAL
|
||||||
jeq @loop
|
jeq @loop
|
||||||
@ -113,6 +108,8 @@ CODE_START:
|
|||||||
beq @lB
|
beq @lB
|
||||||
cmp #'C'
|
cmp #'C'
|
||||||
beq @lC
|
beq @lC
|
||||||
|
cmp #'D'
|
||||||
|
beq @lD
|
||||||
jsr lcd::print_char
|
jsr lcd::print_char
|
||||||
jmp @loop
|
jmp @loop
|
||||||
@l1:
|
@l1:
|
||||||
@ -133,8 +130,8 @@ CODE_START:
|
|||||||
iny
|
iny
|
||||||
jmp @loop
|
jmp @loop
|
||||||
@lA:
|
@lA:
|
||||||
lda ps2kb::VIA + IO::SR
|
jsr ps2kb::begin_receive
|
||||||
jsr lcd::print_char
|
; StoreDByte _receive_irq_timer_handler, $3100
|
||||||
jmp @loop
|
jmp @loop
|
||||||
@lB:
|
@lB:
|
||||||
; Printf "kc%x;", out_str, kb::scancode
|
; Printf "kc%x;", out_str, kb::scancode
|
||||||
@ -149,26 +146,23 @@ CODE_START:
|
|||||||
@lC:
|
@lC:
|
||||||
jsr lcd::clear
|
jsr lcd::clear
|
||||||
jmp @loop
|
jmp @loop
|
||||||
|
@lD:
|
||||||
|
lda ps2kb::STATUS::SEND_CMD
|
||||||
|
sta ps2kb::status
|
||||||
|
; lda #$ed
|
||||||
|
; ldx #%00000111
|
||||||
|
; lda #$f6
|
||||||
|
; lda #$ff
|
||||||
|
lda #$ee
|
||||||
|
; ldx #$ee
|
||||||
|
; ldx #0
|
||||||
|
ldx #ps2kb::NO_DATA
|
||||||
|
sta ps2kb::send_cmd
|
||||||
|
stx ps2kb::send_data
|
||||||
|
jsr _send_byte
|
||||||
|
; jsr ps2kb::send_command;
|
||||||
|
jmp @loop
|
||||||
|
|
||||||
|
|
||||||
; key_read: .res 2
|
|
||||||
; scancode: .res 1
|
|
||||||
kb_irq1:
|
|
||||||
; lda #'!'
|
|
||||||
; jsr lcd::print_char
|
|
||||||
jsr ps2kb::_receive_irq_shift_reg_handler
|
|
||||||
; lda #':'
|
|
||||||
; jsr lcd::print_char
|
|
||||||
rts
|
|
||||||
.byte '='
|
|
||||||
kb_irq2:
|
|
||||||
; lda #'?'
|
|
||||||
; jsr lcd::print_char
|
|
||||||
; jsr kb::on_timer_irq
|
|
||||||
jsr ps2kb::_receive_irq_timer_handler
|
|
||||||
; lda #';'
|
|
||||||
; jsr lcd::print_char
|
|
||||||
rts
|
|
||||||
.byte '@'
|
.byte '@'
|
||||||
|
|
||||||
.proc process_scancode
|
.proc process_scancode
|
||||||
@ -297,6 +291,194 @@ kb_irq2:
|
|||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Enable the clock signal from the keyboard
|
||||||
|
;; @modifies: A
|
||||||
|
;; @details
|
||||||
|
;; Stop pulling the keyboards clock low
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro _EnableClock
|
||||||
|
; set pin to input
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
and #<~ps2kb::PULL_MASK_CLK
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Disable the clock signal from the keyboard
|
||||||
|
;; @modifies: A
|
||||||
|
;; @details
|
||||||
|
;; Pulls the keyboards clock low
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro _DisableClock
|
||||||
|
; set pin to output
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
ora #ps2kb::PULL_MASK_CLK
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
; set pin low
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_REG
|
||||||
|
and #<~ps2kb::PULL_MASK_CLK
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_REG
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
|
||||||
|
.proc _send_byte
|
||||||
|
pha
|
||||||
|
IO_DisableIRQ ps2kb::VIA, (IO::IRQ::T2 | IO::IRQ::SR)
|
||||||
|
|
||||||
|
_DisableClock
|
||||||
|
|
||||||
|
lda #'X'
|
||||||
|
jsr lcd::print_char
|
||||||
|
|
||||||
|
; set shift register to output
|
||||||
|
lda ps2kb::VIA + IO::ACR
|
||||||
|
and #<~IO::ACR_MASK::SR
|
||||||
|
ora #IO::ACR::SR_SOUT_PHIE
|
||||||
|
sta ps2kb::VIA + IO::ACR
|
||||||
|
stz ps2kb::VIA + IO::SR
|
||||||
|
; shift out the startbit = data low
|
||||||
|
_EnableClock
|
||||||
|
_DisableClock
|
||||||
|
; reset shift register to start the count at 0 again
|
||||||
|
lda #IO::ACR::SR_SOUT_PHIE
|
||||||
|
trb ps2kb::VIA + IO::ACR
|
||||||
|
tsb ps2kb::VIA + IO::ACR
|
||||||
|
|
||||||
|
; setup the low timer byte
|
||||||
|
lda #<ps2kb::TIMER_SEND
|
||||||
|
sta ps2kb::VIA + IO::T2CL
|
||||||
|
|
||||||
|
; setup interrupt handlers
|
||||||
|
StoreDByte ps2kb::_send_irq_shift_reg_handler, $3000
|
||||||
|
; StoreDByte _send_irq_cb2_handler, $3020
|
||||||
|
; StoreDByte _send_irq_cb1_handler, $3040
|
||||||
|
StoreDByte _send_irq_timer_handler, $3060
|
||||||
|
pla
|
||||||
|
Reverse A
|
||||||
|
pha
|
||||||
|
CalculateOddParity
|
||||||
|
ror ; Parity -> C
|
||||||
|
lda #$ff
|
||||||
|
ror ; Parity -> bit 7, rest = 1
|
||||||
|
sta ps2kb::send_last_bits ; loaded into SR by irq handler
|
||||||
|
pla
|
||||||
|
sta ps2kb::VIA + IO::SR
|
||||||
|
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
|
_EnableClock
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; .proc _send_irq_shift_reg_handler
|
||||||
|
; lda ps2kb::send_last_bits
|
||||||
|
; sta ps2kb::VIA + IO::SR
|
||||||
|
|
||||||
|
; IO_DisableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
|
; IO_EnableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
|
; ; start timer, low order count already in latch after init
|
||||||
|
; lda #>ps2kb::TIMER_SEND
|
||||||
|
; sta ps2kb::VIA + IO::T2CH
|
||||||
|
; rts
|
||||||
|
; .endproc
|
||||||
|
|
||||||
|
.proc _send_irq_timer_handler
|
||||||
|
lda ps2kb::VIA + IO::T2CL ; clear interrupt flag
|
||||||
|
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
|
|
||||||
|
; disable shift register
|
||||||
|
lda ps2kb::VIA + IO::ACR
|
||||||
|
and #<~IO::ACR_MASK::SR
|
||||||
|
sta ps2kb::VIA + IO::ACR
|
||||||
|
bra _send_done
|
||||||
|
|
||||||
|
; lda ps2kb::VIA + IO::IFR
|
||||||
|
; jsr str::uint8_to_hex_str
|
||||||
|
; jsr lcd::print_char
|
||||||
|
; txa
|
||||||
|
; jsr lcd::print_char
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; @details
|
||||||
|
; Set the SEND_CMD_WAIT status bit the first time
|
||||||
|
; and jump to _send_done the second time it is called
|
||||||
|
; .proc _send_irq_cb1_handler
|
||||||
|
; ; clear the flag and disable interrupts
|
||||||
|
; ; DEBUG_LED_ON 1
|
||||||
|
; lda #'i'
|
||||||
|
; jsr lcd::print_char
|
||||||
|
; stp
|
||||||
|
|
||||||
|
; lda #IO::IRQ::CB1
|
||||||
|
; sta ps2kb::VIA + IO::IFR
|
||||||
|
; sta ps2kb::VIA + IO::IER
|
||||||
|
; ; DEBUG_LED_OFF 1
|
||||||
|
; bra _check_done
|
||||||
|
; .endproc
|
||||||
|
; .proc _send_irq_cb2_handler
|
||||||
|
; ; DEBUG_LED_ON 0
|
||||||
|
; ; lda #'I'
|
||||||
|
; ; jsr lcd::print_char
|
||||||
|
|
||||||
|
; lda #IO::IRQ::CB2
|
||||||
|
; sta ps2kb::VIA + IO::IFR
|
||||||
|
; sta ps2kb::VIA + IO::IER
|
||||||
|
; ; DEBUG_LED_OFF 0
|
||||||
|
; bra _send_done
|
||||||
|
; bra _check_done
|
||||||
|
; .endproc
|
||||||
|
|
||||||
|
; .proc _check_done
|
||||||
|
; ; check if done, by checking if SEND_CMD_WAIT bit is set
|
||||||
|
; lda #ps2kb::STATUS::SEND_CMD_WAIT
|
||||||
|
; tsb ps2kb::status
|
||||||
|
; bne _send_done ; SEND_CMD_WAIT was already set
|
||||||
|
; rts
|
||||||
|
; .endproc
|
||||||
|
|
||||||
|
.proc _send_done
|
||||||
|
_DisableClock ; disable keyboard while setting up receive
|
||||||
|
lda #'D'
|
||||||
|
jsr lcd::print_char
|
||||||
|
; Sleep 1
|
||||||
|
lda ps2kb::status
|
||||||
|
and #ps2kb::STATUS::SEND_CMD
|
||||||
|
beq @status_send_data ; data byte already sent
|
||||||
|
@status_send_cmd:
|
||||||
|
lda #ps2kb::STATUS::SEND_DATA
|
||||||
|
lda ps2kb::status
|
||||||
|
; check if a data byte needs to be sent
|
||||||
|
lda ps2kb::send_data
|
||||||
|
beq @send_data ; if 0
|
||||||
|
cmp #ps2kb::NO_DATA
|
||||||
|
beq @receive_answer ; if not NO_DATA
|
||||||
|
@send_data:
|
||||||
|
jmp _send_byte ; send the data
|
||||||
|
@status_send_data:
|
||||||
|
@receive_answer:
|
||||||
|
_DisableClock ; disable keyboard while setting up receive
|
||||||
|
DEBUG_LED_ON 0
|
||||||
|
lda #ps2kb::STATUS::RECEIVE_ANSWER
|
||||||
|
sta ps2kb::status
|
||||||
|
jmp ps2kb::begin_receive
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.proc _process_cmd_answer
|
||||||
|
Strf fmt_answer, out_str, ps2kb::send_cmd, ps2kb::send_data, ps2kb::scancode
|
||||||
|
PrintNC out_str
|
||||||
|
DEBUG_LED_ON 1
|
||||||
|
stz ps2kb::scancode
|
||||||
|
lda ps2kb::prev_status
|
||||||
|
sta ps2kb::status
|
||||||
|
; set pin to input
|
||||||
|
; lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||||
|
; and #<~ps2kb::CLK_PULL_MASK
|
||||||
|
; sta ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
out_idx: .res 1
|
out_idx: .res 1
|
||||||
out_str: .res 40
|
out_str: .res 40
|
||||||
char: .res 1
|
char: .res 1
|
||||||
@ -304,3 +486,4 @@ keycode: .res 1
|
|||||||
keycode_flags: .res 1
|
keycode_flags: .res 1
|
||||||
fmt_codechar: .asciiz "%x %x %c "
|
fmt_codechar: .asciiz "%x %x %c "
|
||||||
fmt_code: .asciiz "%x %x "
|
fmt_code: .asciiz "%x %x "
|
||||||
|
fmt_answer: .asciiz "%x-%x>%x"
|
||||||
|
@ -30,20 +30,31 @@ INCLUDE_PS2_KEYBOARD = 1
|
|||||||
|
|
||||||
.scope ps2kb
|
.scope ps2kb
|
||||||
Import ps2kb,init,begin_receive,send_command,scancode,status,scancode_handler
|
Import ps2kb,init,begin_receive,send_command,scancode,status,scancode_handler
|
||||||
Import ps2kb, _receive_irq_shift_reg_handler, _receive_irq_timer_handler
|
Import ps2kb, _receive_irq_shift_reg_handler, _receive_irq_timer_handler, _send_byte, _send_irq_shift_reg_handler, _send_irq_timer_handler,
|
||||||
|
Import ps2kb, send_last_bits, send_cmd, send_data, key_read, prev_status
|
||||||
|
|
||||||
VIA = IO1
|
VIA = IO1
|
||||||
TIMER = 230 ; 230 ms (@1MHz)
|
; Enough time must pass for 3 bits to be shifted in.
|
||||||
|
TIMER_RECV = 230 ; 230 ms (@1MHz)
|
||||||
|
; Enough time must pass for one bit must be shifted out (parity),
|
||||||
|
; but at most two (parity+stop).
|
||||||
|
; After that, the interrupt must have happened because the keyboard will pull data low.
|
||||||
|
; At that point, the SR needs to be set to input again
|
||||||
|
TIMER_SEND = 230 ; 180 ms (@1MHz)
|
||||||
; use RA4 to pull the clock low
|
; use RA4 to pull the clock low
|
||||||
CLK_PULL_MASK= %00001000
|
PULL_REG = IO::RANH
|
||||||
CLK_PULL_R = IO::RANH
|
PULL_DDR = IO::DDRA
|
||||||
CLK_PULL_DDR = IO::DDRA
|
|
||||||
|
|
||||||
|
PULL_MASK_CLK = %00010000
|
||||||
|
; PULL_MASK_DAT = %00001000
|
||||||
|
NO_DATA = $ff ; indicates that no data byte should be send
|
||||||
|
|
||||||
.enum STATUS
|
.enum STATUS
|
||||||
RECEIVE_KEYS = %10000000
|
RECEIVE_KEYS = %10000000
|
||||||
RECEIVE_ANSWER = %01000000
|
RECEIVE_ANSWER = %01000000
|
||||||
SEND_CMD = %00100000
|
SEND_CMD = %00100000
|
||||||
|
SEND_DATA = %00010000
|
||||||
|
SEND_CMD_WAIT = %00001000
|
||||||
NONE = %00000000
|
NONE = %00000000
|
||||||
.endenum
|
.endenum
|
||||||
.endscope
|
.endscope
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
.include "lcd.h65"
|
.include "lcd.h65"
|
||||||
.include "parity.h65"
|
.include "parity.h65"
|
||||||
Export ps2kb,init,begin_receive,send_command,scancode,status,scancode_handler
|
Export ps2kb,init,begin_receive,send_command,scancode,status,scancode_handler
|
||||||
Export ps2kb, _receive_irq_shift_reg_handler, _receive_irq_timer_handler
|
Export ps2kb, _receive_irq_shift_reg_handler, _receive_irq_timer_handler, _send_byte, _send_irq_shift_reg_handler, _send_irq_timer_handler,
|
||||||
|
Export ps2kb, send_last_bits, send_cmd, send_data, key_read, prev_status
|
||||||
|
|
||||||
.bss
|
.bss
|
||||||
status: .res 1
|
status: .res 1
|
||||||
|
prev_status: .res 1
|
||||||
send_last_bits: .res 1
|
send_last_bits: .res 1
|
||||||
send_data: .res 1
|
send_data: .res 1
|
||||||
send_cmd: .res 1
|
send_cmd: .res 1
|
||||||
@ -24,16 +26,9 @@ scancode_handler: .res 2
|
|||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro _EnableClock
|
.macro _EnableClock
|
||||||
; set pin to input
|
; set pin to input
|
||||||
lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
and #<~ps2kb::CLK_PULL_MASK
|
and #<~ps2kb::PULL_MASK_CLK
|
||||||
sta ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
.endmacro
|
|
||||||
|
|
||||||
.macro _DisableTimerIRQ
|
|
||||||
; set pin to input
|
|
||||||
lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
|
||||||
and #<~ps2kb::CLK_PULL_MASK
|
|
||||||
sta ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
@ -44,17 +39,45 @@ scancode_handler: .res 2
|
|||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.macro _DisableClock
|
.macro _DisableClock
|
||||||
; set pin to output
|
; set pin to output
|
||||||
lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
ora #ps2kb::CLK_PULL_MASK
|
ora #ps2kb::PULL_MASK_CLK
|
||||||
sta ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
; set pin low
|
; set pin low
|
||||||
lda ps2kb::VIA + ps2kb::CLK_PULL_R
|
lda ps2kb::VIA + ps2kb::PULL_REG
|
||||||
and #<~ps2kb::CLK_PULL_MASK
|
and #<~ps2kb::PULL_MASK_CLK
|
||||||
sta ps2kb::VIA + ps2kb::CLK_PULL_R
|
sta ps2kb::VIA + ps2kb::PULL_REG
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Stop pulling the keyboard data pin low
|
||||||
|
;; @modifies: A
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro _StopPullDataLow
|
||||||
|
; set pin to input
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
and #<~ps2kb::PULL_MASK_DAT
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
;;********************************************************************************
|
||||||
|
;; @macro Pull the keyboard data pin low
|
||||||
|
;; @modifies: A
|
||||||
|
;;********************************************************************************
|
||||||
|
.macro _PullDataLow
|
||||||
|
; set pin to output
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
ora #ps2kb::PULL_MASK_DAT
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||||
|
; set pin low
|
||||||
|
lda ps2kb::VIA + ps2kb::PULL_REG
|
||||||
|
and #<~ps2kb::PULL_MASK_DAT
|
||||||
|
sta ps2kb::VIA + ps2kb::PULL_REG
|
||||||
.endmacro
|
.endmacro
|
||||||
|
|
||||||
|
|
||||||
.proc init
|
.proc init
|
||||||
|
_DisableClock
|
||||||
stz key_read
|
stz key_read
|
||||||
stz key_read+1
|
stz key_read+1
|
||||||
stz scancode
|
stz scancode
|
||||||
@ -64,10 +87,6 @@ scancode_handler: .res 2
|
|||||||
and #<~IO::ACR_MASK::SR
|
and #<~IO::ACR_MASK::SR
|
||||||
ora #IO::ACR::T2_IRQ_LOAD
|
ora #IO::ACR::T2_IRQ_LOAD
|
||||||
sta ps2kb::VIA + IO::ACR
|
sta ps2kb::VIA + 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 #<ps2kb::TIMER
|
|
||||||
sta ps2kb::VIA + IO::T2CL
|
|
||||||
; load this rts as scancode_handler
|
; load this rts as scancode_handler
|
||||||
StoreDByte @rts, scancode_handler
|
StoreDByte @rts, scancode_handler
|
||||||
@rts:
|
@rts:
|
||||||
@ -85,25 +104,32 @@ scancode_handler: .res 2
|
|||||||
.proc begin_receive
|
.proc begin_receive
|
||||||
; disable timer interrupts (this might be called while waiting on the last 3 bits)
|
; disable timer interrupts (this might be called while waiting on the last 3 bits)
|
||||||
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
; set shift register to shift in under external clock on CB1
|
; (re)set shift register to shift in under external clock on CB1
|
||||||
lda ps2kb::VIA + IO::ACR
|
lda ps2kb::VIA + IO::ACR
|
||||||
and #<~IO::ACR_MASK::SR
|
and #<~IO::ACR_MASK::SR
|
||||||
|
sta ps2kb::VIA + IO::ACR ; important, disabling SR resets the count
|
||||||
ora #IO::ACR::SR_SIN_PHIE
|
ora #IO::ACR::SR_SIN_PHIE
|
||||||
sta ps2kb::VIA + IO::ACR
|
sta ps2kb::VIA + IO::ACR
|
||||||
stz key_read
|
stz key_read
|
||||||
stz key_read+1
|
stz key_read+1
|
||||||
stz scancode
|
stz scancode
|
||||||
bit status
|
bit status
|
||||||
|
|
||||||
|
; 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 #<ps2kb::TIMER_RECV
|
||||||
|
sta ps2kb::VIA + IO::T2CL
|
||||||
; set to RECEIVE_KEYS only if RECEIVE_ANSWER is not set
|
; set to RECEIVE_KEYS only if RECEIVE_ANSWER is not set
|
||||||
bvs @receive_answer
|
bvs @status_set
|
||||||
lda #ps2kb::STATUS::RECEIVE_KEYS
|
lda #ps2kb::STATUS::RECEIVE_KEYS
|
||||||
sta status
|
sta status
|
||||||
@receive_answer:
|
@status_set:
|
||||||
|
; todo setup irq handlers
|
||||||
|
StoreDByte _receive_irq_shift_reg_handler, $3000
|
||||||
|
StoreDByte _receive_irq_timer_handler, $3060
|
||||||
|
|
||||||
_EnableClock
|
_EnableClock
|
||||||
|
|
||||||
; todo setup irq handlers
|
|
||||||
|
|
||||||
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
; reset and start SR
|
; reset and start SR
|
||||||
stz ps2kb::VIA + IO::SR
|
stz ps2kb::VIA + IO::SR
|
||||||
@ -132,7 +158,7 @@ scancode_handler: .res 2
|
|||||||
IO_DisableIRQ ps2kb::VIA, IO::IRQ::SR
|
IO_DisableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
IO_EnableIRQ ps2kb::VIA, IO::IRQ::T2
|
IO_EnableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
; start timer, low order count already in latch after init
|
; start timer, low order count already in latch after init
|
||||||
lda #>ps2kb::TIMER
|
lda #>ps2kb::TIMER_RECV
|
||||||
sta ps2kb::VIA + IO::T2CH
|
sta ps2kb::VIA + IO::T2CH
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
@ -173,10 +199,13 @@ scancode_handler: .res 2
|
|||||||
rol ; C -> bit 0, startbit -> C
|
rol ; C -> bit 0, startbit -> C
|
||||||
Reverse A
|
Reverse A
|
||||||
sta scancode
|
sta scancode
|
||||||
CalculateOddParity
|
|
||||||
eor key_read+1 ; if bit 0 is 1 - parity error
|
; check parity
|
||||||
and #1 ; bit 1 is still D7
|
; CalculateOddParity
|
||||||
bne @parity_error
|
; eor key_read+1 ; if bit 0 is 1 - parity error
|
||||||
|
; and #1 ; bit 1 is still D7
|
||||||
|
; bne @parity_error
|
||||||
|
|
||||||
; check what to do with the scancode
|
; check what to do with the scancode
|
||||||
bit status
|
bit status
|
||||||
bcc @status_not_receive_keys
|
bcc @status_not_receive_keys
|
||||||
@ -198,15 +227,15 @@ scancode_handler: .res 2
|
|||||||
;; @function Send a command to the keyboard
|
;; @function Send a command to the keyboard
|
||||||
;; @modifies: A,X,Y
|
;; @modifies: A,X,Y
|
||||||
;; @param A: The command byte
|
;; @param A: The command byte
|
||||||
;; @param X: The data byte or 0 if only the command byte should be sent
|
;; @param X: The data byte or NO_DATA if only the command byte should be sent
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc send_command
|
.proc send_command
|
||||||
|
ldy status
|
||||||
|
sty prev_status
|
||||||
|
ldy #ps2kb::STATUS::SEND_CMD
|
||||||
|
sty status
|
||||||
sta send_cmd ; store if it needs to be resent
|
sta send_cmd ; store if it needs to be resent
|
||||||
cpx #0
|
|
||||||
beq @jmp_send_byte
|
|
||||||
@store_data:
|
|
||||||
stx send_data
|
stx send_data
|
||||||
@jmp_send_byte:
|
|
||||||
jmp _send_byte
|
jmp _send_byte
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
@ -217,36 +246,51 @@ scancode_handler: .res 2
|
|||||||
;; @param A: The byte to send
|
;; @param A: The byte to send
|
||||||
;; @details
|
;; @details
|
||||||
;; - pull clock low to stop keyboard transmissions
|
;; - pull clock low to stop keyboard transmissions
|
||||||
;; - setup shift register to shift out
|
;; - setup SR to shift out
|
||||||
;; - put startbit + D0-6 in shift register
|
;; - pull data low (by shifting out a zero)
|
||||||
;; - store D7 + parity + stopbit in memory
|
;; - reset SR
|
||||||
;; - TODO setup SR and T2 interrupt handlers
|
;; - put (reversed) byte in SR
|
||||||
|
;; - put parity + stopbit(s) in send_last_bits variable
|
||||||
|
;; - setup interrupt handlers
|
||||||
|
;; - enable clock
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc _send_byte
|
.proc _send_byte
|
||||||
pha
|
pha
|
||||||
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
IO_DisableIRQ ps2kb::VIA, (IO::IRQ::T2 | IO::IRQ::SR)
|
||||||
|
|
||||||
_DisableClock
|
_DisableClock
|
||||||
; (re)set shift register to shift out under external clock on CB1
|
|
||||||
|
; set shift register to output
|
||||||
lda ps2kb::VIA + IO::ACR
|
lda ps2kb::VIA + IO::ACR
|
||||||
and #<~IO::ACR_MASK::SR
|
and #<~IO::ACR_MASK::SR
|
||||||
ora #IO::ACR::SR_SOUT_PHIE
|
ora #IO::ACR::SR_SOUT_PHIE
|
||||||
sta ps2kb::VIA + IO::ACR
|
sta ps2kb::VIA + IO::ACR
|
||||||
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
stz ps2kb::VIA + IO::SR
|
||||||
|
; shift out the startbit = data low
|
||||||
|
_EnableClock
|
||||||
|
_DisableClock
|
||||||
|
; reset shift register to start the count at 0 again
|
||||||
|
lda #IO::ACR::SR_SOUT_PHIE
|
||||||
|
trb ps2kb::VIA + IO::ACR
|
||||||
|
tsb ps2kb::VIA + IO::ACR
|
||||||
|
|
||||||
|
; setup the low timer byte
|
||||||
|
lda #<ps2kb::TIMER_SEND
|
||||||
|
sta ps2kb::VIA + IO::T2CL
|
||||||
|
|
||||||
|
StoreDByte _send_irq_shift_reg_handler, $3000
|
||||||
|
StoreDByte _send_irq_timer_handler, $3006
|
||||||
pla
|
pla
|
||||||
|
Reverse A
|
||||||
pha
|
pha
|
||||||
; split into the 11 bits
|
|
||||||
CalculateOddParity
|
CalculateOddParity
|
||||||
tax
|
ror ; Parity -> C
|
||||||
|
lda #$ff
|
||||||
|
ror ; Parity -> bit 7, rest = 1
|
||||||
|
sta ps2kb::send_last_bits ; loaded into SR by irq handler
|
||||||
pla
|
pla
|
||||||
clc ; C = 0 (startbi)
|
|
||||||
rol ; C -> bit 0, D7 -> C
|
|
||||||
sta ps2kb::VIA + IO::SR
|
sta ps2kb::VIA + IO::SR
|
||||||
txa
|
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
ror ; C -> bit 0 (D7)
|
|
||||||
ora #%00000100 ; set stopbit
|
|
||||||
; A = 000001P7 where 7 = D7, P = Parity
|
|
||||||
sta send_last_bits ; loaded into SR by irq handler
|
|
||||||
; stop pulling clk low, which causes the startbit to be shifted out
|
|
||||||
_EnableClock
|
_EnableClock
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
@ -262,17 +306,13 @@ scancode_handler: .res 2
|
|||||||
;; - start timer 2
|
;; - start timer 2
|
||||||
;;********************************************************************************
|
;;********************************************************************************
|
||||||
.proc _send_irq_shift_reg_handler
|
.proc _send_irq_shift_reg_handler
|
||||||
lda send_last_bits
|
lda ps2kb::send_last_bits
|
||||||
sta ps2kb::VIA + IO::SR
|
sta ps2kb::VIA + IO::SR
|
||||||
|
|
||||||
; disable SR interrupts
|
IO_DisableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||||
lda #IO::IRQ::SR
|
IO_EnableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
sta ps2kb::VIA + IO::IER
|
|
||||||
; enable timer interrupts
|
|
||||||
lda #(IO::IRQ::IRQ | IO::IRQ::T2)
|
|
||||||
sta ps2kb::VIA + IO::IER
|
|
||||||
; start timer, low order count already in latch after init
|
; start timer, low order count already in latch after init
|
||||||
lda #>ps2kb::TIMER
|
lda #>ps2kb::TIMER_SEND
|
||||||
sta ps2kb::VIA + IO::T2CH
|
sta ps2kb::VIA + IO::T2CH
|
||||||
rts
|
rts
|
||||||
.endproc
|
.endproc
|
||||||
@ -293,21 +333,20 @@ scancode_handler: .res 2
|
|||||||
.proc _send_irq_timer_handler
|
.proc _send_irq_timer_handler
|
||||||
lda ps2kb::VIA + IO::T2CL ; clear interrupt flag
|
lda ps2kb::VIA + IO::T2CL ; clear interrupt flag
|
||||||
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||||
; no SR reset necessary, will be done in begin_receive or send_byte
|
|
||||||
|
|
||||||
lda send_data
|
lda ps2kb::send_data
|
||||||
beq @receive
|
beq @receive
|
||||||
stz send_data
|
stz ps2kb::send_data
|
||||||
jmp _send_byte
|
jmp _send_byte
|
||||||
rts
|
rts
|
||||||
@receive:
|
@receive:
|
||||||
|
_DisableClock ; disable keyboard while setting up receive
|
||||||
lda #ps2kb::STATUS::RECEIVE_ANSWER
|
lda #ps2kb::STATUS::RECEIVE_ANSWER
|
||||||
sta status
|
sta ps2kb::status
|
||||||
jmp begin_receive
|
jmp ps2kb::begin_receive
|
||||||
.endproc
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
.proc _process_cmd_answer
|
.proc _process_cmd_answer
|
||||||
@success:
|
jmp ($3200)
|
||||||
rts
|
|
||||||
.endproc
|
.endproc
|
||||||
|
Loading…
Reference in New Issue
Block a user