URL
https://opencores.org/ocsvn/rf6809/rf6809/trunk
Subversion Repositories rf6809
[/] [rf6809/] [trunk/] [software/] [boot/] [keyboard.asm] - Rev 8
Go to most recent revision | Compare with Previous | Blame | View Log
; ============================================================================; __; \\__/ o\ (C) 2013-2022 Robert Finch, Waterloo; \ __ / All rights reserved.; \/_// robfinch<remove>@opencores.org; ||;;; Keyboard driver routines to interface to a PS2 style keyboard; Converts the scancode to ascii;; 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; by the Free Software Foundation, either version 3 of the License, or; (at your option) any later version.;; This source file is distributed in the hope that it will be useful,; but WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License; along with this program. If not, see <http://www.gnu.org/licenses/>.;; ============================================================================;SC_F12 EQU $07SC_C EQU $21SC_T EQU $2CSC_Z EQU $1ASC_DEL EQU $71 ; extendSC_KEYUP EQU $F0 ; should be $f0SC_EXTEND EQU $E0SC_CTRL EQU $14SC_RSHIFT EQU $59SC_NUMLOCK EQU $77SC_SCROLLLOCK EQU $7ESC_CAPSLOCK EQU $58SC_ALT EQU $11;#define SC_LSHIFT EQU $12;SC_DEL EQU $71 ; extend;SC_LCTRL EQU $58SC_TAB EQU $0D; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Recieve a byte from the keyboard, used after a command is sent to the; keyboard in order to wait for a response.;; Parameters: none; Returns: accd = recieved byte ($00 to $FF), -1 on timeout; Modifies: acc; Stack Space: 2 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdRecvByte:pshs xldx #100 ; wait up to 1skrb3:bsr KeybdGetStatus ; wait for response from keyboardtstbbmi krb4 ; is input buffer full ? yes, branchbsr Wait10ms ; wait a bitleax -1,xbne krb3 ; go back and try againldd #-1 ; return -1puls x,pckrb4:bsr KeybdGetScancodepuls x,pc; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Send a byte to the keyboard.;; Parameters: accb byte to send; Returns: none; Modifies: none; Stack Space: 0 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdSendByte:stb KEYBDrts; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Wait until the keyboard transmit is complete;; Parameters: none; Returns: r1 = 0 if successful, r1 = -1 timeout; Modifies: r1; Stack Space: 3 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdWaitTx:pshs xldx #100 ; wait a max of 1skwt1:bsr KeybdGetStatusandb #$40 ; check for transmit complete bit; branch if bit setbne kwt2bsr Wait10ms ; delay a little bitleax -1,xbne kwt1 ; go back and try againldd #-1 ; timed out, return -1puls x,pckwt2:clra ; wait complete, return 0clrbpuls x,pc; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Wait for 10 ms;; Parameters: none; Returns: none; Modifies: none; Stack Space: 2 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Wait10ms:pshs dlda MSCOUNT+3W10_0001:tfr a,bsubb MSCOUNT+3cmpb #$FFAbhi W10_0001puls d,pc; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Wait for 300 ms (256 ms);; Parameters: none; Returns: none; Modifies: none; Stack Space: 2 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Wait300ms:pshs dlda MSCOUNT+3W300_0001:tfr a,bsubb MSCOUNT+3cmpb #$F00bhi W300_0001puls d,pc; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Get the keyboard status;; Parameters: none; Returns: d = status; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdGetStatus:kbgs3:ldb KEYBD+1bitb #$80bne kbgs1bitb #$01 ; check parity error flagbne kbgs2clrartskbgs2:ldb #$FE ; request resendbsr KeybdSendBytebsr KeybdWaitTxbra kbgs3kbgs1: ; return negative statusorb #$F00lda #-1rts; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Get the scancode from the keyboard port;; Parameters: none; Returns: acca = scancode; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdGetScancode:clraldb KEYBD ; get the scan codeclr KEYBD+1 ; clear receive register (write $00 to status reg); The following useful during debug.; lbsr DispByteAsHex; pshs b; ldb #' '; lbsr OUTCH; puls brts; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Set the LEDs on the keyboard.;; Parameters: d LED status to set; Returns: none; Modifies: none; Stack Space: 2 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdSetLED:pshs bldb #$ED ; set LEDs commandbsr KeybdSendBytebsr KeybdWaitTxbsr KeybdRecvByte ; should be an ackpuls bbsr KeybdSendBytebsr KeybdWaitTxbsr KeybdRecvByte ; should be an ackrts; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Get ID - get the keyboards identifier code.;; Parameters: none; Returns: d = $AB83, $00 on fail; Modifies: d, KeybdID updated; Stack Space: 2 words; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdGetID:ldb #$F2bsr KeybdSendBytebsr KeybdWaitTxbsr KeybdRecvBytebitb #$80bne kgnotKbdcmpb #$ABbne kgnotKbdbsr KeybdRecvBytebitb #$80bne kgnotKbdcmpb #$83bne kgnotKbdldd #$AB83kgid1:std KeybdIDrtskgnotKbd:clraclrbbra kgid1; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Initialize the keyboard.;; Parameters:; none; Modifies:; none; Returns:; none; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -KeybdInit:pshs d,yldy #5kbdi0002:bsr Wait10msclr KEYBD+1 ; clear receive register (write $00 to status reg)ldb #-1 ; send reset code to keyboardstb KEYBD+1 ; write $FF to status reg to clear TX statebsr KeybdSendByte ; now write to transmit registerbsr KeybdWaitTx ; wait until no longer busybsr KeybdRecvByte ; look for an ACK ($FA)cmpb #$FAbne kbdiTryAgainbsr KeybdRecvByte ; look for BAT completion code ($AA)cmpb #$FC ; reset error ?beq kbdiTryAgaincmpb #$AA ; reset complete okay ?bne kbdiTryAgain; After a reset, scan code set #2 should be active.config:ldb #$F0 ; send scan code selectstb LEDSbsr KeybdSendBytebsr KeybdWaitTxtstbbmi kbdiTryAgainbsr KeybdRecvByte ; wait for response from keyboardtstabmi kbdiTryAgaincmpb #$FA ; ACKbeq kbdi0004kbdiTryAgain:deybne kbdi0002.keybdErr:ldd #msgBadKeybdlbsr DisplayStringCRLFbra ledxitkbdi0004:ldb #2 ; select scan code set #2bsr KeybdSendBytebsr KeybdWaitTxtstbbmi kbdiTryAgainbsr KeybdRecvByte ; wait for response from keyboardtstabmi kbdiTryAgaincmpb #$FAbne kbdiTryAgainbsr KeybdGetIDledxit:ldb #$07bsr KeybdSetLEDbsr Wait300msldb #$00bsr KeybdSetLEDpuls d,y,pcmsgBadKeybd:fcb "Keyboard error",0; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -DBGCheckForKey:bra KeybdGetStatus; KeyState2 variable bit meanings;1176543210; ||||||||+ = shift; |||||||+- = alt; ||||||+-- = control; |||||+--- = numlock; ||||+---- = capslock; |||+----- = scrolllock; ||+------ = <empty>; |+------- = "; | = "; | = "; | = "; +-------- = extended; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Debug versison of keyboard get routine.;; Parameters:; b: 0 = non blocking, otherwise blocking; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -DBGGetKey:pshs xdbgk2:pshs bbsr KeybdGetStatusandb #$80 ; is key available?puls bbne dbgk1 ; branch if keytstb ; block?bne dbgk2 ; If no key and blocking - loopldd #-1 ; return -1 if no block and no keypuls x,pcdbgk1:bsr KeybdGetScancode; lbsr DispByteAsHex; Make sure there is a small delay between scancode readsldx #20dbgk3:dexbne dbgk3; switch on scan codecmpb #SC_KEYUPbne dbgk4clr KeyState1 ; make KeyState1 = -1neg KeyState1bra dbgk2 ; loop backdbgk4:cmpb #SC_EXTENDbne dbgk5lda KeyState2ora #$800sta KeyState2bra dbgk2dbgk5:cmpb #SC_CTRLbne dbgkNotCtrltst KeyState1bmi dbgk7lda KeyState2ora #4sta KeyState2bra dbgk8dbgk7:lda KeyState2anda #~4sta KeyState2dbgk8:clr KeyState1bra dbgk2dbgkNotCtrl:cmpb #SC_RSHIFTbne dbgkNotRshifttst KeyState1bmi dbgk9lda KeyState2ora #1sta KeyState2bra dbgk10dbgk9:lda KeyState2anda #~1sta KeyState2dbgk10:clr KeyState1bra dbgk2dbgkNotRshift:cmpb #SC_NUMLOCKbne dbgkNotNumlocklda KeyState2eora #16sta KeyState2lda KeyLEDeora #2sta KeyLEDtfr a,bclrabsr KeybdSetLEDbra dbgk2dbgkNotNumlock:cmpb #SC_CAPSLOCKbne dbgkNotCapslocklda KeyState2eora #32sta KeyState2lda KeyLEDeora #4sta KeyLEDtfr a,bclrabsr KeybdSetLEDbra dbgk2dbgkNotCapslock:cmpb #SC_SCROLLLOCKbne dbgkNotScrolllocklda KeyState2eora #64sta KeyState2lda KeyLEDeora #1sta KeyLEDtfr a,bclrabsr KeybdSetLEDbra dbgk2dbgkNotScrolllock:cmpb #SC_ALTbne dbgkNotAlttst KeyState1bmi dbgk11lda KeyState2ora #2sta KeyState2bra dbgk12dbgk11:lda KeyState2anda #~2sta KeyState2dbgk12:clr KeyState1bra dbgk2dbgkNotAlt:tst KeyState1beq dbgk13clr KeyState1bra dbgk2dbgk13:lda KeyState2 ; Check for CTRL-ALT-DELanda #6cmpa #6bne dbgk14cmpb #SC_DELbne dbgk14jmp [$FFFFFE] ; jump to reset vectordbgk14:tst KeyState2 ; extended code?bpl dbgk15lda KeyState2anda #$7FFsta KeyState2ldx #keybdExtendedCodesbra dbgk18dbgk15:lda KeyState2 ; Is CTRL down?bita #4beq dbgk16ldx #keybdControlCodesbra dbgk18dbgk16:bita #1 ; Is shift down?beq dbgk17ldx #shiftedScanCodesbra dbgk18dbgk17:ldx #unshiftedScanCodesdbgk18:abxldb ,xclrapuls x,pc ; and return
Go to most recent revision | Compare with Previous | Blame | View Log
