; 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
        Pull    "r4,PC",,^

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

TranslateError_UseR4
        Push    "R8,LR"

        MOV     R8,#0
        LDRB    R8, [R8, #ErrorSemaphore]
        CMP     R8,#0
        Pull    "R8,LR",NE
        ORRNES  PC,LR,#V_bit

        MOV     R8,LR
 [ {TRUE}
        ORR     LR, LR, #SVC_mode               ; SVC mode, preserve IRQ state
        TEQP    PC, LR
 |
        TEQP    PC,#SVC_mode
 ]
        MOV     R0,R0
        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"                      ; Exit with new block and V set.

        TEQP    PC,R8                           ; Back to original mode.
        MOV     R0,R0
        Pull    "R8,LR"
        ORRS    PC,R14,#V_bit                   ; original R0.

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

WriteS_Translated_UseR4

        Push    "r0-r7,LR"

Int_WriteS_Translated_UseR4
        BIC     r1,LR,#3                        ; r1 -> Token.
        BIC     r1,r1,#2_111111 :SHL: 26
        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
        LDR     r1,[sp,#8*4]                    ; Get original token pointer
        BIC     r1,r1,#3                        ; r1 -> Token.
        BIC     r1,r1,#2_111111 :SHL: 26
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

        LDR     r2,[sp,#8*4]
        MOV     r3,#2_111111 :SHL:26
        ORR     r3,r3,#2_11
        AND     r2,r2,r3                        ; 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
        Push    "r0-r7,LR"
        MOV     r4,#0
        B       Int_GSWriteS_Translated_UseR4

GSWriteS_Translated_UseR4

        Push    "r0-r7,LR"

Int_GSWriteS_Translated_UseR4
        BIC     r1,LR,#3                        ; r1 -> Token.
        BIC     r1,r1,#2_111111 :SHL: 26
        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
        LDR     r1,[sp,#8*4]                    ; Get original token pointer
        BIC     r1,r1,#3                        ; r1 -> Token.
        BIC     r1,r1,#2_111111 :SHL: 26
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

        LDR     r2,[sp,#8*4]
        MOV     r3,#2_111111 :SHL:26
        ORR     r3,r3,#2_11
        AND     r2,r2,r3                        ; 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
        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]

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

        Pull    "r0,r1,PC",,^

        END