;    s.PrintStr
;
;******************************************************************************
;
;    This file assembles to a linkable object exporting one procedure which
;    may be useful in several programs, and obeys the ARM procedure call
;    standard, so may be called not only from assembler but also from high
;    level languages. The object file is intended to be incorporated in an
;    example linkable library with the LibFile tool.
;
;    Points demonstrated here include:
;       - Use of the LibFile tool to construct linkable libraries
;       - Leaf procedures obeying the APCS
;
;    The procedure exported is print_string, which prints a null terminated
;    string pointed to by r0. It has the C prototype:
;    void print_string(char *string);
;

; Use the GET directive to include a list of SWI names as if typed here

        GET     ^.AsmHdrs.h.SWINames

; Area name C$$code advisable if wanted to link with C output

        AREA    |C$$code|, CODE, READONLY

        EXPORT  |print_string|

; APCS specifies input arguments in lowest registers - since only 1 here use r0
; r0 - r3 can be altered
; Since this is a leaf procedure (calls no others) it doesn't set up a stack frame

|print_string|

        MOV    r3, lr                 ; store lr in r3 in case called from SVC
                                      ; mode, when SWI corrupts lr
        MOV    r2, r0
loop_print
        LDRB   r0, [r2], #1
        CMP    r0, #" "
        BLT    end_loop_print
        SWI    OS_WriteC
        B      loop_print
end_loop_print
        CMP    r0, #0
 [ {CONFIG}=26
        MOVEQS pc, r3
 |
        MOVEQ  pc, r3
 ]

 [ {CONFIG}=26
        CMP    r0, #10                ; sort out a problem with newlines from C
        SWIEQ  OS_WriteC
        MOVEQ  r0, #13
        BEQ    print_control
        CMP    r0, #13
        SWIEQ  OS_WriteC
        MOVEQ  r0, #10
print_control
        SWI    OS_WriteC
        LDREQB r1, [r2]
        CMPEQ  r0, r1
        ADDEQ  r2, r2, #1
        B      loop_print
 |
; Above cunning code not safe on a 32-bit system - SWIs don't preserve flags
        CMP    r0, #10
        CMPNE  r0, #13
        BEQ    print_cr_or_lf
        SWI    OS_WriteC
        B      loop_print

print_cr_or_lf
        SWI    OS_WriteC
        EOR    r0, r0, #10:EOR:13
        SWI    OS_WriteC
        LDRB   r1, [r2]
        CMP    r0, r1
        ADDEQ  r2, r2, #1
        B      loop_print
 ]

        END
