; 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.
;
        TTL     => Convrsions : varicose number->string routines

despatchConvert ROUT

        MOV     r12, #0                 ; All conversions want initial cnt = 0

        CMP     R11, #OS_ConvertFixedNetStation
        BGE     EconetStation

        Push    "R1, lr"
        SUB     R10, R11, #OS_ConvertHex1 + 1
        BIC     R10, R10, #3
        ADD     PC, PC, R10
        B       Hex_Output       ; one digit     : -4
        B       Hex_Output       ; 2,3,4,8 digits:  0
        B       Cardinal_Output                  ;  4
        B       Signed_Output                    ;  8
        B       Binary_Output                    ; 12
        B       Cardinal_Spaced_Output           ; 16
        B       Signed_Spaced_Output             ; 20

Hex_Output ROUT

        SUBS    R11, R11, #OS_ConvertHex1
        MOVNE   R11, R11, LSL #3
        MOVEQ   R11, #4
        MOV     R0, R0, ROR R11

01      MOV     R0, R0, ROR #28
        AND     R10, R0, #&F
        CMP     R10, #10
        ADDGE   R10, R10, #"A"-10
        ADDLT   R10, R10, #"0"
        BL      addconvchar
        BVS     naffconversion
        SUBS    R11, R11, #4
        BNE     %BT01

endconversion
        MOVVC   R10, #0
        BLVC    addconvchar
        BVS     naffconversion

        Pull    "R0, lr"
        SUB     R2, R2, R12
        ADD     R2, R2, #1              ; null not really a char.
        SUB     R1, R1, #1
        ExitSWIHandler

naffconversion
        ADRL    R0, ErrorBlock_BuffOverflow
naffconversion_ErrorSet
      [ International
        BL      TranslateError
      ]
        Pull    "R1, lr"
        B       SLVK_SetV

Binary_Output ROUT

        SUB     R11, R11, #OS_ConvertBinary1-1
        MOV     R11, R11, LSL #3
        MOV     R0, R0, ROR R11
01      MOV     R0, R0, ROR #31
        AND     R10, R0, #1
        ADD     R10, R10, #"0"
        BL      addconvchar
        BVS     naffconversion
        SUBS    R11, R11, #1
        BNE     %BT01
        B       endconversion


; cardinal output very similar to BinaryToDecimal

Cardinal_Output ROUT

        SUB     R11, R11, #OS_ConvertCardinal1-1
        MOV     R11, R11, LSL #3
        MOV     R10, #-1
        MOV     R10, R10, LSL R11
        BIC     R0, R0, R10
        Push    "R3-R5"
        ADRL    R3, TenTimesTable
        MOV     R5, #9                  ; max entry
        MOV     R4, #0                  ; non-0 had flag
02      LDR     R11, [R3, R5, LSL #2]
        MOV     R10, #"0"-1             ; digit value
03      SUBS    R0, R0, R11
        ADD     R10, R10, #1
        BCS     %BT03
        ADD     R0, R0, R11
        CMP     R10, #"0"
        CMPEQ   R4, #0
        BNE     %FT04                   ; put digit

05      SUBS    R5, R5, #1
        BPL     %BT02                   ; next digit
        CMP     R4, #0
        BEQ     %FT04                   ; R5 must be 0
        Pull    "R3-R5"
        B       endconversion

04      MOV     R4, #-1
        BL      addconvchar
        BVC     %BT05
        Pull    "R3-R5"
        B       naffconversion


Signed_Output ROUT

        SUB     R11, R11, #OS_ConvertInteger1-1
        MOV     R11, R11, LSL #3
        AND     R11, R11, #31
        RSB     R11, R11, #32
        AND     R11, R11, #31
        MOV     R0, R0, LSL R11
        MOV     R0, R0, ASR R11
        MOV     R12, R2
        SWI     XOS_BinaryToDecimal
        MOVVS   r2, r12
        ADDVC   R1, R1, R2
        Swap    R2, R12, VC
        B       endconversion


Cardinal_Spaced_Output ROUT
Signed_Spaced_Output

        SUB     sp, sp, #12             ; get 12 byte buffer
        Push    "r1,r2,lr"
        LDR     r10,code_of_swi
        ADD     r10,r10,r11
        ADD     r1, sp, #3*4
        MOV     r2, #12
        SWI     XOS_CallASWI
        RSB     r0, r2, #12            ; bytes got
        Pull    "r1,r2,lr"
        MOV     R12, #0
        MOV     R11, sp
01      LDRB    R10, [R11], #1
        BL      addconvchar
        BVS     space_conv_exit
        SUBS    R0, R0, #1
        BEQ     space_conv_exit
        CMP     R10, #"-"
        BEQ     %BT01
        CMP     R0, #3
        CMPNE   R0, #6
        CMPNE   R0, #9
        BNE     %BT01
        MOV     R10, #" "
        BL      addconvchar
        BVC     %BT01

space_conv_exit
        ADD     sp, sp, #12
        B       endconversion

code_of_swi
        DCD     XOS_ConvertCardinal1 - OS_ConvertSpacedCardinal1


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; R1 current buffer pos
; R12 character count, R2 character limit
; R10 character

addconvchar ROUT

        CMP     R2, R12
        BLE     addconvcharoverflow

        ADD     R12, R12, #1
        STRB    R10, [R1], #1
        RETURNVC

addconvcharoverflow
        RETURNVS

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; EcoNet conversions

EconetStation ROUT

        CMP     R11, #OS_ConvertFixedFileSize
        BGE     FileSizeConversion

        Push    "R1, lr"
        Push    "R0"
        LDR     R0, [R0, #4]
        CMP     R0, #256
        BHS     invalidnetworknumber
        MOV     R10, #" "
        BL      doabyte
        BVS     %FT01
        CMP     R10, #"0"
        MOVEQ   R10, #"."
        CMPNE   R11, #OS_ConvertFixedNetStation
        BLEQ    addconvchar
        CMP     R10, #"."
        MOVEQ   R10, #"0"

01
        Pull    "R0"
        BVS     naffconversion
        LDR     R0, [R0]
        CMP     R0, #0
        CMPNE   R0, #256
        BHS     invalidstationnumber
        BL      doabyte
        B       endconversion

invalidnetworknumber
        INC     sp, 4                           ; Pull    "R0"
        ADR     R0, ErrorBlock_BadNetwork
        B       naffconversion_ErrorSet

invalidstationnumber
        ADR     R0, ErrorBlock_BadStation
        B       naffconversion_ErrorSet

ErrorBlock_BadNetwork
        DCD     ErrorNumber_BadNetwork
        DCB     "BadNet"                        ; The token for the Global message
        DCB     0
        ALIGN

ErrorBlock_BadStation
        DCD     ErrorNumber_BadStation
        DCB     "BadStn"                        ; The token for the Global message
        DCB     0
        ALIGN

doabyte ROUT
 ; R0 is byte, R11 SWI number (to indicate pad or not)
 ; return VS for oflo
        Push    "lr"
        CMP     R11, #OS_ConvertNetStation
        BEQ     %FT03
        CMP     R0, #100
        BGE     %FT03
        BL      addconvchar
        Pull    "PC", VS
02      CMP     R0, #10
        BGE     %FT03
        BL      addconvchar
        Pull    "PC", VS
03      CMP     R0, #0
        BNE     %FT01
        CMP     R11, #OS_ConvertNetStation
        Pull    "PC", EQ
        Pull    "lr"
        B       addconvchar

01      MOV     R10, R2
        SUB     R2, R2, R12         ; bytes left
        SWI     XOS_BinaryToDecimal
        ADD     R12, R12, R2
        ADD     R1, R1, R2
        MOV     R2, R10
        MOV     R10, #"0"
        Pull    "PC"

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Do length as xxxx bytes or xxxx Kbytes or xxxx Mbytes

; In    r0 = size in bytes
;       r1 -> buffer
;       r2 = buffer length
;       r12 = 0

; Out   r0 = r1in
;       r1 -> terminating zero
;       r2 = amount of buffer left

FileSizeConversion ROUT

        Push    "r1, lr"

        Push    "r4-r7"
        SUB     sp, sp, #16             ; May need temp frame

        MOV     r4, #0                  ; No char by default
        CMP     r0, #4096               ; Only go to 'K' format if > 4K
        MOVCS   r4, #"K"                ; Kilo
        MOVCSS  r0, r0, LSR #10         ; /1024
        ADC     r0, r0, #0              ; Round up iff divided and bit fell out
        CMP     r0, #4096               ; Only go to 'M' format if > 4M
        MOVCS   r4, #"M"                ; Mega
        MOVCSS  r0, r0, LSR #10         ; /1024 again
        ADC     r0, r0, #0              ; Round up iff divided and bit fell out

; No need to go to 'G' format as 2^32 = 4096M!

        MOV     r5, r0                  ; Remember for prettiness

        CMP     r11, #OS_ConvertFixedFileSize
        BNE     %FT50

        Push    "r1, r2"                ; Remembering state
        ADD     r1, sp, #4*2            ; Point to our temp buffer
        MOV     r2, #16
        SWI     XOS_BinaryToDecimal     ; This will not give error
        MOV     r7, r2                  ; Number of chars to do
        RSBS    r6, r2, #4              ; Number of spaces needed
        Pull    "r1, r2"
        BLE     %FT39

30      MOV     r10, #" "
        BL      addconvchar
        BVS     %FA95
        SUBS    r6, r6, #1
        BNE     %BT30

39      MOV     r6, sp                  ; Stick string in punter's buffer
40      LDRB    r10, [r6], #1
        BL      addconvchar
        BVS     %FA95
        SUBS    r7, r7, #1
        BNE     %BT40

        B       %FT60


50      MOV     r12, r2                 ; No padding on LHS, easy case
        SWI     XOS_BinaryToDecimal
        MOVVS   r2, r12
        ADDVC   r1, r1, r2
        Swap    r2, r12, VC

60      MOVVC   r10, #" "
        BLVC    addconvchar
        BVS     %FA95

        MOVS    r10, r4                 ; Char to print ? VClear
        BNE     %FT70

        CMP     r11, #OS_ConvertFixedFileSize ; VClear
        BNE     %FT75

        MOV     r10, #" "               ; Need to pad in middle

70      BL      addconvchar

75      MOVVC   r10, #"b"               ; 'byte'
        BLVC    addconvchar
        MOVVC   r10, #"y"
        BLVC    addconvchar
        MOVVC   r10, #"t"
        BLVC    addconvchar
        MOVVC   r10, #"e"
        BLVC    addconvchar
        BVS     %FA95

        CMP     r5, #1                  ; Prettify (unpluralisationism). VClear
        MOVNE   r10, #"s"
        BNE     %FT90

        CMP     r11, #OS_ConvertFixedFileSize ; VClear
        BNE     %FA95
        MOV     r10, #" "               ; Need to pad to right

90      BL      addconvchar

95      ADD     sp, sp, #16
        Pull    "r4-r7"
        B       endconversion

; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        END