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