struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / device / lib / ez80_z80 / __itoa.s
blob359cf1a4bc457d11cf4d1821110789711ae1c27b
1 ;--------------------------------------------------------------------------
2 ; __itoa.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 ___itoa
33 .globl ___uitoa
35 ;void __itoa(int value, char *string, unsigned char radix);
37 ___itoa::
38 push ix
39 ld ix, #0
40 add ix, sp
42 ; HL - value
43 ; 4 (ix) - string
44 ; 6 (ix) - radix
46 ex de, hl
47 bit 7, d
48 jr Z, ___uitoa_de
49 ;positive/negative numbers are supported only for radix=10
50 ld a, 6 (ix)
51 cp a, #10
52 jr NZ, ___uitoa_de
53 ;add minus sign to result and inverse value (Carry Flag is 0 here)
54 ld hl, #0
55 sbc hl, de
56 ex de, hl
57 ld hl, 4 (ix)
58 ld (hl), #0x2D ;minus symbol
59 inc hl
60 ld 4 (ix), hl
61 jr ___uitoa_dehl
63 ;void __uitoa(unsigned int value, char *string, unsigned char radix);
65 ___uitoa::
66 push ix
67 ld ix, #0
68 add ix, sp
70 ; HL - value
71 ; 4 (ix) - string
72 ; 6 (ix) - radix
74 ex de, hl
76 ___uitoa_de:
77 ld hl, 4 (ix)
79 ___uitoa_dehl: ;DE - value, HL - string, 6 (ix) - radix
80 ld a, e
81 or a, d
82 jr NZ, 100$
84 ld (hl), #0x30
85 inc hl
86 jp 190$
87 100$:
88 ld a, 6 (ix)
89 cp a, #10 ;most popular radix
90 jr NZ, 110$
92 ;-------- decimal conversion
93 ; this algorithm up to 2 times faster than generic
95 ld c, l
96 ld b, h
97 ld hl, #-4
98 add hl, sp
99 ld sp, hl
100 push hl
101 push bc ;BC - pointer to string
102 push hl ;HL - pointer to BCD[4]
103 ex de, hl
104 call ___uitobcd ;HL - value
105 pop de ;DE - pointer to string
106 pop hl ;HL - pointer to BCD value
107 ld b, #3 ;number of bytes in BCD value
108 ld a, #0x30 ;ASCII code of '0'
109 103$:
111 ld (de), a
112 inc de
114 ld (de), a
115 inc de
116 inc hl
117 djnz 103$
119 ; pop af
120 ; pop af
121 ;skip trailing zeroes
122 ld b, #5 ;real BCD number is at most 5 digits
123 dec de ;so always skip last zero
124 105$:
125 dec de
126 ld a, (de)
127 cp a, #0x30
128 jr NZ, 107$ ;break loop if non-zero found
129 djnz 105$
130 107$:
131 inc de ;always point to symbol next to last significant
132 ex de, hl
133 jr 190$
135 ;---------------------------
137 110$:
138 cp a, #2
139 jr C, 190$ ;radix is less than 2
141 ld c, a
142 dec c
143 and a, c
144 jr NZ, 150$
146 ;-------- radix is power of 2
148 ; DE - value, HL - pointer to string, C - mask
149 120$:
150 ld a, e
151 ld b, c
152 125$:
153 srl d
154 rr e
155 srl b
156 jr NZ, 125$
158 and a, c
159 add a, #0x30
160 cp a, #0x3A ;convert to 0...9A...Z
161 jr C, 130$
162 add a, #7
163 130$:
164 ld (hl), a
165 inc hl
166 ld a, e
167 or a, d
168 jr NZ, 120$
169 jr 190$
171 ;---------------------------
173 ;-------- custom radix (generic algorithm)
175 150$:
176 ex de, hl
177 160$:
178 ld c, 6 (ix)
179 call ___divu16_8
180 add a, #0x30
181 cp a, #0x3A
182 jr C, 165$
183 add a, #7
184 165$:
185 ld (de), a
186 inc de
187 ld a, l
188 or a, h
189 jr NZ, 160$
190 ex de, hl
191 ; jr 190$
193 ;---------------------------
195 ;-------- finish string and reverse its order
196 190$:
197 ld (hl), #0
198 ld de, 4 (ix)
199 call ___strreverse_reg
200 ld sp, ix
201 pop ix
202 pop hl
203 inc sp
204 inc sp
205 inc sp
206 jp (hl)
209 ;in: HL - divident, C - divisor
210 ;out: HL - quotient, A - remainder
211 ___divu16_8:
212 xor a, a
213 ld b, #16
214 100$:
215 add hl, hl
217 jr c, 110$
218 cp a, c
219 jr c, 120$
220 110$:
221 sub a, c
222 inc l
223 120$:
224 djnz 100$