; 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.
;
; Kernel.Messages
;
; This file deals with translating text and errors in an international
; kernel.
;
;
; TranslateError
; Entry:
;       R0 = Pointer to error block (Error number followed by token:default).
; Exit
;       R0 = pointer to error block to use.
;            If the error semaphore is set a pointer to the original block is
;            returned.
;       V Set.
;
TranslateError_VClear  ROUT
        Push    "r4,LR"
        MOV     r4,#0
        BL      TranslateError_UseR4
 [ No26bitCode
        CLRV
        Pull    "r4,PC"
 |
        Pull    "r4,PC",,^
 ]

TranslateError  ROUT
        Push    "r4,LR"
        MOV     r4,#0
        BL      TranslateError_UseR4
        Pull    "r4,PC"

TranslateError_UseR4
        Push    "R8,LR"
        mrs    ,R8,CPSR
        ORR     R8,R8,#V_bit                    ; V set ready :)

        MOV     LR,#0
        LDRB    LR, [LR, #ErrorSemaphore]
        TEQ     LR,#0
        BNE     %FT90

        BIC     R8, R8, #&0F
        ORR     R8, R8, #SVC_mode               ; SVC mode, preserve IRQ state
        msr    ,CPSR_c, R8

        Push    "R0-R7,LR"

        MOV     R2,#0
        MOV     R1,#-1                          ; We are looking up an error, don't bother
        STRB    R1, [R2, #ErrorSemaphore]       ; translating other errors.

        ADR     R1,KernelMessagesBlock+4
        MOV     R5,#0
        MOV     R6,#0
        MOV     R7,#0
        SWI     XMessageTrans_ErrorLookup
        LDR     R14,[R0]
        LDR     R1,[SP]
        LDR     R1,[R1]
        CMP     R14,R1
        STREQ   R0,[SP]

        MOV     R1,#0
        STRB    R1, [R1 ,#ErrorSemaphore]       ; Clear error semaphore

        Pull    "R0-R7,LR"
90
        msr    ,CPSR_cf, R8                     ; Back to original mode, V set
        Pull    "R8,PC"

;----------------------------------------------------------------------------------------
;
;WriteS_Translated
;Entry:
;       R14 -> Token.
;*NOTE*
;      MUST BE TOKEN:DEFAULT
;
;Exit:
;       Message printed
;       Returns to word after end of token.
;
WriteS_Translated       ROUT
 [ No26bitCode
        Push    "r0-r8,LR"
 |
        Push    "r0-r7,LR"
 ]
        MOV     r4,#0
        B       Int_WriteS_Translated_UseR4

WriteS_Translated_UseR4

 [ No26bitCode
        Push    "r0-r8,LR"
 |
        Push    "r0-r7,LR"
 ]

Int_WriteS_Translated_UseR4
 [ No26bitCode
        mrs    ,r8,CPSR
        MOV     r1,LR
 |
        BIC     r1,LR,#ARM_CC_Mask              ; r1 -> Token.
 ]
        MOV     r0,#0
        LDR     r0,[r0,#KernelMessagesBlock]
        CMP     r0,#0                           ; If no messages file, try the global one.
        ADRNE   r0,KernelMessagesBlock+4
        MOV     r2,#0                           ; Use message in place.
        MOV     r3,#0
        MOV     r5,#0
        MOV     r6,#0
        MOV     r7,#0                           ; No arguments.
        SWI     XMessageTrans_Lookup
        BVC     %FT01

        MOV     R2,R1                           ; MessageTrans not present or token not found.
00
        LDRB    r0,[r2],#1                      ; Skip to after ":"
        CMP     r0,#":"
        BNE     %BT00

; Now
; r1 -> terminator
; r2 -> message
; Print the message.

01
        LDRB    r0,[r2],#1                      ; Print all characters of message
        CMP     r0,#" "
        BLT     %FT02
        CMP     r0,#"%"
        SWINE   XOS_WriteC
        BNE     %BT01

        LDRB    r0,[r2],#1                      ; Found a %
        CMP     r0,#" "
        BLT     %FT02                           ; Trailing % sign!
        CMP     r0,#"0"
        SWINE   XOS_WriteI+"%"
        SWINE   XOS_WriteC
        BNE     %BT01                           ; Just in case it isn't %0

        CMP     r4,#0                           ; r4 = original parameter
        BEQ     %BT01

11
        LDRB    R0,[R4],#1
        CMP     R0,#" "
        SWIGE   XOS_WriteC
        BGE     %BT11
        B       %BT01
                                                ; Now skip to end of token.
02
 [ No26bitCode
        LDR     r1,[sp,#9*4]                    ; Get original token pointer
 |
        LDR     r1,[sp,#8*4]                    ; Get original token pointer
        BIC     r1,r1,#ARM_CC_Mask              ; r1 -> Token.
 ]
03
        LDRB    r0,[r1],#1
        CMP     r0,#32
        BGE     %BT03                           ; Skip to control character.
04
        CMP     r0,#0                           ; Print all control characters to terminating 0.
        SWINE   XOS_WriteC
        LDRNEB  r0,[r1],#1
        BNE     %BT04

; r1 now points at byte after end of token.

        ADD     r1,r1,#3                        ; Round up to next word.
        BIC     r1,r1,#3

 [ No26bitCode
        STR     r1,[sp,#9*4]                    ; Store back as return address on stack
        ORRVS   r8,r8,#V_bit
        msr    ,CPSR_f,r8

        Pull    "r0-r8,PC"                       ;Return.
 |
        LDR     r2,[sp,#8*4]
        AND     r2,r2,#ARM_CC_Mask              ; Just the flags and mode bits.
        ORR     r1,r1,r2
        ORRVS   r1,r1,#V_bit
        STR     r1,[sp,#8*4]                    ; Store back as return address on stack

        Pull    "r0-r7,PC",,^                    ;Return.
 ]

;----------------------------------------------------------------------------------------
;
;GSWriteS_Translated
;Entry:
;       R14 -> Token.
;*NOTE*
;      MUST BE TOKEN:DEFAULT
;
;Exit:
;       Message printed
;       Returns to word after end of token.
;
GSWriteS_Translated       ROUT
 [ No26bitCode
        Push    "r0-r8,LR"
 |
        Push    "r0-r7,LR"
 ]
        MOV     r4,#0
        B       Int_GSWriteS_Translated_UseR4

GSWriteS_Translated_UseR4

 [ No26bitCode
        Push    "r0-r8,LR"
 |
        Push    "r0-r7,LR"
 ]

Int_GSWriteS_Translated_UseR4
 [ No26bitCode
        mrs    ,r8,CPSR
        MOV     r1,LR
 |
        BIC     r1,LR,#ARM_CC_Mask              ; r1 -> Token.
 ]
        MOV     r0,#0
        LDR     r0,[r0,#KernelMessagesBlock]
        CMP     r0,#0                           ; If no messages file, try the global one.
        ADRNE   r0,KernelMessagesBlock+4
        LDR     r2,=GeneralMOSBuffer
        MOV     r3,#256
        MOV     r5,#0
        MOV     r6,#0
        MOV     r7,#0                           ; No arguments.
        SWI     XMessageTrans_GSLookup
        BVC     %FT01

        MOV     R2,R1                           ; MessageTrans not present or token not found.
00
        LDRB    r0,[r2],#1                      ; Skip to after ":"
        CMP     r0,#":"
        BNE     %BT00

; Now
; r1 -> terminator
; r2 -> message
; Print the message using OS_PrettyPrint.

01
        LDR     r0, =GeneralMOSBuffer
        MOV     r1, #0
        SWI     XOS_PrettyPrint
                                                ; Now skip to end of token.
02
 [ No26bitCode
        LDR     r1,[sp,#9*4]                    ; Get original token pointer
 |
        LDR     r1,[sp,#8*4]                    ; Get original token pointer
        BIC     r1,r1,#ARM_CC_Mask              ; r1 -> Token.
 ]
03
        LDRB    r0,[r1],#1
        CMP     r0,#0
        BNE     %BT03                           ; Skip to 0.

; r1 now points at byte after end of token.

        ADD     r1,r1,#3                        ; Round up to next word.
        BIC     r1,r1,#3

 [ No26bitCode
        STR     r1,[sp,#9*4]                    ; Store back as return address on stack
        ORRVS   r8,r8,#V_bit
        msr    ,CPSR_f,r8

        Pull    "r0-r8,PC"                       ;Return.
 |
        LDR     r2,[sp,#8*4]
        AND     r2,r2,#ARM_CC_Mask              ; Just the flags and mode bits.
        ORR     r1,r1,r2
        ORRVS   r1,r1,#V_bit
        STR     r1,[sp,#8*4]                    ; Store back as return address on stack

        Pull    "r0-r7,PC",,^                    ;Return.
 ]

;----------------------------------------------------------------------------------------
;FindToken
;
;Entry:
;       R0 -> Token.
;*NOTE*
;      MUST BE TOKEN:DEFAULT
;
;Exit:
;       r0 -> Message, or after the : if MessageTrans is dead.
;
;
FindToken      ROUT
 [ No26bitCode
        Push    "r0-r8,LR"
        mrs    ,r8,CPSR
 |
        Push    "r0-r7,LR"
 ]

        MOV     r1,r0
        MOV     r0,#0
        LDR     r0,[r0,#KernelMessagesBlock]
        CMP     r0,#0                           ; If no messages file, try the global one.
        ADRNE   r0,KernelMessagesBlock+4
        MOV     r2,#0
        MOV     r3,#0
        MOV     r4,#0
        MOV     r5,#0
        MOV     r6,#0
        MOV     r7,#0                           ; No arguments.
        SWI     XMessageTrans_Lookup
        BVC     %FT01

        MOV     R2,R1                           ; MessageTrans not present or token not found.
00
        LDRB    r0,[r2],#1                      ; Skip to after ":"
        CMP     r0,#":"
        BNE     %BT00
01
        STR     r2,[sp]

 [ No26bitCode
        msr    ,CPSR_f,r8
        Pull    "r0-r8,PC"
 |
        Pull    "r0-r7,PC",,^
 ]

;----------------------------------------------------------------------------------------
;Write0_Translated
;
;Entry:
;       R0 -> Token.
;*NOTE*
;      MUST BE TOKEN:DEFAULT
;
;Exit:
;        Message printed, r0->Message.
;
Write0_Translated ROUT
        EntryS  "r0,r1"
        BL      FindToken
        MOV     R1,R0
01
        LDRB    R0,[R1],#1
        CMP     R0,#31
        SWIGT   XOS_WriteC
        STRVS   r0,[SP]
        EXIT    VS
        BGT     %BT01

        EXITS

        END