Compare commits
3 Commits
e1f78b2927
...
e7bd5096cd
Author | SHA1 | Date | |
---|---|---|---|
e7bd5096cd | |||
aebd813a55 | |||
808900602e |
25
main.s65
25
main.s65
@ -42,10 +42,13 @@ irq:
|
||||
; DEBUG_LED_ON 2
|
||||
@irq_io1:
|
||||
lda IO1 + IO::IFR
|
||||
and IO1 + IO::IER ; sometimes CB1/2 IFR set even though not enabled in IER
|
||||
sta irq_via_ifr
|
||||
bbr7 irq_via_ifr,@irq_io2 ; skip
|
||||
bbs2 irq_via_ifr,@irq_kb1 ; shit reg -> first 8 bits
|
||||
bbs5 irq_via_ifr,@irq_kb2 ; timer -> last 3 bits
|
||||
bbr7 irq_via_ifr,@irq_io2 ; skip
|
||||
bbs2 irq_via_ifr,@irq_kb_sr
|
||||
bbs3 irq_via_ifr,@irq_kb_cb2
|
||||
bbs4 irq_via_ifr,@irq_kb_cb1
|
||||
bbs5 irq_via_ifr,@irq_kb_t2
|
||||
bra @irq_unknown
|
||||
@irq_io2:
|
||||
lda IO2 + IO::IFR
|
||||
@ -56,7 +59,6 @@ irq:
|
||||
|
||||
@irq_unknown:
|
||||
; this SHOULD never be reached
|
||||
jsr lcd::clear
|
||||
Print "Unknown IRQ"
|
||||
; force reset interrupt flags
|
||||
lda #$ff
|
||||
@ -71,14 +73,15 @@ irq:
|
||||
bra @irq_return
|
||||
; jmp (spi_p::irq_handler)
|
||||
; JsrIndirect (spi_p::irq_handler), @irq_return
|
||||
@irq_kb1:
|
||||
@irq_kb_sr:
|
||||
; Print "$3000"
|
||||
jsr $3000
|
||||
bra @irq_return
|
||||
@irq_kb2:
|
||||
; Print "$3100"
|
||||
jsr $3100
|
||||
bra @irq_return
|
||||
JsrIndirect ($3000), @irq_return
|
||||
@irq_kb_cb2:
|
||||
JsrIndirect ($3020), @irq_return
|
||||
@irq_kb_cb1:
|
||||
JsrIndirect ($3040), @irq_return
|
||||
@irq_kb_t2:
|
||||
JsrIndirect ($3060), @irq_return
|
||||
; @irq_dht:
|
||||
; lda IO1 + IO::T1CL ;T1L2 ; clear interrupt flag
|
||||
; bra @irq_return
|
||||
|
289
spicode.s65
289
spicode.s65
@ -5,6 +5,8 @@
|
||||
.include "keypad.h65"
|
||||
.include "keyboard_handler.h65"
|
||||
.include "chars.h65"
|
||||
.include "parity.h65"
|
||||
.include "sleep.h65"
|
||||
.import homeloop:absolute
|
||||
.import home:absolute
|
||||
|
||||
@ -25,37 +27,30 @@ CODE_START:
|
||||
DEBUG_LED_OFF 1
|
||||
DEBUG_LED_OFF 2
|
||||
|
||||
StoreDByte kb_irq1, ARG0
|
||||
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
|
||||
StoreDByte _process_cmd_answer, $3200
|
||||
|
||||
|
||||
jsr ps2kb::init
|
||||
stz kb::status
|
||||
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 #'%'
|
||||
jsr lcd::print_char
|
||||
@ -84,17 +79,17 @@ CODE_START:
|
||||
@noscancode:
|
||||
bbr5 kb::status, @shift_off
|
||||
@shift_on:
|
||||
DEBUG_LED_ON 0
|
||||
; DEBUG_LED_ON 0
|
||||
bra @check_caps
|
||||
@shift_off:
|
||||
DEBUG_LED_OFF 0
|
||||
; DEBUG_LED_OFF 0
|
||||
@check_caps:
|
||||
bbr4 kb::status, @caps_off
|
||||
@caps_on:
|
||||
DEBUG_LED_ON 2
|
||||
; DEBUG_LED_ON 2
|
||||
bra @read_keypad
|
||||
@caps_off:
|
||||
DEBUG_LED_OFF 2
|
||||
; DEBUG_LED_OFF 2
|
||||
@read_keypad:
|
||||
lda kp::_DEBUG_VAL
|
||||
jeq @loop
|
||||
@ -113,6 +108,8 @@ CODE_START:
|
||||
beq @lB
|
||||
cmp #'C'
|
||||
beq @lC
|
||||
cmp #'D'
|
||||
beq @lD
|
||||
jsr lcd::print_char
|
||||
jmp @loop
|
||||
@l1:
|
||||
@ -133,8 +130,8 @@ CODE_START:
|
||||
iny
|
||||
jmp @loop
|
||||
@lA:
|
||||
lda ps2kb::VIA + IO::SR
|
||||
jsr lcd::print_char
|
||||
jsr ps2kb::begin_receive
|
||||
; StoreDByte _receive_irq_timer_handler, $3100
|
||||
jmp @loop
|
||||
@lB:
|
||||
; Printf "kc%x;", out_str, kb::scancode
|
||||
@ -149,26 +146,23 @@ CODE_START:
|
||||
@lC:
|
||||
jsr lcd::clear
|
||||
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 '@'
|
||||
|
||||
.proc process_scancode
|
||||
@ -297,10 +291,199 @@ kb_irq2:
|
||||
rts
|
||||
.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_str: .res 40
|
||||
char: .res 1
|
||||
keycode: .res 1
|
||||
keycode_flags: .res 1
|
||||
fmt_codechar: .asciiz "%x %x %c "
|
||||
fmt_code: .asciiz "%x %x "
|
||||
fmt_codechar: .asciiz "%x %x %c "
|
||||
fmt_code: .asciiz "%x %x "
|
||||
fmt_answer: .asciiz "%x-%x>%x"
|
||||
|
@ -79,10 +79,10 @@ INCLUDE_IOW65C22 = 1
|
||||
CA2_IN_AE_IRQ_IND= %00000010 ; Independent interrupt input-negative edge
|
||||
CA2_IP_AE = %00000100 ; Input-positive active edge
|
||||
CA2_IP_AE_IRQ_IND= %00000110 ; Independent interrupt input-positive edge
|
||||
CA2_IN_HANDSHAKE = %00001000 ; Handshake output
|
||||
CA2_IN_PULSE_OUT = %00001010 ; Pulse output
|
||||
CA2_IN_LOW_OUT = %00001100 ; Low output
|
||||
CA2_IN_HIGH_OUT = %00001110 ; High output
|
||||
CA2_OUT_HANDSHAKE= %00001000 ; Handshake output
|
||||
CA2_OUT_PULSE = %00001010 ; Pulse output
|
||||
CA2_OUT_LOW = %00001100 ; Low output
|
||||
CA2_OUT_HIGH = %00001110 ; High output
|
||||
; CB1 Modes
|
||||
CB1_IN_AE = %00000000 ; Input-negative active edge
|
||||
CB1_IP_AE = %00010000 ; Input-positive active edge
|
||||
@ -91,10 +91,10 @@ INCLUDE_IOW65C22 = 1
|
||||
CB2_IN_AE_IRQ_IND= %00100000 ; Independent interrupt input-negative edge
|
||||
CB2_IP_AE = %01000000 ; Input-positive active edge
|
||||
CB2_IP_AE_IRQ_IND= %01100000 ; Independent interrupt input-positive edge
|
||||
CB2_IN_HANDSHAKE = %10000000 ; Handshake output
|
||||
CB2_IN_PULSE_OUT = %10100000 ; Pulse output
|
||||
CB2_IN_LOW_OUT = %11000000 ; Low output
|
||||
CB2_IN_HIGH_OUT = %11100000 ; High output
|
||||
CB2_OUT_HANDSHAKE= %10000000 ; Handshake output
|
||||
CB2_OUT_PULSE = %10100000 ; Pulse output
|
||||
CB2_OUT_LOW = %11000000 ; Low output
|
||||
CB2_OUT_HIGH = %11100000 ; High output
|
||||
.endenum
|
||||
|
||||
; IFR/IER bits
|
||||
|
@ -30,20 +30,31 @@ INCLUDE_PS2_KEYBOARD = 1
|
||||
|
||||
.scope ps2kb
|
||||
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
|
||||
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
|
||||
CLK_PULL_MASK= %00001000
|
||||
CLK_PULL_R = IO::RANH
|
||||
CLK_PULL_DDR = IO::DDRA
|
||||
PULL_REG = IO::RANH
|
||||
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
|
||||
RECEIVE_KEYS = %10000000
|
||||
RECEIVE_ANSWER = %01000000
|
||||
SEND_CMD = %00100000
|
||||
SEND_DATA = %00010000
|
||||
SEND_CMD_WAIT = %00001000
|
||||
NONE = %00000000
|
||||
.endenum
|
||||
.endscope
|
||||
|
@ -3,10 +3,12 @@
|
||||
.include "lcd.h65"
|
||||
.include "parity.h65"
|
||||
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
|
||||
status: .res 1
|
||||
prev_status: .res 1
|
||||
send_last_bits: .res 1
|
||||
send_data: .res 1
|
||||
send_cmd: .res 1
|
||||
@ -24,16 +26,9 @@ scancode_handler: .res 2
|
||||
;;********************************************************************************
|
||||
.macro _EnableClock
|
||||
; set pin to input
|
||||
lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||
and #<~ps2kb::CLK_PULL_MASK
|
||||
sta ps2kb::VIA + ps2kb::CLK_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
|
||||
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||
and #<~ps2kb::PULL_MASK_CLK
|
||||
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||
.endmacro
|
||||
|
||||
;;********************************************************************************
|
||||
@ -44,17 +39,45 @@ scancode_handler: .res 2
|
||||
;;********************************************************************************
|
||||
.macro _DisableClock
|
||||
; set pin to output
|
||||
lda ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||
ora #ps2kb::CLK_PULL_MASK
|
||||
sta ps2kb::VIA + ps2kb::CLK_PULL_DDR
|
||||
lda ps2kb::VIA + ps2kb::PULL_DDR
|
||||
ora #ps2kb::PULL_MASK_CLK
|
||||
sta ps2kb::VIA + ps2kb::PULL_DDR
|
||||
; set pin low
|
||||
lda ps2kb::VIA + ps2kb::CLK_PULL_R
|
||||
and #<~ps2kb::CLK_PULL_MASK
|
||||
sta ps2kb::VIA + ps2kb::CLK_PULL_R
|
||||
lda ps2kb::VIA + ps2kb::PULL_REG
|
||||
and #<~ps2kb::PULL_MASK_CLK
|
||||
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
|
||||
|
||||
|
||||
.proc init
|
||||
_DisableClock
|
||||
stz key_read
|
||||
stz key_read+1
|
||||
stz scancode
|
||||
@ -64,10 +87,6 @@ scancode_handler: .res 2
|
||||
and #<~IO::ACR_MASK::SR
|
||||
ora #IO::ACR::T2_IRQ_LOAD
|
||||
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
|
||||
StoreDByte @rts, scancode_handler
|
||||
@rts:
|
||||
@ -85,25 +104,32 @@ scancode_handler: .res 2
|
||||
.proc begin_receive
|
||||
; disable timer interrupts (this might be called while waiting on the last 3 bits)
|
||||
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
|
||||
and #<~IO::ACR_MASK::SR
|
||||
sta ps2kb::VIA + IO::ACR ; important, disabling SR resets the count
|
||||
ora #IO::ACR::SR_SIN_PHIE
|
||||
sta ps2kb::VIA + IO::ACR
|
||||
stz key_read
|
||||
stz key_read+1
|
||||
stz scancode
|
||||
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
|
||||
bvs @receive_answer
|
||||
bvs @status_set
|
||||
lda #ps2kb::STATUS::RECEIVE_KEYS
|
||||
sta status
|
||||
@receive_answer:
|
||||
@status_set:
|
||||
; todo setup irq handlers
|
||||
StoreDByte _receive_irq_shift_reg_handler, $3000
|
||||
StoreDByte _receive_irq_timer_handler, $3060
|
||||
|
||||
_EnableClock
|
||||
|
||||
; todo setup irq handlers
|
||||
|
||||
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||
; reset and start SR
|
||||
stz ps2kb::VIA + IO::SR
|
||||
@ -132,7 +158,7 @@ scancode_handler: .res 2
|
||||
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
|
||||
lda #>ps2kb::TIMER_RECV
|
||||
sta ps2kb::VIA + IO::T2CH
|
||||
rts
|
||||
.endproc
|
||||
@ -150,7 +176,7 @@ scancode_handler: .res 2
|
||||
;;********************************************************************************
|
||||
.proc _receive_irq_timer_handler
|
||||
lda ps2kb::VIA + IO::SR
|
||||
sta key_read + 1
|
||||
sta key_read+1
|
||||
|
||||
lda ps2kb::VIA + IO::T2CL ; clear interrupt flag
|
||||
|
||||
@ -173,10 +199,13 @@ scancode_handler: .res 2
|
||||
rol ; C -> bit 0, startbit -> C
|
||||
Reverse A
|
||||
sta scancode
|
||||
CalculateOddParity
|
||||
eor key_read+1 ; if bit 0 is 1 - parity error
|
||||
and #1 ; bit 1 is still D7
|
||||
bne @parity_error
|
||||
|
||||
; check parity
|
||||
; CalculateOddParity
|
||||
; 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
|
||||
bit status
|
||||
bcc @status_not_receive_keys
|
||||
@ -198,15 +227,15 @@ scancode_handler: .res 2
|
||||
;; @function Send a command to the keyboard
|
||||
;; @modifies: A,X,Y
|
||||
;; @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
|
||||
ldy status
|
||||
sty prev_status
|
||||
ldy #ps2kb::STATUS::SEND_CMD
|
||||
sty status
|
||||
sta send_cmd ; store if it needs to be resent
|
||||
cpx #0
|
||||
beq @jmp_send_byte
|
||||
@store_data:
|
||||
stx send_data
|
||||
@jmp_send_byte:
|
||||
jmp _send_byte
|
||||
.endproc
|
||||
|
||||
@ -217,36 +246,51 @@ scancode_handler: .res 2
|
||||
;; @param A: The byte to send
|
||||
;; @details
|
||||
;; - pull clock low to stop keyboard transmissions
|
||||
;; - setup shift register to shift out
|
||||
;; - put startbit + D0-6 in shift register
|
||||
;; - store D7 + parity + stopbit in memory
|
||||
;; - TODO setup SR and T2 interrupt handlers
|
||||
;; - setup SR to shift out
|
||||
;; - pull data low (by shifting out a zero)
|
||||
;; - reset SR
|
||||
;; - put (reversed) byte in SR
|
||||
;; - put parity + stopbit(s) in send_last_bits variable
|
||||
;; - setup interrupt handlers
|
||||
;; - enable clock
|
||||
;;********************************************************************************
|
||||
.proc _send_byte
|
||||
pha
|
||||
IO_DisableIRQ ps2kb::VIA, IO::IRQ::T2
|
||||
IO_DisableIRQ ps2kb::VIA, (IO::IRQ::T2 | IO::IRQ::SR)
|
||||
|
||||
_DisableClock
|
||||
; (re)set shift register to shift out under external clock on CB1
|
||||
|
||||
; 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
|
||||
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
|
||||
Reverse A
|
||||
pha
|
||||
; split into the 11 bits
|
||||
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
|
||||
clc ; C = 0 (startbi)
|
||||
rol ; C -> bit 0, D7 -> C
|
||||
sta ps2kb::VIA + IO::SR
|
||||
txa
|
||||
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
|
||||
IO_EnableIRQ ps2kb::VIA, IO::IRQ::SR
|
||||
_EnableClock
|
||||
rts
|
||||
.endproc
|
||||
@ -262,17 +306,13 @@ scancode_handler: .res 2
|
||||
;; - start timer 2
|
||||
;;********************************************************************************
|
||||
.proc _send_irq_shift_reg_handler
|
||||
lda send_last_bits
|
||||
lda ps2kb::send_last_bits
|
||||
sta ps2kb::VIA + IO::SR
|
||||
|
||||
; disable SR interrupts
|
||||
lda #IO::IRQ::SR
|
||||
sta ps2kb::VIA + IO::IER
|
||||
; enable timer interrupts
|
||||
lda #(IO::IRQ::IRQ | IO::IRQ::T2)
|
||||
sta ps2kb::VIA + IO::IER
|
||||
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
|
||||
lda #>ps2kb::TIMER_SEND
|
||||
sta ps2kb::VIA + IO::T2CH
|
||||
rts
|
||||
.endproc
|
||||
@ -293,21 +333,20 @@ scancode_handler: .res 2
|
||||
.proc _send_irq_timer_handler
|
||||
lda ps2kb::VIA + IO::T2CL ; clear interrupt flag
|
||||
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
|
||||
stz send_data
|
||||
stz ps2kb::send_data
|
||||
jmp _send_byte
|
||||
rts
|
||||
@receive:
|
||||
_DisableClock ; disable keyboard while setting up receive
|
||||
lda #ps2kb::STATUS::RECEIVE_ANSWER
|
||||
sta status
|
||||
jmp begin_receive
|
||||
sta ps2kb::status
|
||||
jmp ps2kb::begin_receive
|
||||
.endproc
|
||||
|
||||
|
||||
.proc _process_cmd_answer
|
||||
@success:
|
||||
rts
|
||||
jmp ($3200)
|
||||
.endproc
|
||||
|
@ -98,15 +98,15 @@ INCLUDE_UTILITY = 1
|
||||
.macro JsrIndirect addr,ret_addr
|
||||
; -1 because rts increments it
|
||||
.if .blank(ret_addr)
|
||||
lda #<(:+ - 1)
|
||||
pha
|
||||
lda #>(:+ - 1)
|
||||
pha
|
||||
.else
|
||||
lda #<(ret_addr -1)
|
||||
lda #<(:+ - 1)
|
||||
pha
|
||||
.else
|
||||
lda #>(ret_addr -1)
|
||||
pha
|
||||
lda #<(ret_addr -1)
|
||||
pha
|
||||
.endif
|
||||
jmp addr
|
||||
.if .blank(ret_addr)
|
||||
|
Loading…
Reference in New Issue
Block a user