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