;-- ; ; File: ftoa.asm ; Author: George Gallant ; Date: 19OCT04 ; ; This routine provides a floating point to ascii conversion. ; It was written support the SDCC project. ; ; SDCC C Syntax: ; ; extern void g_ftoa(data char *buf, float num, char precision); ; ; The routine is NOT reenterant but expects the entire parameter list ; to be placed on the stack. ; ; Notes: 1. measured 105usec to convert -65535.996 on a 20MHz 18f252 ; 2. Software stack can not cross a RAM page boundary ; ;-- list r=dec, n=96, st=off, mm=off nolist include list udata extern digits exp: res 1 man: res 4 r: res 5 x: res 3 bp: res 2 prec: res 1 ctr: res 1 code extern cvt_dec_word global _g_ftoa _g_ftoa: movff FSR2H,POSTDEC1 movff FSR2L,POSTDEC1 movff FSR1H,FSR2H movff FSR1L,FSR2L movff exp, POSTDEC1 movff man+0, POSTDEC1 movff man+1, POSTDEC1 movff man+2, POSTDEC1 movff man+3, POSTDEC1 movff r+0, POSTDEC1 movff r+1, POSTDEC1 movff r+2, POSTDEC1 movff r+3, POSTDEC1 movff r+4, POSTDEC1 movff x+0, POSTDEC1 movff x+1, POSTDEC1 movff bp+0, POSTDEC1 movff bp+1, POSTDEC1 movff prec, POSTDEC1 movff ctr, POSTDEC1 movff FSR0H,POSTDEC1 movff FSR0L,POSTDEC1 movlw 3 addwf FSR2L, f btfsc STATUS,C incf FSR2H, f movff POSTINC2,FSR0L ;get the low byte of buf pointer movff POSTINC2,FSR0H movff POSTINC2,man+0 ;get the low byte of float movff POSTINC2,man+1 movff POSTINC2,man+2 movff POSTINC2,exp movff POSTINC2,prec rlcf man+2,w rlcf exp,f bnc @1 movlw '-' movwf POSTINC0 @1: movff man+0,r+0 movff man+1,r+1 movff man+2,r+2 bsf r+2,7 clrf r+3 clrf r+4 ; Shift the mantissa left or right by the expondent movf exp,w ;get the expondent sublw 127 ;subtract the bais bz @4 ;skip shifting if zero bn @3 ;shift left if neg @2: bcf STATUS,C ;otherwise, shift right rrcf r+4,f rrcf r+3,f rrcf r+2,f rrcf r+1,f rrcf r+0,f decfsz WREG,w bra @2 bra @4 @3: bcf STATUS,C rlcf r+0, f rlcf r+1, f rlcf r+2, f rlcf r+3, f rlcf r+4, f incfsz WREG,w bra @3 @4: rlcf r+2,w ;extract bit 23 rlcf r+3,f ;shift rest of whole number rlcf r+4,f movff r+3,PRODL movff r+4,PRODH call cvt_dec_word movlw '.' movwf POSTINC0 @10: movlw 0x7F andwf r+2,f clrf r+3 movff r+0,x+0 ;temp copy movff r+1,x+1 movff r+2,x+2 bcf STATUS,C ;mult by 2 rlcf r+0,f rlcf r+1,f rlcf r+2,f rlcf r+3,f bcf STATUS,C ;mult by 4 rlcf r+0,f rlcf r+1,f rlcf r+2,f rlcf r+3,f movf x+0,w ;mult by 5 addwf r+0,f movf x+1,w addwfc r+1,f movf x+2,w addwfc r+2,f movlw 0 addwfc r+3,f rlcf r+2,w ;div by 0x400000 rlcf r+3,f ;or just extract bits 24-22 rlcf WREG,w rlcf r+3,f movf r+3,w ;this is the bcd value addlw 0x30 ;convert to ascii movwf POSTINC0 ;and save in memory bcf STATUS,C ;mult by 2 rlcf r+0,f rlcf r+1,f rlcf r+2,f decfsz prec,f bra @10 clrf POSTINC0 ;pack a nullbyte at the end movff ctr, POSTDEC1 movff prec, POSTDEC1 movff bp+1, POSTDEC1 movff bp+0, POSTDEC1 movff x+1, POSTDEC1 movff x+0, POSTDEC1 movff r+4, POSTDEC1 movff r+3, POSTDEC1 movff r+2, POSTDEC1 movff r+1, POSTDEC1 movff r+0, POSTDEC1 movff man+3, POSTDEC1 movff man+2, POSTDEC1 movff man+1, POSTDEC1 movff man+0, POSTDEC1 movff exp, POSTDEC1 movff PREINC1,FSR0L movff PREINC1,FSR0H movff PREINC1,FSR2L movff PREINC1,FSR2H return end