gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/asm/z80/__itoa.s
1 ;--------------------------------------------------------------------------
2 ; __itoa.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 _itoa
32 .globl _uitoa
33 ;
34 ;void __itoa(int value, char *string, unsigned char radix);
35 ;
36 _itoa::
37 push ix
38 ld ix, #0
39 add ix, sp
40 ;
41 ; 4(ix) - value
42 ; 6(ix) - string
43 ; 8(ix) - radix
44 ;
45 ld e, 4 (ix)
46 ld d, 5 (ix)
47 bit 7, d
48 jr Z, ___uitoa_de
49 ;positive/negative numbers are supported only for radix=10
50 ld a, 8 (ix)
51 cp a, #10
52 jr NZ, ___uitoa_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 l, 6 (ix)
59 ld h, 7 (ix)
60 ld (hl), #0x2D ;minus symbol
61 inc hl
62 ld 6 (ix), l
63 ld 7 (ix), h
64 jr ___uitoa_dehl
65 ;
66 ;void __uitoa(unsigned int value, char *string, unsigned char radix);
67 ;
68 _uitoa::
69 push ix
70 ld ix, #0
71 add ix, sp
72 ;
73 ; 4(ix) - value
74 ; 6(ix) - string
75 ; 8(ix) - radix
76 ;
77 ld e, 4 (ix)
78 ld d, 5 (ix)
79 ;
80 ___uitoa_de:
81 ld l, 6 (ix)
82 ld h, 7 (ix)
83 ;
84 ___uitoa_dehl:
85 ld a, e
86 or a, d
87 jr NZ, 100$
88 ;
89 ld (hl), #0x30
90 inc hl
91 jp 190$
92 100$:
93 ld a, 8 (ix)
94 cp a, #10 ;most popular radix
95 jr NZ, 110$
96 ;
97 ;-------- decimal convertion
98 ; this algorithm up to 2 times faster than generic
99 ;
100 ld c, l
101 ld b, h
102 ld hl, #-4
103 add hl, sp
104 ld sp, hl
105 push bc
106 push hl
107 push de
108 call ___uitobcd
109 ld hl, #4
110 add hl, sp
111 ld sp, hl
112 pop de ;DE - pointer to string
113 inc hl
114 inc 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$:
118 rrd
119 ld (de), a
120 inc de
121 rrd
122 ld (de), a
123 inc de
124 inc hl
125 djnz 103$
126 ;
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$
142 ;
143 ;---------------------------
144 ;
145 110$:
146 cp a, #2
147 jr C, 190$ ;radix is less than 2
148 ;
149 ld c, a
150 dec c
151 and a, c
152 jr NZ, 150$
153 ;
154 ;-------- radix is power of 2
155 ;
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$
165 ;
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$
178 ;
179 ;---------------------------
180 ;
181 ;-------- custom radix (generic algorithm)
182 ;
183 150$:
184 ex de, hl
185 160$:
186 ld c, 8 (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 h
197 jr NZ, 160$
198 ex de, hl
199 ; jr 190$
200 ;
201 ;---------------------------
202 ;
203 ;-------- finish string and reverse order
204 190$:
205 ld (hl), #0
206 ld e, 6 (ix)
207 ld d, 7 (ix)
208 call ___strreverse_reg
209 ld sp, ix
210 pop ix
211 ret
212 ;
213 ;
214 ;in: HL - divident, C - divisor
215 ;out: HL - quotient, A - remainder
216 ___divu16_8:
217 xor a, a
218 ld b, #16
219 100$:
220 add hl, hl
221 rla
222 jr c, 110$
223 cp a, c
224 jr c, 120$
225 110$:
226 sub a, c
227 inc l
228 120$:
229 djnz 100$
230 ret
231
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.