; 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. ; ; > KbdResPC ; This file contains the minimal PC 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. ; For now, use development podule in slot 0. IOBase * IOMD_Base IOData * IOCSERTX IOStatus * IOMD_KBDCR IOControl * IOMD_KBDCR stat_RXF * IOMD_KBDCR_RxF stat_TXE * IOMD_KBDCR_TxE ctl_Enable * IOMD_KBDCR_Enable ctl_EnableIRQ * 0 ; not needed on IOMD ; PC keyboard codes we are interested in. PCReset * &AA PCSpecial * &E0 PCCTRLL * &14 PCCTRLR * &14 ; Preceded by &E0 PCSHIFTL * &12 PCSHIFTR * &59 PCR * &2D PCT * &2C PCDelete * &71 ; Preceded by &E0 PCBSpace * &66 PCEnd * &69 ; Preceded by &E0 KeyData DCB PCCTRLL, CTRL_Down_Flag DCB PCSHIFTL, SHIFT_Down_Flag DCB PCSHIFTR, SHIFT_Down_Flag DCB PCR, R_Down_Flag DCB PCT, T_Down_Flag DCB PCBSpace, Del_Down_Flag DCB 0 ALIGN SpecialData DCB PCCTRLR, CTRL_Down_Flag DCB PCDelete, Del_Down_Flag DCB PCEnd, Copy_Down_Flag DCB 0 ALIGN ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [ :LNOT HAL SetUpKbd MOV r0, #IOBase MOV r1, #ctl_Enable + ctl_EnableIRQ STRB r1, [r0, #IOControl] 10 LDRB r1, [r0, #IOStatus] TST r1, #stat_TXE MOVNE r1, #&FF STRNEB r1, [r0, #IOData] BEQ %BT10 [ MorrisSupport [ {TRUE} ; ARM7500FE support ; Change test to check for IOMD_Original, rather than IOMD_7500, so we include IOMD_7500FE ; in the latter category LDRB r1, [r0, #IOMD_ID0] LDRB r2, [r0, #IOMD_ID1] ; safe to use r2, since SetUpKbdReturn corrupts it ORR r1, r1, r2, LSL #8 ; straight away LDR r2, =IOMD_Original TEQ r1, r2 BEQ %FT30 | LDRB R1, [R0, #IOMD_ID0] ;Are we running on Morris CMP R1, #&E7 LDRB R1, [R0, #IOMD_ID1] CMPEQ R1, #&5B BNE %FT30 ;NE: no, assume IOMD, so only one PS2 port ] MOV R1, #IOMD_MSECR_Enable ;yes, so initialise 2nd PS2 (mouse) port cos STRB R1, [R0, #IOMD_MSECR] ;keyboard may be connected there instead 20 LDRB R1, [R0, #IOMD_MSECR] TST R1, #IOMD_MSECR_TxE ;Is port ready to accept data MOVNE R1, #&FF ;NE: port ready, so send 'reset' command STRNEB R1, [R0, #IOMD_MSEDAT] ; BEQ %BT20 ;EQ: loop til port ready MOV R1, #IOMD_MouseRxFull_IRQ_bit STRB R1, [R0, #IOMD_IRQMSKD] MOV R0, #InitKbdWs MOV R1, #2 STRB R1, [R0, #Port2Present] 30 ] MOV r0, #InitKbdWs ADR r1, KeyData STR r1, [r0, #KeyDataPtr] B SetUpKbdReturn ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; On ARM600, this routine must work in IRQ32 mode IRQ_Test_CTRL_or_R_Pressed ROUT SUB lr, lr, #4 Push "r0-r2,lr" MOV r2, #IOBase [ MorrisSupport MOV lr, #InitIRQWs LDRB r1, [lr, #Port2Present] ;Check if 2nd PS2 port (in Morris) is available TEQ r1, #0 LDRNEB r0, [r2, #IOMD_MSECR] ;NE: yes, so check if interrupt is from it TSTNE r0, #IOMD_MSECR_RxF ; LDRNEB r2, [r2, #IOMD_MSEDAT] ;NE: 2nd port present and interrupting, get scan code MOVNE r1, #2 ;NE: indicate which port BNE %FT5 ;NE: process it ;EQ: 2nd port not present or interrupting ; drop through and check 1st port ] LDRB r0, [r2, #IOStatus] TST r0, #stat_RXF ; If not keyboard then Pull "r0-r2,pc",EQ,^ ; exit. LDRB r2, [r2, #IOData] ; Get scan code. [ MorrisSupport MOV r1, #1 5 LDRB r0, [lr, #KB_There_Flag] TEQ r2, #0 ;Assume that zero is the end of a mouse AA 00 start up BICEQ r0, r0, r1 ; sequence, so clear keyboard present indication. STREQB r0, [lr, #KB_There_Flag] Pull "r0-r2,pc",EQ,^ ; and exit ORRNE r0, r0, r1 ;Not zero, mark keyboard present ] MOV lr, #InitIRQWs STRB r0, [lr, #KB_There_Flag] ; Keyboard must be there (r0<>0 from above). ADR r1, SpecialData TEQ r2, #PCSpecial ; If special code then STREQ r1, [lr, #KeyDataPtr] ; switch tables Pull "r0-r2,pc",EQ,^ ; and exit. LDR r0, [lr, #KeyDataPtr] ; Get pointer to current table. TEQ r0, r1 ; Only use special table once, then ADREQ r1, KeyData ; switch back to normal table. STREQ r1, [lr, #KeyDataPtr] 10 LDRB r1, [r0], #2 ; Get key code from table. TEQ r1, #0 ; If at end of table then Pull "r0-r2,pc",EQ,^ ; ignore key. TEQ r1, r2 ; If not this key then BNE %BT10 ; try the next. LDRB r1, [r0, #-1] ; Get flag. STRB r1, [lr, r1] ; Non-zero means pressed. Pull "r0-r2,pc",,^ ] ; :LNOT: HAL END