; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; > KbdResA1 ; This file contains all the old-style keyboard control stuff that the kernel does on reset ; The only two hooks in this file used externally are IRQ_Test_CTRL_or_R_Pressed ; and SetUpKbd. GBLL KeyboardDebungling KeyboardDebungling SETL {FALSE} ; reset code needs to know where CTRL, SHIFT and R are in the kbd matrix ; these are codes given by the keyboard [ Keyboard_Type = "A1A500" A1CtrlLeft * &3B A1CtrlRight * &61 A1ShiftLeft * &4C A1ShiftRight * &58 A1CTRLLCol * K1kdda + (A1CtrlLeft :AND: 15) A1CTRLLRow * K1kdda + (A1CtrlLeft :SHR: 4) A1CTRLRCol * K1kdda + (A1CtrlRight :AND: 15) A1CTRLRRow * K1kdda + (A1CtrlRight :SHR: 4) A1SHIFTLCol * K1kdda + (A1ShiftLeft :AND: 15) A1SHIFTLRow * K1kdda + (A1ShiftLeft :SHR: 4) A1SHIFTRCol * K1kdda + (A1ShiftRight :AND: 15) A1SHIFTRRow * K1kdda + (A1ShiftRight :SHR: 4) A1R_Col * K1kdda + 10 A1R_Row * K1kdda + 2 A1T_Col * K1kdda + 11 A1T_Row * K1kdda + 2 A1Del_Col * K1kdda + 4 A1Del_Row * K1kdda + 3 A1Copy_Col * K1kdda + 5 A1Copy_Row * K1kdda + 3 ] [ Keyboard_Type = "A1A500" ; old (A500) keyboard positions A500CTRLRow * KEYDOWN + &C A500CTRLCol * KEYDOWN + 0 A500SHIFTRow * KEYDOWN + &A A500SHIFTCol * KEYDOWN + 0 A500R_Row * KEYDOWN + 2 A500R_Col * KEYDOWN + 7 A500T_Row * KEYDOWN + 2 A500T_Col * KEYDOWN + 6 A500Del_Row * KEYDOWN + 5 A500Del_Col * KEYDOWN + 7 A500Copy_Row * KEYDOWN + 0 A500Copy_Col * KEYDOWN + 8 ] ; On ARM600, this routine must work in IRQ32 mode IRQ_Test_CTRL_or_R_Pressed ROUT Push "r0-r2, R10-R12, lr" MOV R12, #IOC MOV r2, #IOC MOV r0, #32 BL DoMicroDelay ; quick thumb twiddle until it's REALLY there LDRB R11, KARTRx ; read byte transmitted by keyboard [ KeyboardDebungling Push R12 MOV R12, R11, LSR #4 TubeChar R10, R11, "MOV R11, #""R""" TubeChar R10, R11, "ADD R11, R12, #""0""" AND R12, R11, #&F TubeChar R10, R11, "ADD R11, R12, #""0""" Pull R12 ] CMP R11, #HRDRESET ; first check for part of reset sequence and reply accordingly BEQ fartaboutfornewkbd CMP R11, #RST1ACK MOVEQ R10, #RST2ACK BEQ send_ack_byte CMP R11, #RST2ACK BNE keytransmission MOV R10, #InitKbdWs LDR R10, [R10, #KeyDataPtr] CMP R10, #0 MOVNE R10, #ACK+SCAN BNE send_ack_byte MOV R10, #ACK [ KeyboardDebungling Push R12 MOV R12, R10, LSR #4 TubeChar R10, R11, "MOV R11, #""k""" TubeChar R10, R11, "ADD R11, R12, #""0""" AND R12, R10, #&F TubeChar R10, R11, "ADD R11, R12, #""0""" Pull R12 ] STRB R10, KARTTx BL PollTxBit MOV R11, #K1rqid BL SendAndPollRxBit [ Keyboard_Type = "A1A500" AND r10, r11, #&F0 CMP R11, #IDTYPE ; a500 kbd? ADREQ R10, DataA500Kbd BEQ gotkbdid ] SUB r11, r11, #K1kbid + 1 CMP r11, #30 ADRLSL R10, DataA1Kbd ; only accept ID 1-31 MOVHI R10, #0 ; else don't know gotkbdid MOV R11, #InitKbdWs STR R10, [R11, #KeyDataPtr] [ Keyboard_Type = "A1A500" ASSERT (DataA1Kbd :AND: 255) <> 0 ] [ Keyboard_Type = "A1A500" ASSERT (DataA500Kbd :AND: 255) <> 0 ] STRB R10, [R11, #KB_There_Flag] ; only there once ID understood MOV R10, #HRDRESET ; and from the top B send_ack_byte keytransmission ; assume it's key info MOV R10, #InitKbdWs LDRB R10, [R10] ; the "had a byte" flag CMP R10, #0 BNE hadabyteofkey MOV R10, #InitKbdWs STRB R11, [R10] ; first part of 2 byte protocol: set flag MOV R10, #ACK+&F B send_ack_byte fartaboutfornewkbd kickitagain MOV R11, #HRDRESET BL SendAndPollRxBit ; get a byte to R11 BL PollTxBit CMP R11, #HRDRESET BNE kickitagain MOV R11, #RST1ACK BL SendAndPollRxBit ; get a byte to R11 BL PollTxBit CMP R11, #RST1ACK BNE kickitagain MOV R10, #RST2ACK B send_ack_byte hadabyteofkey ; now got 1st byte in R10, second byte in R11 : test for CTRL or R MOV R0, #InitKbdWs LDR R0, [R0, #KeyDataPtr] 10 LDRB R1, [R0], #1 CMP R1, #0 BEQ %FT11 CMP R1, R10 LDRB R1, [R0], #1 CMPEQ R1, R11 LDRB R1, [R0], #1 BNE %BT10 MOV R11, #InitKbdWs STRB R1, [R11, R1] ; non-zero means pressed 11 MOV R10, #ACK+SCAN send_ack_byte [ KeyboardDebungling Push R12 MOV R12, R10, LSR #4 TubeChar R10, R11, "MOV R11, #""T""" TubeChar R10, R11, "ADD R11, R12, #""0""" AND R12, R10, #&F TubeChar R10, R11, "ADD R11, R12, #""0""" Pull R12 ] STRB R10, KARTTx ; assume always able to transmit? CMP R10, #ACK+&F MOVNE R11, #InitKbdWs STRNEB R11, [R11] ; clear "one byte of 2 byte seq had" flag Pull "r0-r2, R10-R12, lr" SUBS PC, R14, #4 DCD 0 ; temp fudge [ Keyboard_Type = "A1A500" [ . :AND: 255 = 0 DCB "S" ; Odd length, should throw us ] DataA1Kbd = A1CTRLLRow, A1CTRLLCol, CTRL_Down_Flag = A1CTRLRRow, A1CTRLRCol, CTRL_Down_Flag = A1SHIFTRRow, A1SHIFTRCol, SHIFT_Down_Flag = A1SHIFTLRow, A1SHIFTLCol, SHIFT_Down_Flag = A1R_Row, A1R_Col, R_Down_Flag = A1T_Row, A1T_Col, T_Down_Flag = A1Del_Row, A1Del_Col, Del_Down_Flag = A1Copy_Row, A1Copy_Col, Copy_Down_Flag = 0 ] [ Keyboard_Type = "A1A500" [ . :AND: 255 = 0 DCB "K" ] DataA500Kbd = A500CTRLRow, A500CTRLCol, CTRL_Down_Flag = A500SHIFTRow, A500SHIFTCol, SHIFT_Down_Flag = A500R_Row, A500R_Col, R_Down_Flag = A500T_Row, A500T_Col, T_Down_Flag = A500Del_Row, A500Del_Col, Del_Down_Flag = A500Copy_Row, A500Copy_Col, Copy_Down_Flag = 0 ] ALIGN LTORG PollTxBit ROUT 01 LDRB R10, [R12, #IOCIRQSTAB] TST R10, #KARTTxBit BEQ %BT01 MOV pc, lr SendAndPollRxBit ROUT Push lr [ KeyboardDebungling Push R12 MOV R12, R11, LSR #4 TubeChar R10, R11, "MOV R11, #""t""" TubeChar R10, R11, "ADD R11, R12, #""0""" AND R12, R11, #&F TubeChar R10, R11, "ADD R11, R12, #""0""" Pull R12 ] STRB R11, KARTTx 01 LDRB R10, [R12, #IOCIRQSTAB] TST R10, #KARTRxBit BEQ %BT01 MOV r2, #IOC MOV r0, #32 BL DoMicroDelay LDRB R11, KARTRx ; purge KART, or get reply [ KeyboardDebungling Push R12 MOV R12, R11, LSR #4 TubeChar R10, R11, "MOV R11, #""r""" TubeChar R10, R11, "ADD R11, R12, #""0""" AND R12, R11, #&F TubeChar R10, R11, "ADD R11, R12, #""0""" Pull R12 ] Pull pc ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SetUpKbd ; set up keyboard: initialise baud rate, send dummy, read dummy MOV R12, #IOC ; code ripped off from pmf.Key MOV R0, #1 STRB R0, Timer3Low MOV R0, #0 STRB R0, Timer3High STRB R0, Timer3Go ; baud rate set and going STRB R0, KARTTx ; send dummy MOV r1, r13 MOV r13, #&8000 ; need a quick stack - scratchspace Push r1 ; probably the best bet. MOV r0, #&800*2 ; magic delay MOV r2, #IOC BL DoMicroDelay LDMFD r13, {r13} ; finished with stack LDRB R0, KARTRx ; ensure no wally byte in KARTRx BL PollTxBit MOV R0, #HRDRESET ; start reset protocol STRB R0, KARTTx B SetUpKbdReturn ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ KeyboardDebungling SETL {FALSE} END