; ============================================================================
|
; ============================================================================
|
; __
|
; __
|
; \\__/ o\ (C) 2013-2022 Robert Finch, Waterloo
|
; \\__/ o\ (C) 2013-2022 Robert Finch, Waterloo
|
; \ __ / All rights reserved.
|
; \ __ / All rights reserved.
|
; \/_// robfinch@opencores.org
|
; \/_// robfinch@opencores.org
|
; ||
|
; ||
|
;
|
;
|
;
|
;
|
; Keyboard driver routines to interface to a PS2 style keyboard
|
; Keyboard driver routines to interface to a PS2 style keyboard
|
; Converts the scancode to ascii
|
; Converts the scancode to ascii
|
;
|
;
|
; This source file is free software: you can redistribute it and/or modify
|
; This source file is free software: you can redistribute it and/or modify
|
; it under the terms of the GNU Lesser General Public License as published
|
; it under the terms of the GNU Lesser General Public License as published
|
; by the Free Software Foundation, either version 3 of the License, or
|
; by the Free Software Foundation, either version 3 of the License, or
|
; (at your option) any later version.
|
; (at your option) any later version.
|
;
|
;
|
; This source file is distributed in the hope that it will be useful,
|
; This source file is distributed in the hope that it will be useful,
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
; GNU General Public License for more details.
|
; GNU General Public License for more details.
|
;
|
;
|
; You should have received a copy of the GNU General Public License
|
; You should have received a copy of the GNU General Public License
|
; along with this program. If not, see .
|
; along with this program. If not, see .
|
;
|
;
|
; ============================================================================
|
; ============================================================================
|
;
|
;
|
SC_F12 EQU $07
|
SC_F12 EQU $07
|
SC_C EQU $21
|
SC_C EQU $21
|
SC_T EQU $2C
|
SC_T EQU $2C
|
SC_Z EQU $1A
|
SC_Z EQU $1A
|
SC_DEL EQU $71 ; extend
|
SC_DEL EQU $71 ; extend
|
SC_KEYUP EQU $F0 ; should be $f0
|
SC_KEYUP EQU $F0 ; should be $f0
|
SC_EXTEND EQU $E0
|
SC_EXTEND EQU $E0
|
SC_CTRL EQU $14
|
SC_CTRL EQU $14
|
SC_RSHIFT EQU $59
|
SC_RSHIFT EQU $59
|
SC_NUMLOCK EQU $77
|
SC_NUMLOCK EQU $77
|
SC_SCROLLLOCK EQU $7E
|
SC_SCROLLLOCK EQU $7E
|
SC_CAPSLOCK EQU $58
|
SC_CAPSLOCK EQU $58
|
SC_ALT EQU $11
|
SC_ALT EQU $11
|
|
|
;#define SC_LSHIFT EQU $12
|
;#define SC_LSHIFT EQU $12
|
;SC_DEL EQU $71 ; extend
|
;SC_DEL EQU $71 ; extend
|
;SC_LCTRL EQU $58
|
;SC_LCTRL EQU $58
|
|
|
SC_TAB EQU $0D
|
SC_TAB EQU $0D
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Recieve a byte from the keyboard, used after a command is sent to the
|
; Recieve a byte from the keyboard, used after a command is sent to the
|
; keyboard in order to wait for a response.
|
; keyboard in order to wait for a response.
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: accd = recieved byte ($00 to $FF), -1 on timeout
|
; Returns: accd = recieved byte ($00 to $FF), -1 on timeout
|
; Modifies: acc
|
; Modifies: acc
|
; Stack Space: 2 words
|
; Stack Space: 2 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdRecvByte:
|
KeybdRecvByte:
|
pshs x
|
pshs x
|
ldx #100 ; wait up to 1s
|
ldx #100 ; wait up to 1s
|
krb3:
|
krb3:
|
bsr KeybdGetStatus ; wait for response from keyboard
|
bsr KeybdGetStatus ; wait for response from keyboard
|
tstb
|
tstb
|
bmi krb4 ; is input buffer full ? yes, branch
|
bmi krb4 ; is input buffer full ? yes, branch
|
bsr Wait10ms ; wait a bit
|
bsr Wait10ms ; wait a bit
|
dex
|
dex
|
bne krb3 ; go back and try again
|
bne krb3 ; go back and try again
|
ldd #-1 ; return -1
|
ldd #-1 ; return -1
|
puls x,pc
|
puls x,pc
|
krb4:
|
krb4:
|
bsr KeybdGetScancode
|
bsr KeybdGetScancode
|
puls x,pc
|
puls x,pc
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Send a byte to the keyboard.
|
; Send a byte to the keyboard.
|
;
|
;
|
; Parameters: accb byte to send
|
; Parameters: accb byte to send
|
; Returns: none
|
; Returns: none
|
; Modifies: none
|
; Modifies: none
|
; Stack Space: 0 words
|
; Stack Space: 0 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdSendByte:
|
KeybdSendByte:
|
stb KEYBD
|
stb KEYBD
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Wait until the keyboard transmit is complete
|
; Wait until the keyboard transmit is complete
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: r1 = 0 if successful, r1 = -1 timeout
|
; Returns: r1 = 0 if successful, r1 = -1 timeout
|
; Modifies: r1
|
; Modifies: r1
|
; Stack Space: 3 words
|
; Stack Space: 3 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdWaitTx:
|
KeybdWaitTx:
|
pshs x
|
pshs x
|
ldx #100 ; wait a max of 1s
|
ldx #100 ; wait a max of 1s
|
kwt1:
|
kwt1:
|
bsr KeybdGetStatus
|
bsr KeybdGetStatus
|
andb #$40 ; check for transmit complete bit; branch if bit set
|
andb #$40 ; check for transmit complete bit; branch if bit set
|
bne kwt2
|
bne kwt2
|
bsr Wait10ms ; delay a little bit
|
bsr Wait10ms ; delay a little bit
|
dex
|
dex
|
bne kwt1 ; go back and try again
|
bne kwt1 ; go back and try again
|
ldd #-1 ; timed out, return -1
|
ldd #-1 ; timed out, return -1
|
puls x,pc
|
puls x,pc
|
kwt2:
|
kwt2:
|
clra ; wait complete, return 0
|
clra ; wait complete, return 0
|
clrb
|
clrb
|
puls x,pc
|
puls x,pc
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Wait for 10 ms
|
; Wait for 10 ms
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: none
|
; Returns: none
|
; Modifies: none
|
; Modifies: none
|
; Stack Space: 2 words
|
; Stack Space: 2 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
Wait10ms:
|
Wait10ms:
|
pshs d
|
pshs d
|
lda MSCOUNT+3
|
lda MSCOUNT+3
|
W10_0001:
|
W10_0001:
|
tfr a,b
|
tfr a,b
|
subb MSCOUNT+3
|
subb MSCOUNT+3
|
cmpb #$FFA
|
cmpb #$FFA
|
bhi W10_0001
|
bhi W10_0001
|
puls d,pc
|
puls d,pc
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Wait for 300 ms (256 ms)
|
; Wait for 300 ms (256 ms)
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: none
|
; Returns: none
|
; Modifies: none
|
; Modifies: none
|
; Stack Space: 2 words
|
; Stack Space: 2 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
Wait300ms:
|
Wait300ms:
|
pshs d
|
pshs d
|
lda MSCOUNT+3
|
lda MSCOUNT+3
|
W300_0001:
|
W300_0001:
|
tfr a,b
|
tfr a,b
|
subb MSCOUNT+3
|
subb MSCOUNT+3
|
cmpb #$F00
|
cmpb #$F00
|
bhi W300_0001
|
bhi W300_0001
|
puls d,pc
|
puls d,pc
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Get the keyboard status
|
; Get the keyboard status
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: d = status
|
; Returns: d = status
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdGetStatus:
|
KeybdGetStatus:
|
kbgs3:
|
kbgs3:
|
ldb KEYBD+1
|
ldb KEYBD+1
|
bitb #$80
|
bitb #$80
|
bne kbgs1
|
bne kbgs1
|
bitb #$01 ; check parity error flag
|
bitb #$01 ; check parity error flag
|
bne kbgs2
|
bne kbgs2
|
clra
|
clra
|
rts
|
rts
|
kbgs2:
|
kbgs2:
|
ldb #$FE ; request resend
|
ldb #$FE ; request resend
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bra kbgs3
|
bra kbgs3
|
kbgs1: ; return negative status
|
kbgs1: ; return negative status
|
orb #$F00
|
orb #$F00
|
lda #-1
|
lda #-1
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Get the scancode from the keyboard port
|
; Get the scancode from the keyboard port
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: acca = scancode
|
; Returns: acca = scancode
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdGetScancode:
|
KeybdGetScancode:
|
clra
|
clra
|
ldb KEYBD ; get the scan code
|
ldb KEYBD ; get the scan code
|
clr KEYBD+1 ; clear receive register (write $00 to status reg)
|
clr KEYBD+1 ; clear receive register (write $00 to status reg)
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Set the LEDs on the keyboard.
|
; Set the LEDs on the keyboard.
|
;
|
;
|
; Parameters: d LED status to set
|
; Parameters: d LED status to set
|
; Returns: none
|
; Returns: none
|
; Modifies: none
|
; Modifies: none
|
; Stack Space: 2 words
|
; Stack Space: 2 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdSetLED:
|
KeybdSetLED:
|
pshs b
|
pshs b
|
ldb #$ED ; set LEDs command
|
ldb #$ED ; set LEDs command
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bsr KeybdRecvByte ; should be an ack
|
bsr KeybdRecvByte ; should be an ack
|
puls b
|
puls b
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bsr KeybdRecvByte ; should be an ack
|
bsr KeybdRecvByte ; should be an ack
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Get ID - get the keyboards identifier code.
|
; Get ID - get the keyboards identifier code.
|
;
|
;
|
; Parameters: none
|
; Parameters: none
|
; Returns: d = $AB83, $00 on fail
|
; Returns: d = $AB83, $00 on fail
|
; Modifies: d, KeybdID updated
|
; Modifies: d, KeybdID updated
|
; Stack Space: 2 words
|
; Stack Space: 2 words
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdGetID:
|
KeybdGetID:
|
ldb #$F2
|
ldb #$F2
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
bsr KeybdRecvByte
|
bsr KeybdRecvByte
|
bitb #$80
|
bitb #$80
|
bne kgnotKbd
|
bne kgnotKbd
|
cmpb #$AB
|
cmpb #$AB
|
bne kgnotKbd
|
bne kgnotKbd
|
bsr KeybdRecvByte
|
bsr KeybdRecvByte
|
bitb #$80
|
bitb #$80
|
bne kgnotKbd
|
bne kgnotKbd
|
cmpb #$83
|
cmpb #$83
|
bne kgnotKbd
|
bne kgnotKbd
|
ldd #$AB83
|
ldd #$AB83
|
kgid1:
|
kgid1:
|
std KeybdID
|
std KeybdID
|
rts
|
rts
|
kgnotKbd:
|
kgnotKbd:
|
clra
|
clra
|
clrb
|
clrb
|
bra kgid1
|
bra kgid1
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Initialize the keyboard.
|
; Initialize the keyboard.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; none
|
; none
|
; Modifies:
|
; Modifies:
|
; none
|
; none
|
; Returns:
|
; Returns:
|
; none
|
; none
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdInit:
|
KeybdInit:
|
pshs d,y
|
pshs d,y
|
ldy #5
|
ldy #5
|
clr KeyState1 ; records key up/down state
|
clr KeyState1 ; records key up/down state
|
clr KeyState2 ; records shift,ctrl,alt state
|
clr KeyState2 ; records shift,ctrl,alt state
|
kbdi0002:
|
kbdi0002:
|
bsr Wait10ms
|
bsr Wait10ms
|
clr KEYBD+1 ; clear receive register (write $00 to status reg)
|
clr KEYBD+1 ; clear receive register (write $00 to status reg)
|
ldb #-1 ; send reset code to keyboard
|
ldb #-1 ; send reset code to keyboard
|
stb KEYBD+1 ; write $FF to status reg to clear TX state
|
stb KEYBD+1 ; write $FF to status reg to clear TX state
|
bsr KeybdSendByte ; now write to transmit register
|
bsr KeybdSendByte ; now write to transmit register
|
bsr KeybdWaitTx ; wait until no longer busy
|
bsr KeybdWaitTx ; wait until no longer busy
|
bsr KeybdRecvByte ; look for an ACK ($FA)
|
bsr KeybdRecvByte ; look for an ACK ($FA)
|
cmpb #$FA
|
cmpb #$FA
|
bne kbdiTryAgain
|
bne kbdiTryAgain
|
bsr KeybdRecvByte ; look for BAT completion code ($AA)
|
bsr KeybdRecvByte ; look for BAT completion code ($AA)
|
cmpb #$FC ; reset error ?
|
cmpb #$FC ; reset error ?
|
beq kbdiTryAgain
|
beq kbdiTryAgain
|
cmpb #$AA ; reset complete okay ?
|
cmpb #$AA ; reset complete okay ?
|
bne kbdiTryAgain
|
bne kbdiTryAgain
|
|
|
; After a reset, scan code set #2 should be active
|
; After a reset, scan code set #2 should be active
|
.config:
|
.config:
|
ldb #$F0 ; send scan code select
|
ldb #$F0 ; send scan code select
|
stb LEDS
|
stb LEDS
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
tstb
|
tstb
|
bmi kbdiTryAgain
|
bmi kbdiTryAgain
|
bsr KeybdRecvByte ; wait for response from keyboard
|
bsr KeybdRecvByte ; wait for response from keyboard
|
tsta
|
tsta
|
bmi kbdiTryAgain
|
bmi kbdiTryAgain
|
cmpb #$FA ; ACK
|
cmpb #$FA ; ACK
|
beq kbdi0004
|
beq kbdi0004
|
kbdiTryAgain:
|
kbdiTryAgain:
|
dey
|
dey
|
bne kbdi0002
|
bne kbdi0002
|
.keybdErr:
|
.keybdErr:
|
ldd #msgBadKeybd
|
ldd #msgBadKeybd
|
lbsr DisplayStringCRLF
|
lbsr DisplayStringCRLF
|
bra ledxit
|
bra ledxit
|
kbdi0004:
|
kbdi0004:
|
ldb #2 ; select scan code set #2
|
ldb #2 ; select scan code set #2
|
bsr KeybdSendByte
|
bsr KeybdSendByte
|
bsr KeybdWaitTx
|
bsr KeybdWaitTx
|
tstb
|
tstb
|
bmi kbdiTryAgain
|
bmi kbdiTryAgain
|
bsr KeybdRecvByte ; wait for response from keyboard
|
bsr KeybdRecvByte ; wait for response from keyboard
|
tsta
|
tsta
|
bmi kbdiTryAgain
|
bmi kbdiTryAgain
|
cmpb #$FA
|
cmpb #$FA
|
bne kbdiTryAgain
|
bne kbdiTryAgain
|
bsr KeybdGetID
|
bsr KeybdGetID
|
ledxit:
|
ledxit:
|
ldb #$07
|
ldb #$07
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
bsr Wait300ms
|
bsr Wait300ms
|
ldb #$00
|
ldb #$00
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
puls d,y,pc
|
puls d,y,pc
|
|
|
msgBadKeybd:
|
msgBadKeybd:
|
fcb "Keyboard error",0
|
fcb "Keyboard error",0
|
|
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
; Calculate number of character in input buffer
|
; Calculate number of character in input buffer
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; y = $Cn00000 where n is core id
|
; y = $Cn00000 where n is core id
|
; Returns:
|
; Returns:
|
; d = number of bytes in buffer.
|
; d = number of bytes in buffer.
|
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
|
|
kbdRcvCount:
|
kbdRcvCount:
|
clra
|
clra
|
ldb kbdTailRcv,y
|
ldb kbdTailRcv,y
|
subb kbdHeadRcv,y
|
subb kbdHeadRcv,y
|
bge krcXit
|
bge krcXit
|
ldb #$40
|
ldb #$40
|
subb kbdHeadRcv,y
|
subb kbdHeadRcv,y
|
addb kbdTailRcv,y
|
addb kbdTailRcv,y
|
krcXit:
|
krcXit:
|
rts
|
rts
|
|
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
KeybdIRQ:
|
KeybdIRQ:
|
lda KEYBD+1 ; check status
|
lda KEYBD+1 ; check status
|
bita #$80 ; was key pressed?
|
bita #$80 ; was key pressed?
|
beq notKbdIRQ ; if not, exit
|
beq notKbdIRQ ; if not, exit
|
ldb KEYBD ; get the scan code
|
ldb KEYBD ; get the scan code
|
clr KEYBD+1 ; clear receive register (write $00 to status reg)
|
clr KEYBD+1 ; clear receive register (write $00 to status reg)
|
pshs b ; save it off
|
pshs b ; save it off
|
lda IOFocusID ; compute core memory address $Cn0000
|
lda IOFocusID ; compute core memory address $Cn0000
|
clrb
|
clrb
|
asla
|
asla
|
asla
|
asla
|
asla
|
asla
|
asla
|
asla
|
ora #$C00 ; address $Cn0000
|
ora #$C00 ; address $Cn0000
|
tfr d,y ; y =
|
tfr d,y ; y =
|
bsr kbdRcvCount ; get count of scan codes in buffer
|
bsr kbdRcvCount ; get count of scan codes in buffer
|
cmpb #64 ; check if buffer full?
|
cmpb #64 ; check if buffer full?
|
bhs kbdBufFull ; if buffer full, ignore new keystroke
|
bhs kbdBufFull ; if buffer full, ignore new keystroke
|
tfr y,x ; compute fifo address
|
tfr y,x ; compute fifo address
|
ldb kbdTailRcv,y ; b = buffer index
|
ldb kbdTailRcv,y ; b = buffer index
|
puls a ; get back scancode
|
puls a ; get back scancode
|
leax kbdFifo,x ; x = base address for fifo
|
leax kbdFifo,x ; x = base address for fifo
|
sta b,x ; store in buffer
|
sta b,x ; store in buffer
|
incb ; increment buffer index
|
incb ; increment buffer index
|
andb #$3f ; wrap around at 64 chars
|
andb #$3f ; wrap around at 64 chars
|
stb kbdTailRcv,y ; update it
|
stb kbdTailRcv,y ; update it
|
lda #28 ; Keyboard is IRQ #28
|
lda #28 ; Keyboard is IRQ #28
|
sta IrqSource ; stuff a byte indicating the IRQ source for PEEK()
|
sta IrqSource ; stuff a byte indicating the IRQ source for PEEK()
|
notKbdIRQ:
|
notKbdIRQ:
|
rts
|
rts
|
kbdBufFull:
|
kbdBufFull:
|
leas 1,s ; get rid of saved scancode
|
leas 1,s ; get rid of saved scancode
|
rts
|
rts
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
DBGCheckForKey:
|
DBGCheckForKey:
|
bra KeybdGetStatus
|
bra KeybdGetStatus
|
|
|
|
|
; KeyState2 variable bit meanings
|
; KeyState2 variable bit meanings
|
;1176543210
|
;1176543210
|
; ||||||||+ = shift
|
; ||||||||+ = shift
|
; |||||||+- = alt
|
; |||||||+- = alt
|
; ||||||+-- = control
|
; ||||||+-- = control
|
; |||||+--- = numlock
|
; |||||+--- = numlock
|
; ||||+---- = capslock
|
; ||||+---- = capslock
|
; |||+----- = scrolllock
|
; |||+----- = scrolllock
|
; ||+------ =
|
; ||+------ =
|
; |+------- = "
|
; |+------- = "
|
; | = "
|
; | = "
|
; | = "
|
; | = "
|
; | = "
|
; | = "
|
; +-------- = extended
|
; +-------- = extended
|
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; Keyboard get routine.
|
; Keyboard get routine.
|
;
|
;
|
; The routine may get characters directly from the scancode input or less
|
; The routine may get characters directly from the scancode input or less
|
; directly from the scancode buffer, if things are interrupt driven.
|
; directly from the scancode buffer, if things are interrupt driven.
|
;
|
;
|
; Parameters:
|
; Parameters:
|
; b: bit 11 = blocking status 1=blocking, 0=non blocking
|
; b: bit 11 = blocking status 1=blocking, 0=non blocking
|
; b: bit 1 = scancode source 1=scancode buffer, 0=direct
|
; b: bit 1 = scancode source 1=scancode buffer, 0=direct
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
GetKey:
|
GetKey:
|
pshs x,y
|
pshs x,y
|
stb KeybdBlock ; save off blocking status
|
stb KeybdBlock ; save off blocking status
|
dbgk2:
|
dbgk2:
|
ldb KeybdBlock
|
ldb KeybdBlock
|
pshs b
|
pshs b
|
bitb #1 ; what is the scancode source
|
bitb #1 ; what is the scancode source
|
beq dbgk20 ; branch if direct read
|
beq dbgk20 ; branch if direct read
|
lda COREID ; compute core memory address
|
lda COREID ; compute core memory address
|
clrb
|
clrb
|
asla
|
asla
|
asla
|
asla
|
asla
|
asla
|
asla
|
asla
|
ora #$C00
|
ora #$C00
|
tfr d,y ; y = $Cn0000
|
tfr d,y ; y = $Cn0000
|
bsr kbdRcvCount
|
bsr kbdRcvCount
|
tstb ; anything in buffer?
|
tstb ; anything in buffer?
|
puls b
|
puls b
|
bne dbgk1 ; branch if something in buffer
|
bne dbgk1 ; branch if something in buffer
|
tstb
|
tstb
|
bmi dbgk2 ; if no key and blocking - loop
|
bmi dbgk2 ; if no key and blocking - loop
|
|
bra dbgk24
|
dbgk20:
|
dbgk20:
|
ldy #0
|
ldy #0
|
bsr KeybdGetStatus
|
bsr KeybdGetStatus
|
andb #$80 ; is key available?
|
andb #$80 ; is key available?
|
puls b
|
puls b
|
bne dbgk1 ; branch if key
|
bne dbgk1 ; branch if key
|
tstb ; block?
|
tstb ; block?
|
bmi dbgk2 ; If no key and blocking - loop
|
bmi dbgk2 ; If no key and blocking - loop
|
|
dbgk24:
|
ldd #-1 ; return -1 if no block and no key
|
ldd #-1 ; return -1 if no block and no key
|
puls x,pc
|
puls x,y,pc
|
dbgk1:
|
dbgk1:
|
cmpy #0
|
cmpy #0
|
bne dbgk22
|
bne dbgk22
|
bsr KeybdGetScancode ; get scancode directly
|
bsr KeybdGetScancode ; get scancode directly
|
bra dbgk23
|
bra dbgk23
|
dbgk22:
|
dbgk22:
|
; Retrieve value from scancode buffer
|
; Retrieve value from scancode buffer
|
tfr y,x
|
tfr y,x
|
leax kbdFifo,x ; x = fifo address
|
leax kbdFifo,x ; x = fifo address
|
ldb kbdHeadRcv,y ; b = buffer index
|
ldb kbdHeadRcv,y ; b = buffer index
|
lda b,x ; get the scancode
|
lda b,x ; get the scancode
|
incb ; increment fifo index
|
incb ; increment fifo index
|
andb #$3f ; and wrap around
|
andb #$3f ; and wrap around
|
stb kbdHeadRcv,y ; save it back
|
stb kbdHeadRcv,y ; save it back
|
tfr a,b ; the scancode is needed in accb
|
tfr a,b ; the scancode is needed in accb
|
dbgk23:
|
dbgk23:
|
; lbsr DispByteAsHex
|
; lbsr DispByteAsHex
|
; Make sure there is a small delay between scancode reads
|
; Make sure there is a small delay between scancode reads
|
ldx #20
|
ldx #20
|
dbgk3:
|
dbgk3:
|
dex
|
dex
|
bne dbgk3
|
bne dbgk3
|
; switch on scan code
|
; switch on scan code
|
cmpb #SC_KEYUP
|
cmpb #SC_KEYUP
|
bne dbgk4
|
bne dbgk4
|
stb KeyState1 ; make KeyState1 <> 0
|
stb KeyState1 ; make KeyState1 <> 0
|
bra dbgk2 ; loop back
|
bra dbgk2 ; loop back
|
dbgk4:
|
dbgk4:
|
cmpb #SC_EXTEND
|
cmpb #SC_EXTEND
|
bne dbgk5
|
bne dbgk5
|
lda KeyState2
|
lda KeyState2
|
ora #$800
|
ora #$800
|
sta KeyState2
|
sta KeyState2
|
bra dbgk2
|
bra dbgk2
|
dbgk5:
|
dbgk5:
|
cmpb #SC_CTRL
|
cmpb #SC_CTRL
|
bne dbgkNotCtrl
|
bne dbgkNotCtrl
|
tst KeyState1
|
tst KeyState1
|
bne dbgk7
|
bne dbgk7
|
lda KeyState2
|
lda KeyState2
|
ora #4
|
ora #4
|
sta KeyState2
|
sta KeyState2
|
bra dbgk8
|
bra dbgk8
|
dbgk7:
|
dbgk7:
|
lda KeyState2
|
lda KeyState2
|
anda #~4
|
anda #~4
|
sta KeyState2
|
sta KeyState2
|
dbgk8:
|
dbgk8:
|
clr KeyState1
|
clr KeyState1
|
bra dbgk2
|
bra dbgk2
|
dbgkNotCtrl:
|
dbgkNotCtrl:
|
cmpb #SC_RSHIFT
|
cmpb #SC_RSHIFT
|
bne dbgkNotRshift
|
bne dbgkNotRshift
|
tst KeyState1
|
tst KeyState1
|
bne dbgk9
|
bne dbgk9
|
lda KeyState2
|
lda KeyState2
|
ora #1
|
ora #1
|
sta KeyState2
|
sta KeyState2
|
bra dbgk10
|
bra dbgk10
|
dbgk9:
|
dbgk9:
|
lda KeyState2
|
lda KeyState2
|
anda #~1
|
anda #~1
|
sta KeyState2
|
sta KeyState2
|
dbgk10:
|
dbgk10:
|
clr KeyState1
|
clr KeyState1
|
bra dbgk2
|
bra dbgk2
|
dbgkNotRshift:
|
dbgkNotRshift:
|
cmpb #SC_NUMLOCK
|
cmpb #SC_NUMLOCK
|
bne dbgkNotNumlock
|
bne dbgkNotNumlock
|
lda KeyState2
|
lda KeyState2
|
eora #16
|
eora #16
|
sta KeyState2
|
sta KeyState2
|
lda KeyLED
|
lda KeyLED
|
eora #2
|
eora #2
|
sta KeyLED
|
sta KeyLED
|
tfr a,b
|
tfr a,b
|
clra
|
clra
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
bra dbgk2
|
bra dbgk2
|
dbgkNotNumlock:
|
dbgkNotNumlock:
|
cmpb #SC_CAPSLOCK
|
cmpb #SC_CAPSLOCK
|
bne dbgkNotCapslock
|
bne dbgkNotCapslock
|
lda KeyState2
|
lda KeyState2
|
eora #32
|
eora #32
|
sta KeyState2
|
sta KeyState2
|
lda KeyLED
|
lda KeyLED
|
eora #4
|
eora #4
|
sta KeyLED
|
sta KeyLED
|
tfr a,b
|
tfr a,b
|
clra
|
clra
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
bra dbgk2
|
bra dbgk2
|
dbgkNotCapslock:
|
dbgkNotCapslock:
|
cmpb #SC_SCROLLLOCK
|
cmpb #SC_SCROLLLOCK
|
bne dbgkNotScrolllock
|
bne dbgkNotScrolllock
|
lda KeyState2
|
lda KeyState2
|
eora #64
|
eora #64
|
sta KeyState2
|
sta KeyState2
|
lda KeyLED
|
lda KeyLED
|
eora #1
|
eora #1
|
sta KeyLED
|
sta KeyLED
|
tfr a,b
|
tfr a,b
|
clra
|
clra
|
bsr KeybdSetLED
|
bsr KeybdSetLED
|
bra dbgk2
|
bra dbgk2
|
dbgkNotScrolllock:
|
dbgkNotScrolllock:
|
cmpb #SC_ALT
|
cmpb #SC_ALT
|
bne dbgkNotAlt
|
bne dbgkNotAlt
|
tst KeyState1
|
tst KeyState1
|
bne dbgk11
|
bne dbgk11
|
lda KeyState2
|
lda KeyState2
|
ora #2
|
ora #2
|
sta KeyState2
|
sta KeyState2
|
bra dbgk12
|
bra dbgk12
|
dbgk11:
|
dbgk11:
|
lda KeyState2
|
lda KeyState2
|
anda #~2
|
anda #~2
|
sta KeyState2
|
sta KeyState2
|
dbgk12:
|
dbgk12:
|
clr KeyState1
|
clr KeyState1
|
bra dbgk2
|
bra dbgk2
|
dbgkNotAlt:
|
dbgkNotAlt:
|
tst KeyState1
|
tst KeyState1
|
beq dbgk13
|
beq dbgk13
|
clr KeyState1
|
clr KeyState1
|
bra dbgk2
|
bra dbgk2
|
dbgk13:
|
dbgk13:
|
lda KeyState2 ; Check for CTRL-ALT-DEL
|
lda KeyState2 ; Check for CTRL-ALT-DEL
|
anda #6
|
anda #6
|
cmpa #6
|
cmpa #6
|
bne dbgk14
|
bne dbgk14
|
cmpb #SC_DEL
|
cmpb #SC_DEL
|
bne dbgk14
|
bne dbgk14
|
jmp [$FFFFFC] ; jump to NMI vector
|
jmp [$FFFFFC] ; jump to NMI vector
|
dbgk14:
|
dbgk14:
|
tst KeyState2 ; extended code?
|
tst KeyState2 ; extended code?
|
bpl dbgk15
|
bpl dbgk15
|
lda KeyState2
|
lda KeyState2
|
anda #$7FF
|
anda #$7FF
|
sta KeyState2
|
sta KeyState2
|
ldx #keybdExtendedCodes
|
ldx #keybdExtendedCodes
|
bra dbgk18
|
bra dbgk18
|
dbgk15:
|
dbgk15:
|
lda KeyState2 ; Is CTRL down?
|
lda KeyState2 ; Is CTRL down?
|
bita #4
|
bita #4
|
beq dbgk16
|
beq dbgk16
|
ldx #keybdControlCodes
|
ldx #keybdControlCodes
|
bra dbgk18
|
bra dbgk18
|
dbgk16:
|
dbgk16:
|
bita #1 ; Is shift down?
|
bita #1 ; Is shift down?
|
beq dbgk17
|
beq dbgk17
|
ldx #shiftedScanCodes
|
ldx #shiftedScanCodes
|
bra dbgk18
|
bra dbgk18
|
dbgk17:
|
dbgk17:
|
ldx #unshiftedScanCodes
|
ldx #unshiftedScanCodes
|
dbgk18:
|
dbgk18:
|
ldb b,x ; load accb with ascii from table
|
ldb b,x ; load accb with ascii from table
|
clra
|
clra
|
puls x,y,pc ; and return
|
puls x,y,pc ; and return
|
|
|