Announce SDCC 4.5.0 RC1.
[sdcc.git] / sdcc / device / lib / z80 / __ltoa.s
blobd7036896a499e12b301e8f70dc0a8a515adb6196
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 .module __ltoa
30 .optsdcc -mz80 sdcccall(1)
32 .area _CODE
34 .globl ___ltoa
35 .globl ___ultoa
37 ;void __itoa(long value, char *string, unsigned char radix);
39 ___ltoa::
40 push ix
41 ld ix, #0
42 add ix, sp
44 push hl
45 ; push de
47 ; HLDE, -4 (ix) - value
48 ; 4 (ix) - string
49 ; 6 (ix) - radix
51 bit 7, h
52 jr Z, ___ultoa_de
53 ;positive/negative numbers are supported only for radix=10
54 ld a, 6 (ix)
55 cp a, #10
56 jr NZ, ___ultoa_de
57 ;add minus sign to result and inverse value
58 ld hl, #0
59 or a, a
60 sbc hl, de
61 ex de, hl
62 ld hl, #0
63 ld c, -2 (ix)
64 ld b, -1 (ix)
65 sbc hl, bc
66 ld -2 (ix), l
67 ld -1 (ix), h
68 ld l, 4 (ix)
69 ld h, 5 (ix)
70 ld (hl), #0x2D ;minus symbol
71 inc hl
72 ld 4 (ix), l
73 ld 5 (ix), h
74 jr ___ultoa_dehl
76 ;void __uitoa(unsigned int value, char *string, unsigned char radix);
78 ___ultoa::
79 push ix
80 ld ix, #0
81 add ix, sp
83 push hl
84 ; push de
86 ; HLDE, -4 (ix) - value
87 ; 4 (ix) - string
88 ; 6 (ix) - radix
90 ___ultoa_de:
91 ld l, 4 (ix)
92 ld h, 5 (ix)
94 ___ultoa_dehl:
95 ld a, e
96 or a, d
97 or a, -2 (ix)
98 or a, -1 (ix)
99 jr NZ, 100$
101 ld (hl), #0x30
102 inc hl
103 jp 190$
104 100$:
105 ld a, 6 (ix)
106 cp a, #10 ;most popular radix
107 jr NZ, 110$
109 ;-------- decimal conversion
110 ;this algorithm is 20% faster than generic one
112 ld c, l
113 ld b, h
114 ld hl, #-5
115 add hl, sp
116 ld sp, hl
117 push bc
118 push hl
119 ld l, -2 (ix)
120 ld h, -1 (ix)
121 call ___ultobcd
122 pop de ;DE - pointer to string
123 ld hl, #0
124 add hl, sp ;HL - pointer to BCD value
125 ld b, #5 ;number of bytes in BCD value
126 ld a, #0x30 ;ASCII code of '0'
127 103$:
129 ld (de), a
130 inc de
132 ld (de), a
133 inc de
134 inc hl
135 djnz 103$
137 ; ld sp, hl
138 ;skip trailing zeroes
139 ld b, #10 ;real decimal number is at most 10 digits
140 105$:
141 dec de
142 ld a, (de)
143 cp a, #0x30
144 jr NZ, 107$ ;break loop if non-zero found
145 djnz 105$
146 107$:
147 inc de ;always point to symbol next to last significant
148 ex de, hl
149 jr 190$
151 ;---------------------------
153 110$:
154 cp a, #2
155 jr C, 190$ ;radix is less than 2
157 ld c, a
158 dec c
159 and a, c
160 jr NZ, 150$
162 ;-------- radix is power of 2
164 ; DE - lower 16 bits of value, HL - pointer to string, C - mask
165 120$:
166 ld a, e
167 ld b, c
168 125$:
169 srl -1 (ix)
170 rr -2 (ix)
171 rr d
172 rr e
173 srl b
174 jr NZ, 125$
176 and a, c
177 add a, #0x30
178 cp a, #0x3A ;convert to 0...9A...Z
179 jr C, 130$
180 add a, #7
181 130$:
182 ld (hl), a
183 inc hl
184 ld a, e
185 or a, d
186 or a, -2 (ix)
187 or a, -1 (ix)
188 jr NZ, 120$
189 jr 190$
191 ;---------------------------
193 ;-------- custom radix (generic algorithm)
195 150$:
196 ex de, hl
197 ld c, e
198 ld b, d
199 ld e, -2 (ix)
200 ld d, -1 (ix)
201 160$:
202 push bc
203 ld c, 6 (ix)
204 call ___divu32_8
205 pop bc
206 add a, #0x30
207 cp a, #0x3A
208 jr C, 165$
209 add a, #7
210 165$:
211 ld (bc), a
212 inc bc
213 ld a, l
214 or a, h
215 or a, e
216 or a, d
217 jr NZ, 160$
218 ld l, c
219 ld h, b
220 ; jr 190$
222 ;---------------------------
224 ;-------- finish string and reverse order
225 190$:
226 ld (hl), #0
227 ld e, 4 (ix)
228 ld d, 5 (ix)
229 call ___strreverse_reg
230 ld sp, ix
231 pop ix
232 pop hl
233 inc sp
234 inc sp
235 inc sp
236 jp (hl)
238 ;in: DEHL - divident, C - divisor
239 ;out: DEHL - quotient, A - remainder
240 ___divu32_8:
241 xor a, a
242 ld b, #32
243 100$:
244 add hl, hl
245 rl e
246 rl d
248 jr c, 110$
249 cp a, c
250 jr c, 120$
251 110$:
252 sub a, c
253 inc l
254 120$:
255 djnz 100$