; Message file handling code

; ----------
; copy_error
; ----------
;
; In    r0 = pointer to error block with text <tag>
; Out   r0 = pointer to translated error block flags preserved (error not marked in globalerror)
copy_error ENTRY "r1-r7"
        ADR     R4, MsgsNul
10
        ADR     R5, MsgsNul
20
        ADR     R6, MsgsNul
30
        ADR     R7, MsgsNul
        CLRV                    ; To avoid interaction with any V set on entry
 [ debugmsgstuff
        ADD     r0, r0, #4
        DSTRING r0,"copy_error(",cc
        SUB     r0, r0, #4
        DSTRING r4,",",cc
        DSTRING r5,",",cc
        DSTRING r6,",",cc
        DSTRING r7,",",cc
        DLINE   ")"
 ]

        ; Check we're not threaded too many times
        LDR     r1, message_file_flags
        MOV     lr, r1, LSR #message_error_lookup_threads
        AND     lr, lr, #message_error_lookup_threads_mask
        CMP     lr, #message_max_error_threads
        BLO     %FT50

        ; We're threaded too many times looking up the error - it's
        ; time to give up.
        addr    r0, ErrorBlock_TooManyErrorLookups
        SETV
        EXIT

50
        ; Increase the threadedness of the error lookups
        ADD     r1, r1, #1 :SHL: message_error_lookup_threads
        STR     r1, message_file_flags

        BL      open_message_file
        EXIT    VS

        ; Lookup the error
        ADR     R1, message_file_block
        MOV     R2, #0
        SWI     XMessageTrans_ErrorLookup

        ; Decrease the threadedness of the error lookups
        LDR     r1, message_file_flags
        SUB     r1, r1, #1 :SHL: message_error_lookup_threads
        STR     r1, message_file_flags

        EXIT

; -----------
; copy_error1
; -----------
;
; In    r0 = pointer to error block with text <tag>
;       r4 = 1st parameter
; Out   r0 = pointer to translated error block flags preserved
copy_error1 ALTENTRY
        B       %BT10

; -----------
; copy_error2
; -----------
;
; In    r0 = pointer to error block with text <tag>
;       r4 = 1st parameter
;       r5 = 2nd parameter
; Out   r0 = pointer to translated error block flags preserved
copy_error2 ALTENTRY
        B       %BT20

; -----------
; copy_error3
; -----------
;
; In    r0 = pointer to error block with text <tag>
;       r4 = 1st parameter
;       r5 = 2nd parameter
;       r6 = 3rd parameter
; Out   r0 = pointer to translated error block flags preserved
copy_error3 ALTENTRY
        B       %BT30

; --------------
; message_lookup
; --------------
;
; In    r0 = pointer to nul-terminated tag
; Out   r0 = pointer to ctrl-char terminated string
;       error possible
message_lookup ENTRY "r0-r7"
 [ debugmsgstuff
        DSTRING r0,"message_lookup(",cc
        DLINE   ")->",cc
 ]
        ADR     R4, MsgsNul
        ADR     R5, MsgsNul
        ADR     R6, MsgsNul
        ADR     R7, MsgsNul
        MOV     r2, #0
        MOV     r1, r0
        ADR     r0, message_file_block
        BL      open_message_file
        SWI     XMessageTrans_Lookup
 [ debugmsgstuff
        BVS     %FT01
        DSTRING r2
01
 ]
        STRVC   r2, [sp]
        EXITS   VC
 [ debugmsgstuff
        ADD     r0, r0, #4
        DSTRING r0, "error:"
        SUB     r0, r0, #4
 ]
        STR     r0, [sp]
        EXIT

MsgsNul DCB     0
        ALIGN

; ---------------------------
; message_lookup2_into_buffer
; ---------------------------
;
; In    r0 = pointer to nul-terminated tag
;       r1 = buffer
;       r2 = buffer size
; Out   r0 = pointer to ctrl-char terminated string
;       r1 = pointer to terminating char in buffer
;       r2 = number of bytes free in buffer
;       error possible
message_lookup2_into_buffer ENTRY "r0-r7"
        ADR     R4, MsgsNul
10
        ADR     R5, MsgsNul
20
        ADR     R6, MsgsNul
        ADR     R7, MsgsNul
 [ debugmsgstuff
        DSTRING r0,"message_lookup2_into_buffer(",cc
        DREG    r1,",",cc
        DREG    r2,",",cc
        DSTRING r4,",",cc
        DSTRING r5,",",cc
        DSTRING r6,",",cc
        DSTRING r7,",",cc
        DLINE   ")"
 ]
        MOV     r3, r2
        MOV     r2, r1
        MOV     r1, r0
        ADR     r0, message_file_block
        BL      open_message_file
        SWIVC   XMessageTrans_Lookup
        STRVS   r0, [sp]
        STRVC   r2, [sp]
        ADDVC   r2, r2, r3
        STRVC   r2, [sp, #1*4]
        LDRVC   r2, [sp, #2*4]
        SUBVC   r2, r2, r3
        STRVC   r2, [sp, #2*4]
 [ debugmsgstuff
        BVC     %FT01
        ADD     r0, r0, #4
        DSTRING r0, "error:"
        SUB     r0, r0, #4
01
 ]
        EXIT

; ---------------------------
; message_lookup21_into_buffer
; ---------------------------
;
; In    r0 = pointer to nul-terminated tag
;       r1 = buffer
;       r2 = buffer size
;       r4 = subst argument 1
; Out   r0 = pointer to ctrl-char terminated string
;       r1 = pointer to terminating char in buffer
;       r2 = number of bytes free in buffer
;       error possible
message_lookup21_into_buffer ALTENTRY
        B       %BT10

; ---------------------------
; message_lookup22_into_buffer
; ---------------------------
;
; In    r0 = pointer to nul-terminated tag
;       r1 = buffer
;       r2 = buffer size
;       r4 = subst argument 1
;       r5 = subst argument 2
; Out   r0 = pointer to ctrl-char terminated string
;       r1 = pointer to terminating char in buffer
;       r2 = number of bytes free in buffer
;       error possible
message_lookup22_into_buffer ALTENTRY
        B       %BT20

; ----------------
; message_gswrite0
; ----------------
;
; In    r0 = pointer to nul-terminated <tag>
; Out   all regs preserved (except r0 on error)
;       error possible
message_gswrite0 ENTRY "r0-r7", 256
        ADR     R4, MsgsNul
10
        ADR     R5, MsgsNul
20
        ADR     R6, MsgsNul
        ADR     R7, MsgsNul
 [ debugmsgstuff
        DSTRING r0,"message_gswrite0(",cc
        DSTRING r4,",",cc
        DSTRING r5,",",cc
        DSTRING r6,",",cc
        DSTRING r7,",",cc
        DLINE   ")"
 ]
        BL      open_message_file
        MOVVC   r1, r0
        ADRVC   r0, message_file_block
        MOVVC   r2, sp
        MOVVC   r3, #256
        SWIVC   XMessageTrans_GSLookup
        MOVVC   r0, r2
        MOVVC   r1, r3
        SWIVC   XOS_WriteN
        STRVS   r0, [sp, #Proc_LocalStack + 0*4]
 [ debugmsgstuff
        BVC     %FT01
        ADD     r0, r0, #4
        DSTRING r0, "error:"
        SUB     r0, r0, #4
01
 ]

        EXIT

; -----------------
; message_gswrite01
; -----------------
;
; In    r0 = pointer to nul-terminated <tag>
;       r4 = pointer to substitute string
; Out   all regs preserved unless error
;               globalerror possible
message_gswrite01 ALTENTRY
        B       %BT10


; -----------------
; message_gswrite02
; -----------------
;
; In    r0 = pointer to nul-terminated <tag>
;       r4 = pointer to substitute string
;       r5 = pointer to substitute string
; Out   all regs preserved unless error
;               globalerror possible
message_gswrite02 ALTENTRY
        B       %BT20


; --------------
; message_write0
; --------------
;
; In    r0 = pointer to nul-terminated <tag>
; Out   all regs preserved (except r0 on error)
;       error possible
message_write0 ENTRY "r0-r7", 768
        ADR     R4, MsgsNul
10
        ADR     R5, MsgsNul
20
        ADR     R6, MsgsNul
30
        ADR     R7, MsgsNul
 [ debugmsgstuff
        DSTRING r0,"message_write0(",cc
        DSTRING r4,",",cc
        DSTRING r5,",",cc
        DSTRING r6,",",cc
        DSTRING r7,",",cc
        DLINE   ")"
 ]
        BL      open_message_file
        MOVVC   r1, r0
        ADRVC   r0, message_file_block
        MOVVC   r2, sp
        MOVVC   r3, #Proc_LocalStack
        SWIVC   XMessageTrans_Lookup
        MOVVC   r0, r2
        MOVVC   r1, r3
 [ debugmsgstuff
        BVS     %FT01
        DSTRING r0, "about to WriteN ",cc
        DREG    r1, " with length "
        B       %FT02
01
        ADD     r0, r0, #4
        DSTRING r0, "Not about to WriteN with error:"
        SUB     r0, r0, #4
02
 ]
        SWIVC   XOS_WriteN
 [ debugmsgstuff
        BVC     %FT01
        ADD     r0, r0, #4
        DSTRING r0, "error:"
        SUB     r0, r0, #4
01
 ]
        STRVS   r0, [sp, #Proc_LocalStack + 0*4]

        EXIT

; ---------------
; message_write01
; ---------------
;
; In    r0 = pointer to nul-terminated <tag>
;       r4 = pointer to substitute string
; Out   all regs preserved unless error
message_write01 ALTENTRY
        B       %BT10


; ---------------
; message_write02
; ---------------
;
; In    r0 = pointer to nul-terminated <tag>
;       r4 = pointer to substitute string
;       r5 = pointer to substitute string
; Out   all regs preserved unless error
;               error possible
message_write02 ALTENTRY
        B       %BT20

; ---------------
; message_write03
; ---------------
;
; In    r0 = pointer to nul-terminated <tag>
;       r4 = pointer to substitute string
;       r5 = pointer to substitute string
;       r6 = pointer to substitute string
; Out   all regs preserved unless error
;               error possible
message_write03 ALTENTRY
        B       %BT30


message_filename
        DCB     "Resources:$.Resources.FileSwitch.Messages", 0
        ALIGN

; -----------------
; open_message_file
; -----------------
;
; In    -
; Out   r0,VS possible - globalerror not set
open_message_file ENTRY "r0-r2"

        ; Ensure file not open already
        LDR     r1, message_file_flags
        TST     r1, #message_file_open
        EXIT    NE

 [ debugmsgstuff
        DLINE   "Open message file...",cc
 ]

        ; Check if we're busy openning it at the moment
        TST     r1, #message_file_busy
        BEQ     %FT10

 [ debugmsgstuff
        DLINE   "***BUSY***"
 ]
        ; Gark: message file currently busy.
        ; Don't even try to look up the error!
        addr    r0, ErrorBlock_MessageFileBusy
        SETV
        B       %FT95

10
        ; Mark message file as busy
        ORR     r1, r1, #message_file_busy
        STR     r1, message_file_flags

        ; Open it
        ADR     R0, message_file_block
        ADR     R1, message_filename
        MOV     r2, #0
        SWI     XMessageTrans_OpenFile

        ; Mark the message file as open and not busy
        LDRVC   r1, message_file_flags
        ORRVC   r1, r1, #message_file_open
        STRVC   r1, message_file_flags
 [ debugmsgstuff
        BVC     %FT01
        ADD     r0, r0, #4
        DSTRING r0, "error:"
        SUB     r0, r0, #4
        B       %FT02
01
        DLINE   "Done"
02
 ]

90
        LDR     r1, message_file_flags
        BIC     r1, r1, #message_file_busy
        STR     r1, message_file_flags

95
        STRVS   r0, [sp]
        EXIT

        END
