gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/asm/z80/__ltoa.s
1 ;--------------------------------------------------------------------------
2 ; __ltoa.s
3 ;
4 ; Copyright (C) 2020, Sergey Belyashov
5 ;
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.
10 ;
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.
15 ;
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.
20 ;
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 ;--------------------------------------------------------------------------
28
29 .area _CODE
30
31 .globl _ltoa
32 .globl _ultoa
33 ;
34 ;void __itoa(long value, char *string, unsigned char radix);
35 ;
36 _ltoa::
37 push ix
38 ld ix, #0
39 add ix, sp
40 ;
41 ; 4(ix) - value
42 ; 8(ix) - string
43 ; 10(ix) - radix
44 ;
45 ld e, 4 (ix)
46 ld d, 5 (ix)
47 bit 7, 7 (ix)
48 jr Z, ___ultoa_de
49 ;positive/negative numbers are supported only for radix=10
50 ld a, 10 (ix)
51 cp a, #10
52 jr NZ, ___ultoa_de
53 ;add minus sign to result and inverse value
54 ld hl, #0
55 or a, a
56 sbc hl, de
57 ex de, hl
58 ld hl, #0
59 ld c, 6 (ix)
60 ld b, 7 (ix)
61 sbc hl, bc
62 ld 6 (ix), l
63 ld 7 (ix), h
64 ld l, 8 (ix)
65 ld h, 9 (ix)
66 ld (hl), #0x2D ;minus symbol
67 inc hl
68 ld 8 (ix), l
69 ld 9 (ix), h
70 jr ___ultoa_dehl
71 ;
72 ;void __uitoa(unsigned int value, char *string, unsigned char radix);
73 ;
74 _ultoa::
75 push ix
76 ld ix, #0
77 add ix, sp
78 ;
79 ; 4(ix) - value
80 ; 8(ix) - string
81 ; 10(ix) - radix
82 ;
83 ld e, 4 (ix)
84 ld d, 5 (ix)
85 ;
86 ___ultoa_de:
87 ld l, 8 (ix)
88 ld h, 9 (ix)
89 ;
90 ___ultoa_dehl:
91 ld a, e
92 or a, d
93 or a, 6 (ix)
94 or a, 7 (ix)
95 jr NZ, 100$
96 ;
97 ld (hl), #0x30
98 inc hl
99 jp 190$
100 100$:
101 ld a, 10 (ix)
102 cp a, #10 ;most popular radix
103 jr NZ, 110$
104 ;
105 ;-------- decimal convertion
106 ;this algorithm is 20% faster than generic one
107 ;
108 ld c, l
109 ld b, h
110 ld hl, #-5
111 add hl, sp
112 ld sp, hl
113 push bc
114 push hl
115 ld c, 6 (ix)
116 ld b, 7 (ix)
117 push bc
118 push de
119 call ___ultobcd
120 ld hl, #6
121 add hl, sp
122 ld sp, hl
123 pop de ;DE - pointer to string
124 inc hl
125 inc hl ;HL - pointer to BCD value
126 ld b, #5 ;number of bytes in BCD value
127 ld a, #0x30 ;ASCII code of '0'
128 103$:
129 rrd
130 ld (de), a
131 inc de
132 rrd
133 ld (de), a
134 inc de
135 inc hl
136 djnz 103$
137 ;
138 ; ld sp, hl
139 ;skip trailing zeroes
140 ld b, #10 ;real decimal number is at most 10 digits
141 105$:
142 dec de
143 ld a, (de)
144 cp a, #0x30
145 jr NZ, 107$ ;break loop if non-zero found
146 djnz 105$
147 107$:
148 inc de ;always point to symbol next to last significant
149 ex de, hl
150 jr 190$
151 ;
152 ;---------------------------
153 ;
154 110$:
155 cp a, #2
156 jr C, 190$ ;radix is less than 2
157 ;
158 ld c, a
159 dec c
160 and a, c
161 jr NZ, 150$
162 ;
163 ;-------- radix is power of 2
164 ;
165 ; DE - lower 16 bits of value, HL - pointer to string, C - mask
166 120$:
167 ld a, e
168 ld b, c
169 125$:
170 srl 7 (ix)
171 rr 6 (ix)
172 rr d
173 rr e
174 srl b
175 jr NZ, 125$
176 ;
177 and a, c
178 add a, #0x30
179 cp a, #0x3A ;convert to 0...9A...Z
180 jr C, 130$
181 add a, #7
182 130$:
183 ld (hl), a
184 inc hl
185 ld a, e
186 or a, d
187 or a, 6 (ix)
188 or a, 7 (ix)
189 jr NZ, 120$
190 jr 190$
191 ;
192 ;---------------------------
193 ;
194 ;-------- custom radix (generic algorithm)
195 ;
196 150$:
197 ex de, hl
198 ld c, e
199 ld b, d
200 ld e, 6 (ix)
201 ld d, 7 (ix)
202 160$:
203 push bc
204 ld c, 10 (ix)
205 call ___divu32_8
206 pop bc
207 add a, #0x30
208 cp a, #0x3A
209 jr C, 165$
210 add a, #7
211 165$:
212 ld (bc), a
213 inc bc
214 ld a, l
215 or a, h
216 or a, e
217 or a, d
218 jr NZ, 160$
219 ld l, c
220 ld h, b
221 ; jr 190$
222 ;
223 ;---------------------------
224 ;
225 ;-------- finish string and reverse order
226 190$:
227 ld (hl), #0
228 ld e, 8 (ix)
229 ld d, 9 (ix)
230 call ___strreverse_reg
231 ld sp, ix
232 pop ix
233 ret
234 ;
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
244 rla
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$
253 ret
254
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.