__itoa.s (4077B)
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$ 92100$: 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' 117103$: 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 132105$: 133 dec de 134 ld a, (de) 135 cp a, #0x30 136 jr NZ, 107$ ;break loop if non-zero found 137 djnz 105$ 138107$: 139 inc de ;always point to symbol next to last significant 140 ex de, hl 141 jr 190$ 142; 143;--------------------------- 144; 145110$: 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 157120$: 158 ld a, e 159 ld b, c 160125$: 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 171130$: 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; 183150$: 184 ex de, hl 185160$: 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 192165$: 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 204190$: 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 219100$: 220 add hl, hl 221 rla 222 jr c, 110$ 223 cp a, c 224 jr c, 120$ 225110$: 226 sub a, c 227 inc l 228120$: 229 djnz 100$ 230 ret 231