; StringOctal  0.05  11-08-2006


StringOctal                            ROUT
; Function:     Create the textual representation of an octal value.
;               Return with V set (but NOT with a pointer to an error block in R0!) if the result doesn't fit in the buffer.
; Entry   :     r0 = value
;               r1 = pointer to output buffer
;               r2 = size of output buffer
; Exit    :     r0 = pointer to resulting string
;               r1 = pointer to closing null following resulting string
;               r2 = number of bytes left in buffer
; APCS    :     no, but useable in an APCS environment
; Alters  :     r0-r2
; Flags   :     V set on error; others undefined
; Requires:     -
        STMFD   sp!, {r9-fp, lr}
        MOV     lr, r0                           ; value to convert
        MOV     fp, r1                           ; keep pointer to buffer
        MOV     sl, #30                          ; set bit position to 30
0000    MOV     r9, lr, LSR sl                   ; shift value right R10 positions
        ANDS    r9, r9, #7                       ; only keep bit 0-2
        TEQEQ   fp, r1                           ; zero? then only store if this is not the first digit stored
        BEQ     %f0010
        SUBS    r2, r2, #1                       ; decrement buffer size
        BMI     %f0020                           ; negative? then buffer full
        ORR     r9, r9, #'0'                     ; add ASCII "0" to digit
        STRB    r9, [r1], #1                     ; store digit and adjust pointer
0010    SUBS    sl, sl, #3                       ; lower bit position with 3
        BPL     %b0000                           ; continue until negative
        SUBS    r2, r2, #1                       ; then decrement buffer size (still need to store a null)
0020    CMNMI   r2, #1<<31                       ; set V flag and restore original buffer pointer if buffer full
        MOVVS   r1, fp
        MOVVC   r0, fp                           ; else return pointer to start of buffer in R0
        MOVVC   lr, #0
        STRVCB  lr, [r1]                         ; and add closing null
        LDMFD   sp!, {r9-fp, pc}

        END
