Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / pic16 / libc / stdlib / g_ftoa.S
1 ;--
2 ;
3 ;       File:   ftoa.asm
4 ;       Author: George Gallant
5 ;       Date:   19OCT04
6 ;
7 ;       This routine provides a floating point to ascii conversion.
8 ;       It was written support the SDCC project.
9 ;
10 ;       SDCC C Syntax:
11 ;
12 ;       extern void g_ftoa(data char *buf, float num, char precision);
13 ;
14 ;       The routine is NOT reenterant but expects the entire parameter list
15 ;       to be placed on the stack.
16 ;
17 ;       Notes:  1. measured 105usec to convert -65535.996 on a 20MHz 18f252
18 ;               2. Software stack can not cross a RAM page boundary
19 ;
20 ;--
21                 list    r=dec, n=96, st=off, mm=off
22
23                 nolist
24                 include         <p18fxxx.inc>
25                 list
26
27                 udata
28
29                 extern  digits
30
31 exp:            res     1
32 man:            res     4
33 r:              res     5
34 x:              res     3
35 bp:             res     2
36 prec:           res     1
37 ctr:            res     1
38
39                 code
40
41                 extern  cvt_dec_word
42                 global  _g_ftoa
43
44 _g_ftoa:        movff   FSR2H,POSTDEC1
45                 movff   FSR2L,POSTDEC1
46
47                 movff   FSR1H,FSR2H
48                 movff   FSR1L,FSR2L
49
50                 movff   exp, POSTDEC1
51                 movff   man+0, POSTDEC1
52                 movff   man+1, POSTDEC1
53                 movff   man+2, POSTDEC1
54                 movff   man+3, POSTDEC1
55                 movff   r+0, POSTDEC1
56                 movff   r+1, POSTDEC1
57                 movff   r+2, POSTDEC1
58                 movff   r+3, POSTDEC1
59                 movff   r+4, POSTDEC1
60                 movff   x+0, POSTDEC1
61                 movff   x+1, POSTDEC1
62                 movff   bp+0, POSTDEC1
63                 movff   bp+1, POSTDEC1
64                 movff   prec, POSTDEC1
65                 movff   ctr, POSTDEC1
66
67                 movff   FSR0H,POSTDEC1
68                 movff   FSR0L,POSTDEC1
69
70                 movlw   3
71                 addwf   FSR2L, f
72                 btfsc   STATUS,C
73                 incf    FSR2H, f
74
75                 movff   POSTINC2,FSR0L          ;get the low byte of buf pointer
76                 movff   POSTINC2,FSR0H
77
78                 movff   POSTINC2,man+0          ;get the low byte of float
79                 movff   POSTINC2,man+1
80                 movff   POSTINC2,man+2
81                 movff   POSTINC2,exp
82
83                 movff   POSTINC2,prec
84
85                 rlcf    man+2,w
86                 rlcf    exp,f
87                 bnc     @1
88                 movlw   '-'
89                 movwf   POSTINC0
90
91 @1:             movff   man+0,r+0
92                 movff   man+1,r+1
93                 movff   man+2,r+2
94                 bsf     r+2,7
95                 clrf    r+3
96                 clrf    r+4
97
98 ;       Shift the mantissa left or right by the expondent
99
100                 movf    exp,w                   ;get the expondent
101                 sublw   127                     ;subtract the bais
102                 bz      @4                      ;skip shifting if zero
103                 bn      @3                      ;shift left if neg
104
105 @2:             bcf     STATUS,C                ;otherwise, shift right
106                 rrcf    r+4,f
107                 rrcf    r+3,f
108                 rrcf    r+2,f
109                 rrcf    r+1,f
110                 rrcf    r+0,f
111                 decfsz  WREG,w
112                 bra     @2
113                 bra     @4
114
115 @3:             bcf     STATUS,C
116                 rlcf    r+0, f
117                 rlcf    r+1, f
118                 rlcf    r+2, f
119                 rlcf    r+3, f
120                 rlcf    r+4, f
121                 incfsz  WREG,w
122                 bra     @3
123
124 @4:             rlcf    r+2,w                   ;extract bit 23
125                 rlcf    r+3,f                   ;shift rest of whole number
126                 rlcf    r+4,f
127
128                 movff   r+3,PRODL
129                 movff   r+4,PRODH
130                 call    cvt_dec_word
131
132                 movlw   '.'
133                 movwf   POSTINC0
134
135 @10:            movlw   0x7F                    
136                 andwf   r+2,f
137                 clrf    r+3
138
139                 movff   r+0,x+0                 ;temp copy
140                 movff   r+1,x+1
141                 movff   r+2,x+2
142
143                 bcf     STATUS,C                ;mult by 2
144                 rlcf    r+0,f
145                 rlcf    r+1,f
146                 rlcf    r+2,f
147                 rlcf    r+3,f
148
149                 bcf     STATUS,C                ;mult by 4
150                 rlcf    r+0,f
151                 rlcf    r+1,f
152                 rlcf    r+2,f
153                 rlcf    r+3,f
154
155                 movf    x+0,w                   ;mult by 5
156                 addwf   r+0,f
157                 movf    x+1,w
158                 addwfc  r+1,f
159                 movf    x+2,w
160                 addwfc  r+2,f
161                 movlw   0
162                 addwfc  r+3,f
163
164                 rlcf    r+2,w                   ;div by 0x400000                        
165                 rlcf    r+3,f                   ;or just extract bits 24-22
166                 rlcf    WREG,w
167                 rlcf    r+3,f
168
169                 movf    r+3,w                   ;this is the bcd value
170                 addlw   0x30                    ;convert to ascii
171                 movwf   POSTINC0                ;and save in memory
172
173                 bcf     STATUS,C                ;mult by 2
174                 rlcf    r+0,f
175                 rlcf    r+1,f
176                 rlcf    r+2,f
177
178                 decfsz  prec,f
179                 bra     @10
180
181                 clrf    POSTINC0                ;pack a nullbyte at the end
182
183
184                 movff   ctr, POSTDEC1
185                 movff   prec, POSTDEC1
186                 movff   bp+1, POSTDEC1
187                 movff   bp+0, POSTDEC1
188                 movff   x+1, POSTDEC1
189                 movff   x+0, POSTDEC1
190                 movff   r+4, POSTDEC1
191                 movff   r+3, POSTDEC1
192                 movff   r+2, POSTDEC1
193                 movff   r+1, POSTDEC1
194                 movff   r+0, POSTDEC1
195                 movff   man+3, POSTDEC1
196                 movff   man+2, POSTDEC1
197                 movff   man+1, POSTDEC1
198                 movff   man+0, POSTDEC1
199                 movff   exp, POSTDEC1
200
201                 movff   PREINC1,FSR0L
202                 movff   PREINC1,FSR0H
203
204                 movff   PREINC1,FSR2L
205                 movff   PREINC1,FSR2H
206                 return
207
208                 end