PLBuff         db  50 dup(?),0
PRBuff         db  50 dup(?),0
ConvO          db  120 dup(?),0
ErrorMsg       db  '** The output is out of range **            ',0

Work           dd  ?
Base4          dd  ?
w1             dd  ?
RNum10     REAL10  ?

CWNoRound    WORD  0f7fh
BaseVal        dd  10   ; Base value = 2, 8, 10, or 16

;================================================================
; Converts a REAL10 value to a Dec, Hex, Oct or Bin ascii string.
; The input total has a maximun of 18 digits (interger & decimal)
; The input interger has a maximun of 9 digits
; The input decimal has a maximun of 18 digits
; The output decimal positions is 12
;================================================================
;         mov     edx, offset RNum10
;        call     FloatToAscii

FloatToAscii  PROC  uses ebx esi edi
LOCAL     sw1:DWORD

         mov     PLBuff, 0
         mov     byte ptr PRBuff, 0
         mov     esi, offset PRBuff
         mov     ebx, edx          ; Input
       fldcw     CWNoRound
         fld     tbyte ptr[ebx]    ; Load number
         fst     Work
         and     Work, 80000000h
         cmp     Work, 80000000h
         jnz     PlusNum
         mov     Work, 1
        fchs                       ; Changes sign 
PlusNum:
         fld     ST(0)             ; Duplicate
       fistp     Base4
      .if Base4 > 7fffffffh
            jmp     DoError
      .endif
      INVOKE     BaseToAscii, Base4, addr PLBuff, 0, BaseVal, 1, 0, 1 ; Convert the DWORD to Ascii
        fild     Base4             ; ST(0) : xxxxx,  ST(1) : xxxxx.yyyyy
       fsubp     ST(1), ST(0)      ; ST(0) = 0.yyyyy
         fst     Work
         cmp     Work, 0
         jz      Buildit           ; No decimal
         mov     byte ptr[esi], 2eh
         mov     byte ptr[esi+1], 0
         inc     esi
         mov     dx,sp             ; Save stack pointer
         xor     ecx,ecx
         mov     edi,edx

CalcDec:
        fild     BaseVal           ; Base 10, 16, 8, 2
       fmulp     ST(1), ST(0)
         fld     ST(0)             ; Duplicate
        call     Extend
        fist     Work              ; looks good at this point first int after dec
       fsubp     ST(1), ST(0)
         mov     eax, Work
      .if eax == 19999999h
         mov     ebx, esp
         jmp     GetOut
      .endif
      .if al > 9h
            add     al, 37h        ; Convert to hex ASCII
      .else
            add     al, 30h        ; Convert to dec ASCII
      .endif
         mov     byte ptr[esi], al ; Ascii output
         mov     byte ptr[esi+1], 0
         inc     esi
         inc     ecx
         cmp     ecx, 12 ;19 ;20  ;12  ;15
         jnz     CalcDec
         mov     ebx, esp

GetOut:
         mov     edx, edi
         mov     SP, DX            ; Restore SP
         mov     byte ptr[esi], 0

Buildit:
      INVOKE     lstrcpy, addr ConvO, addr PLBuff      ; Non decimal number
      INVOKE     lstrcat, addr ConvO, addr PRBuff      ; Decimal number
        fstp     Work              ; Get rid of ST(0)
         cmp     PRBuff, 0
         je      Exit
      INVOKE     lstrlen, offset PLBuff
      .if eax > 11
DoError:
         INVOKE     lstrcpy, addr ConvO, addr ErrorMsg ; Error
            mov     PLBuff, 0
            mov     PRBuff, 0
           fldz
           fstp     RNum10     
            jmp     Exit
      .endif
jmp     Exit

;---------- [If you want to do some type of rounding] ----------
         and     sw1, 0
      INVOKE     lstrlen, offset ConvO
         mov     edx, offset ConvO
         add     edx, eax
      .while (eax)
         .if byte ptr [edx]-1 == 39h   
               mov     byte ptr [edx]-1, '0'
               mov     sw1, 1
         .elseif sw1
               inc     byte ptr [edx]-1
            .break
         .endif
            dec     eax
            dec     edx
      .endw

Exit:
         RET
FloatToAscii  ENDP

;*************************************************************************************      
Extend   PROC
        fild     BaseVal           ; base 10, 16, 8, 2
       fmulp     ST(1), ST(0)
       fistp     w1
         mov     eax, w1
         xor     edx, edx
         div     BaseVal           ; base 10, 16, 8, 2
         mov     w1, eax
        fild     w1
         RET
Extend   ENDP
