1 2SECTION code_clib 3SECTION code_stdlib 4 5PUBLIC __dtoe__, __dtoe_join 6 7EXTERN __dtoa_preamble, asm_fpclassify, __dtoa_special_form, __dtoa_base10, __dtoa_adjust_prec 8EXTERN __dtoa_digits, __dtoa_round, __dtoa_remove_zeroes, __dtoa_postamble, __dtoa_exp_digit 9 10; math library supplies asm_fpclassify, __dtoa_base10, __dtoa_digits, __dtoa_sgnabs 11 12__dtoe__: 13 14 ; enter : c = flags (bit 4=#, bits 7 and 0 will be modified) 15 ; de = precision (clipped at 255) 16 ; hl = buffer * 17 ; exx set contains float 18 ; 19 ; exit : if carry reset 20 ; 21 ; bc = buffer length 22 ; de = buffer * 23 ; (IX-6) = flags, bit 7 = 'N', bit 4 = '#', bit 1 = %g, bit 0 = precision==0 24 ; (IX-5) = iz (number of zeroes to insert before .) 25 ; (IX-4) = fz (number of zeroes to insert after .) 26 ; (IX-3) = tz (number of zeroes to append) 27 ; (IX-2) = ignore 28 ; (IX-1) = '0' marks start of buffer 29 ; 30 ; if carry set, special form just output buffer with sign 31 ; 32 ; used : af, bc, de, hl, ix, af', bc', de', hl' 33 34 call __dtoa_preamble 35 36 ; EXX = double x 37 ; E = precision 38 ; HL = buffer_dst * 39 ; IX = buffer * 40 ; (IX-6) = flags, bit 7 = 'N', bit 4 = '#', bit 1 = %g, bit 0 = precision==0 41 ; (IX-5) = iz (number of zeroes to insert before .) 42 ; (IX-4) = fz (number of zeroes to insert after .) 43 ; (IX-3) = tz (number of zeroes to append) 44 ; (IX-2) = ignore 45 ; (IX-1) = '0' marks start of buffer 46 47 call asm_fpclassify ; supplied by math library 48 49 or a 50 jr z, normal_form ; if not inf, nan or zero 51 52 call __dtoa_special_form 53 54 jr nc, prune ; if zero 55 ret ; return with carry set if inf or nan 56 57normal_form: 58 59 ld (hl),e ; save precision 60 push hl ; save buffer * 61 62 ; EXX = float x 63 ; IX = buffer * 64 ; STACK = buffer * 65 ; (IX-6) = flags, bit 7 = 'N', bit 4 = '#', bit 1 = %g, bit 0 = precision==0 66 ; (IX-5) = iz (number of zeroes to insert before .) 67 ; (IX-4) = fz (number of zeroes to insert after .) 68 ; (IX-3) = tz (number of zeroes to append) 69 ; (IX-2) = ignore 70 ; (IX-1) = '0' marks start of buffer 71 72 call __dtoa_base10 ; supplied by math library 73 74 pop hl ; hl = buffer * 75 ld e,(hl) ; e = precision 76 77 call __dtoa_adjust_prec ; if precision == 255, set to max sig digits - 1 78 jr nz, __dtoe_join 79 dec e 80 81__dtoe_join: 82 83 ; EXX = float in form b(*10^e), 1 <= b < 10 mantissa only 84 ; C = remaining significant digits 85 ; D = base 10 exponent e 86 ; E = remaining precision 87 ; HL = buffer_dst * 88 ; IX = buffer * 89 ; (IX-6) = flags, bit 7 = 'N', bit 4 = '#', bit 1 = %g, bit 0 = precision==0 90 ; (IX-5) = iz (number of zeroes to insert before .) 91 ; (IX-4) = fz (number of zeroes to insert after .) 92 ; (IX-3) = tz (number of zeroes to append) 93 ; (IX-2) = ignore 94 ; (IX-1) = '0' marks start of buffer 95 96 ld b,1 97 call __dtoa_digits ; single digit left of decimal 98 99 ld (hl),'.' 100 inc hl 101 102 ld b,e 103 inc b 104 105 call __dtoa_digits ; generate precision + 1 digits 106 jr c, round ; if all precision digits generated 107 108 dec b 109 ld (ix-3),b ; add trailing zeroes 110 111 jr prune 112 113round: 114 115 call __dtoa_round 116 117 ld a,(ix-1) 118 cp '0' 119 jr z, prune ; if round did not affect carry digit 120 121 ld a,(ix+0) ; move decimal point left 122 ld (ix+1),a 123 ld (ix+0),'.' 124 125 inc d 126 dec hl ; remove extra precision digit 127 128prune: 129 130 call __dtoa_remove_zeroes ; remove trailing zeroes 131 132 ; D = base 10 exponent e 133 ; HL = buffer_dst * 134 ; IX = buffer * 135 ; (IX-6) = flags, bit 7 = 'N', bit 4 = '#', bit 1 = %g, bit 0 = precision==0 136 ; (IX-5) = iz (number of zeroes to insert before .) 137 ; (IX-4) = fz (number of zeroes to insert after .) 138 ; (IX-3) = tz (number of zeroes to append) 139 ; (IX-2) = ignore 140 ; (IX-1) = '0' marks start of buffer 141 142 ld (hl),'E' 143 inc hl 144 ld (hl),'+' 145 146 ld a,d ; a = exponent 147 or a 148 jp p, exponent_plus 149 150 ld (hl),'-' 151 neg 152 153exponent_plus: 154 155 inc hl ; hl = buffer_dst * 156 157 cp 100 158 jr c, skip_100 159 160 sub 100 161 162 ld (hl),'1' 163 inc hl 164 165skip_100: 166 167 ld de,$0a00 + '0' - 1 168 call __dtoa_exp_digit ; 10s 169 170 add a,'0' ; 1s 171 172 ld (hl),a 173 inc hl 174 175 ; HL = buffer_dst * 176 ; IX = buffer * 177 ; (IX-6) = flags, bit 7 = 'N', bit 4 = '#', bit 1 = %g, bit 0 = precision==0 178 ; (IX-5) = iz (number of zeroes to insert before .) 179 ; (IX-4) = fz (number of zeroes to insert after .) 180 ; (IX-3) = tz (number of zeroes to append) 181 ; (IX-2) = ignore 182 ; (IX-1) = '0' marks start of buffer 183 184 jp __dtoa_postamble ; return buffer pointer and length 185