__ltoa.s (4365B)
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$ 100100$: 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' 128103$: 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 141105$: 142 dec de 143 ld a, (de) 144 cp a, #0x30 145 jr NZ, 107$ ;break loop if non-zero found 146 djnz 105$ 147107$: 148 inc de ;always point to symbol next to last significant 149 ex de, hl 150 jr 190$ 151; 152;--------------------------- 153; 154110$: 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 166120$: 167 ld a, e 168 ld b, c 169125$: 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 182130$: 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; 196150$: 197 ex de, hl 198 ld c, e 199 ld b, d 200 ld e, 6 (ix) 201 ld d, 7 (ix) 202160$: 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 211165$: 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 226190$: 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 240100$: 241 add hl, hl 242 rl e 243 rl d 244 rla 245 jr c, 110$ 246 cp a, c 247 jr c, 120$ 248110$: 249 sub a, c 250 inc l 251120$: 252 djnz 100$ 253 ret 254