Announce SDCC 4.5.0 RC1.
[sdcc.git] / sdcc / device / lib / z80 / __itoa.s
blob431ecbed5d73a095f398d9611482e701acdaada9
1 ;--------------------------------------------------------------------------
2 ; __itoa.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 __itoa
30 .optsdcc -mz80 sdcccall(1)
32 .area _CODE
34 .globl ___itoa
35 .globl ___uitoa
37 ;void __itoa(int value, char *string, unsigned char radix);
39 ___itoa::
40 push ix
41 ld ix, #0
42 add ix, sp
44 push de
46 ; HL - value
47 ; DE - string
48 ; 4 (ix) - radix
50 ex de, hl
51 bit 7, d
52 jr Z, ___uitoa_de
53 ;positive/negative numbers are supported only for radix=10
54 ld a, 4 (ix)
55 cp a, #10
56 jr NZ, ___uitoa_de
57 ;add minus sign to result and inverse value (Carry Flag is 0 here)
58 ld hl, #0
59 sbc hl, de
60 ex de, hl
61 ld l, -2 (ix)
62 ld h, -1 (ix)
63 ld (hl), #0x2D ;minus symbol
64 inc hl
65 ld -2 (ix), l
66 ld -1 (ix), h
67 jr ___uitoa_dehl
69 ;void __uitoa(unsigned int value, char *string, unsigned char radix);
71 ___uitoa::
72 push ix
73 ld ix, #0
74 add ix, sp
76 push de
78 ; HL - value
79 ; DE - string
80 ; 4 (ix) - radix
82 ex de, hl
84 ___uitoa_de:
85 ld l, -2 (ix)
86 ld h, -1 (ix)
88 ___uitoa_dehl: ;DE - value, HL - string, 6 (ix) - radix
89 ld a, e
90 or a, d
91 jr NZ, 100$
93 ld (hl), #0x30
94 inc hl
95 jp 190$
96 100$:
97 ld a, 4 (ix)
98 cp a, #10 ;most popular radix
99 jr NZ, 110$
101 ;-------- decimal conversion
102 ; this algorithm up to 2 times faster than generic
104 ld c, l
105 ld b, h
106 ld hl, #-4
107 add hl, sp
108 ld sp, hl
109 push hl
110 push bc ;BC - pointer to string
111 ex de, hl
112 call ___uitobcd ;HL - value, DE - pointer to BCD value
113 pop de ;DE - pointer to string
114 pop hl ;HL - pointer to BCD value
115 ld b, #3 ;number of bytes in BCD value
116 ld a, #0x30 ;ASCII code of '0'
117 103$:
119 ld (de), a
120 inc de
122 ld (de), a
123 inc de
124 inc hl
125 djnz 103$
127 ; pop af
128 ; pop af
129 ;skip trailing zeroes
130 ld b, #5 ;real BCD number is at most 5 digits
131 dec de ;so always skip last zero
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 - value, HL - pointer to string, C - mask
157 120$:
158 ld a, e
159 ld b, c
160 125$:
161 srl d
162 rr e
163 srl b
164 jr NZ, 125$
166 and a, c
167 add a, #0x30
168 cp a, #0x3A ;convert to 0...9A...Z
169 jr C, 130$
170 add a, #7
171 130$:
172 ld (hl), a
173 inc hl
174 ld a, e
175 or a, d
176 jr NZ, 120$
177 jr 190$
179 ;---------------------------
181 ;-------- custom radix (generic algorithm)
183 150$:
184 ex de, hl
185 160$:
186 ld c, 4 (ix)
187 call ___divu16_8
188 add a, #0x30
189 cp a, #0x3A
190 jr C, 165$
191 add a, #7
192 165$:
193 ld (de), a
194 inc de
195 ld a, l
196 or a, h
197 jr NZ, 160$
198 ex de, hl
199 ; jr 190$
201 ;---------------------------
203 ;-------- finish string and reverse its order
204 190$:
205 ld (hl), #0
206 ld e, -2 (ix)
207 ld d, -1 (ix)
208 call ___strreverse_reg
209 ld sp, ix
210 pop ix
211 pop hl
212 inc sp
213 jp (hl)
216 ;in: HL - divident, C - divisor
217 ;out: HL - quotient, A - remainder
218 ___divu16_8:
219 xor a, a
220 ld b, #16
221 100$:
222 add hl, hl
224 jr c, 110$
225 cp a, c
226 jr c, 120$
227 110$:
228 sub a, c
229 inc l
230 120$:
231 djnz 100$