Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / device / lib / z180 / __ltoa.s
blob7df890d87ef37a6dc215af76d78e6c6c5d9199b7
1 ;--------------------------------------------------------------------------
2 ; __ltoa.s
4 ; Copyright (C) 2020-2021, Sergey Belyashov
6 ; This library is free software; you can redistribute it and/or modify it
7 ; under the terms of the GNU General Public License as published by the
8 ; Free Software Foundation; either version 2, or (at your option) any
9 ; later version.
11 ; This library is distributed in the hope that it will be useful,
12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ; GNU General Public License for more details.
16 ; You should have received a copy of the GNU General Public License
17 ; along with this library; see the file COPYING. If not, write to the
18 ; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
19 ; MA 02110-1301, USA.
21 ; As a special exception, if you link this library with other files,
22 ; some of which are compiled with SDCC, to produce an executable,
23 ; this library does not by itself cause the resulting executable to
24 ; be covered by the GNU General Public License. This exception does
25 ; not however invalidate any other reasons why the executable file
26 ; might be covered by the GNU General Public License.
27 ;--------------------------------------------------------------------------
29 .area _CODE
31 .globl ___ltoa
32 .globl ___ultoa
34 ;void __itoa(long value, char *string, unsigned char radix);
36 ___ltoa::
37 push ix
38 ld ix, #0
39 add ix, sp
41 push hl
42 ; push de
44 ; HLDE, -4 (ix) - value
45 ; 4 (ix) - string
46 ; 6 (ix) - radix
48 bit 7, h
49 jr Z, ___ultoa_de
50 ;positive/negative numbers are supported only for radix=10
51 ld a, 6 (ix)
52 cp a, #10
53 jr NZ, ___ultoa_de
54 ;add minus sign to result and inverse value
55 ld hl, #0
56 or a, a
57 sbc hl, de
58 ex de, hl
59 ld hl, #0
60 ld c, -2 (ix)
61 ld b, -1 (ix)
62 sbc hl, bc
63 ld -2 (ix), l
64 ld -1 (ix), h
65 ld l, 4 (ix)
66 ld h, 5 (ix)
67 ld (hl), #0x2D ;minus symbol
68 inc hl
69 ld 4 (ix), l
70 ld 5 (ix), h
71 jr ___ultoa_dehl
73 ;void __uitoa(unsigned int value, char *string, unsigned char radix);
75 ___ultoa::
76 push ix
77 ld ix, #0
78 add ix, sp
80 push hl
81 ; push de
83 ; HLDE, -4 (ix) - value
84 ; 4 (ix) - string
85 ; 6 (ix) - radix
87 ___ultoa_de:
88 ld l, 4 (ix)
89 ld h, 5 (ix)
91 ___ultoa_dehl:
92 ld a, e
93 or a, d
94 or a, -2 (ix)
95 or a, -1 (ix)
96 jr NZ, 100$
98 ld (hl), #0x30
99 inc hl
100 jp 190$
101 100$:
102 ld a, 6 (ix)
103 cp a, #10 ;most popular radix
104 jr NZ, 110$
106 ;-------- decimal conversion
107 ;this algorithm is 20% faster than generic one
109 ld c, l
110 ld b, h
111 ld hl, #-5
112 add hl, sp
113 ld sp, hl
114 push bc
115 push hl
116 ld l, -2 (ix)
117 ld h, -1 (ix)
118 call ___ultobcd
119 pop de ;DE - pointer to string
120 ld hl, #0
121 add hl, sp ;HL - pointer to BCD value
122 ld b, #5 ;number of bytes in BCD value
123 ld a, #0x30 ;ASCII code of '0'
124 103$:
126 ld (de), a
127 inc de
129 ld (de), a
130 inc de
131 inc hl
132 djnz 103$
134 ; ld sp, hl
135 ;skip trailing zeroes
136 ld b, #10 ;real decimal number is at most 10 digits
137 105$:
138 dec de
139 ld a, (de)
140 cp a, #0x30
141 jr NZ, 107$ ;break loop if non-zero found
142 djnz 105$
143 107$:
144 inc de ;always point to symbol next to last significant
145 ex de, hl
146 jr 190$
148 ;---------------------------
150 110$:
151 cp a, #2
152 jr C, 190$ ;radix is less than 2
154 ld c, a
155 dec c
156 and a, c
157 jr NZ, 150$
159 ;-------- radix is power of 2
161 ; DE - lower 16 bits of value, HL - pointer to string, C - mask
162 120$:
163 ld a, e
164 ld b, c
165 125$:
166 srl -1 (ix)
167 rr -2 (ix)
168 rr d
169 rr e
170 srl b
171 jr NZ, 125$
173 and a, c
174 add a, #0x30
175 cp a, #0x3A ;convert to 0...9A...Z
176 jr C, 130$
177 add a, #7
178 130$:
179 ld (hl), a
180 inc hl
181 ld a, e
182 or a, d
183 or a, -2 (ix)
184 or a, -1 (ix)
185 jr NZ, 120$
186 jr 190$
188 ;---------------------------
190 ;-------- custom radix (generic algorithm)
192 150$:
193 ex de, hl
194 ld c, e
195 ld b, d
196 ld e, -2 (ix)
197 ld d, -1 (ix)
198 160$:
199 push bc
200 ld c, 6 (ix)
201 call ___divu32_8
202 pop bc
203 add a, #0x30
204 cp a, #0x3A
205 jr C, 165$
206 add a, #7
207 165$:
208 ld (bc), a
209 inc bc
210 ld a, l
211 or a, h
212 or a, e
213 or a, d
214 jr NZ, 160$
215 ld l, c
216 ld h, b
217 ; jr 190$
219 ;---------------------------
221 ;-------- finish string and reverse order
222 190$:
223 ld (hl), #0
224 ld e, 4 (ix)
225 ld d, 5 (ix)
226 call ___strreverse_reg
227 ld sp, ix
228 pop ix
229 pop hl
230 inc sp
231 inc sp
232 inc sp
233 jp (hl)
235 ;in: DEHL - divident, C - divisor
236 ;out: DEHL - quotient, A - remainder
237 ___divu32_8:
238 xor a, a
239 ld b, #32
240 100$:
241 add hl, hl
242 rl e
243 rl d
245 jr c, 110$
246 cp a, c
247 jr c, 120$
248 110$:
249 sub a, c
250 inc l
251 120$:
252 djnz 100$