; Copyright 1999 Pace Micro Technology plc ; ; 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. ; ; > KbdResRCMM ; This file contains the minimal RCMM 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. ; These asserts are to do with the need to pull forward the combo chip configuration. ; As the code presently stands, ConfigureCombo will only work without calling ; ReadMachineType and PowerHardware in these conditions. ; ; The reason for not calling them is that they mess with variables and VIDC things ; that aren't ready yet. ; ; ConfigureCombo etc only write to IOSystemType, which has now been moved to SkippedTables ; so it doesn't get wiped by ClearPhysRam. ASSERT :LNOT: BatManSupport UART2 * ComboBase + &2F8*4 ; -> base of UART 2 ^ 0, R2 UART_RBR # 0 ; 0 Receive buffer register (read only) { DLAB=0 } UART_THR # 4 ; 0 Transmit holding register (write only) { DLAB=0 } UART_IER # 4 ; 1 Interrupt enable register (RW) { DLAB=0 } UART_FCR # 0 ; 2 FIFO control register (write only) UART_IIR # 4 ; 2 Interrupt identification register (read only) UART_LCR # 4 ; 3 Line control register UART_MCR # 4 ; 4 Modem control register UART_LSR # 4 ; 5 Line status register UART_MSR # 4 ; 6 Modem status register UART_SCR # 4 ; 7 Scratchpad register ^ 0, R2 UART_DLL # 4 ; 0 Divisor latch (LS) { DLAB=1 } UART_DLH # 4 ; 1 Divisor latch (MS) { DLAB=1 } ; States ^ 0 RCMM_HaveNowt # 1 RCMM_HaveBasic # 1 RCMM_HaveOEM # 1 RCMM_HaveOEM_Key # 1 RCMM_HaveOEM_Remote # 1 RCMM_HaveOEM_Remote_2 # 1 ; RCMM keyboard codes we are interested in. RCMMCtrlL * 74 RCMMCtrlR * 81 RCMMShiftL * 61 RCMMShiftR * 72 RCMMR * 38 RCMMT * 39 RCMMDelete * 88 RCMMBSpace * 33 RCMMEnd * 89 ; RCMM remote control codes we are interested in. RCMMRemRight * 91+128 KeyData DCB RCMMCtrlL, CTRL_Down_Flag DCB RCMMCtrlR, CTRL_Down_Flag DCB RCMMShiftL, SHIFT_Down_Flag DCB RCMMShiftR, SHIFT_Down_Flag DCB RCMMR, R_Down_Flag DCB RCMMT, T_Down_Flag DCB RCMMDelete, Del_Down_Flag DCB RCMMBSpace, Del_Down_Flag DCB RCMMEnd, Copy_Down_Flag DCB RCMMRemRight, Del_Down_Flag DCB 0 ALIGN ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SetUpKbd ; Tricky - we don't have R13_svc set up yet - indeed it contains the RAM size ; and musn't be corrupted. These calls will need it though. The SVC stack does ; exist, so we can use it temporarily. MOV R3, R13 LDR R13, =SVCSTK ; We're going to be using the serial port on the combo chip, so we need to ; pull forward the combo chip initialisation from PMF.osinit. [ STB BL ConfigureCombo | BL Configure37C665 ;RiscPC, Kryten and Stork use only SMC 37C665 ] ; Set up the serial port LDR R2, =UART2 ; R2 -> UART LDRB R0, UART_LCR ORR R1, R0, #2_10000000 ; set DLAB (enable Divisor Latch Access) STRB R1, UART_LCR MOV R1, #12 ; divisor latch := 12 (9600 baud) STRB R1, UART_DLL MOV R1, #0 STRB R1, UART_DLH MOV R0, #2_00000011 ; 8N1, DLAB off STRB R0, UART_LCR STRB R1, UART_FCR ; FIFOs off LDRB R0, UART_RBR ; clear the receive buffer LDRB R0, UART_RBR LDRB R0, UART_LSR ; clear any error condition MOV R0, #2_00000101 ; received data and line status interrupts only STRB R0, UART_IER MOV R0, #2_00001011 ; enable IRQ; RTS and DTR on STRB R0, UART_MCR MOV R0, #IOMD_Base [ ReassignedIOMDInterrupts MOV R1, #IOMDr_serial_IRQ_bit | MOV R1, #IOMD_serial_IRQ_bit ] STRB R1, [R0, #IOCIRQMSKB] MOV R0, #InitKbdWs STRB R1, [R0, #KB_There_Flag] ; keyboard is always there (it's infra-red...) MOV R13, R3 ; restore R13 B SetUpKbdReturn ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; On ARM600, this routine must work in IRQ32 mode ; This is called on receipt of a serial interrupt. IRQ_Test_CTRL_or_R_Pressed ROUT SUB lr, lr, #4 Push "r0-r2,lr" LDR R2, =UART2 LDRB R0, UART_IIR AND R1, R0, #2_00000111 ; check the interrupt source TEQ R1, #2_100 BEQ IRQ_RCMM_Receive TEQ R1, #2_110 BEQ IRQ_RCMM_LineStatus Pull "R0-R2,PC",,^ ; shouldn't happen. Hope it goes away :) IRQ_RCMM_LineStatus LDRB R0, UART_LSR ; this clears the interrupt TST R0, #2_00011110 ; overrun, parity, framing or break error? Pull "R0-R2,PC",EQ,^ ; no? then why did you call us? TST R0, #2_00000001 ; data ready? LDRNEB R0, UART_RBR ; junk it then. MOV R0, #RCMM_HaveNowt MOV LR, #InitKbdWs STRB R0, [LR, #KeyState] Pull "R0-R2,PC",,^ ; Problem we have is no flow control; we could be looking at any ; part of a message. Deal with this by resynchronising every time ; we get something we don't expect. ; Basic mode keypress is binary 10xx0kkk kkkk0000 ; OEM mode keypress is binary 000011xx xxxx10xx 0kkkkkkk ; or 001xxxxx xxxx10xx 0kkkkkkk ; Remote control press is binary 000011xx xxxx00xx xxxxxxxx 0rrrrrrr ; or 001xxxxx xxxx00xx xxxxxxxx 0rrrrrrr IRQ_RCMM_Receive LDRB R0, UART_RBR ; received data in R0 (interrupt cleared) MOV R2, #InitKbdWs LDRB LR, [R2, #KeyState] ADD PC, PC, LR, LSL #2 NOP B IRQ_RCMM_Nowt B IRQ_RCMM_Basic B IRQ_RCMM_OEM B IRQ_RCMM_OEM_Key B IRQ_RCMM_OEM_Remote B IRQ_RCMM_OEM_Remote_2 IRQ_RCMM_Nowt AND LR, R0, #2_11001000 TEQ LR, #2_10000000 ; is it a basic mode keypress? BNE %FT10 MOV LR, #RCMM_HaveBasic STRB LR, [R2, #KeyState] AND LR, R0, #2_00000111 STRB LR, [R2, #KeyMSB] 10 AND LR, R0, #2_11111100 ; is it a short ID OEM message? TEQ LR, #2_00001100 ANDNE LR, R0, #2_11100000 ; or a long ID one? TEQNE LR, #2_00100000 MOVEQ LR, #RCMM_HaveOEM STREQB LR, [R2, #KeyState] Pull "R0-R2,PC",,^ IRQ_RCMM_Basic TST R0, #2_00001111 BNE ResyncRCMM LDRB LR, [R2, #KeyMSB] MOV R0, R0, LSR #4 ORR R0, R0, LR, LSL #4 ; R0 = key code B GotRCMMKey IRQ_RCMM_OEM AND LR, R0, #2_00001100 TEQ LR, #2_00000000 ; Remote control? TEQNE LR, #2_00001000 ; Keyboard? BNE ResyncRCMM TEQ LR, #2_00000000 MOVEQ LR, #RCMM_HaveOEM_Remote MOVNE LR, #RCMM_HaveOEM_Key B UpdateRCMMState IRQ_RCMM_OEM_Key TST R0, #2_10000000 ; Key up rather than down? BNE ResyncRCMM B GotRCMMKey IRQ_RCMM_OEM_Remote MOV LR, #RCMM_HaveOEM_Remote_2 B UpdateRCMMState ; This byte can be anything :) IRQ_RCMM_OEM_Remote_2 TST R0, #2_10000000 ; Key up rather than down? BNE ResyncRCMM ADD R0, R0, #128 ; Indicate a remote code B GotRCMMKey ResyncRCMM MOV LR, #RCMM_HaveNowt UpdateRCMMState STRB LR, [R2, #KeyState] Pull "R0-R2,PC",,^ ; In: R0 = key code, R2 = InitKbdWs GotRCMMKey ADR R1, KeyData 10 LDRB LR, [R1], #2 ; Get key code from table. TEQ LR, #0 ; If at end of table then Pull "R0-R2,PC",EQ,^ ; ignore key. TEQ LR, R0 ; If not this key then BNE %BT10 ; try the next. LDRB LR, [R1, #-1] ; Get flag. STRB LR, [R2, LR] ; Non-zero means pressed. B ResyncRCMM END