AsciiFloat     PROTO :DWORD

RNum10     REAL10  ?
BaseVal        dd  10   ; Base value = 2, 8, 10, or 16

;=================================================================
; Converts ascii string of Dec, Hex, Oct or Bin to a REAL10 value.
;=================================================================
;INVOKE     AsciiToFloat, addr szBuff (Max of 16 bytes for szBuff)
AsciiFloat PROC InPut:DWORD
LOCAL    Min:DWORD, Work

      pushad
         and     Min, 0
      INVOKE     lstrlen, InPut  ; Input
         cmp     eax, 0
         je      GetOut
         xor     ecx, ecx

         mov     edx, InPut
      .while (eax)
      .if byte ptr [edx] > 60h
            sub     byte ptr [edx], 57h
      .elseif byte ptr [edx] > 40h
            sub     byte ptr [edx], 37h
      .elseif byte ptr [edx] == 2eh
            mov     byte ptr [edx], 2eh
      .elseif byte ptr [edx] == 2dh
            or     Min, 1
      .else
            sub     byte ptr [edx], 30h
      .endif
         inc     ecx
         inc     edx
         dec     eax
      .endw

      .if ecx == 0
            inc     ecx
      .endif    
         mov     ebx, InPut         ; Ascii string
         mov     esi, ebx
         add     esi, ecx           ; Set esi at the end of szBuff
         dec     esi
      .if Min == 1
            dec     ecx
            inc     ebx
      .endif 
       finit
        fldz                        ; Initialize ST(0) = 0

Loop1:                              ; Loop before the decimal point
         xor     eax, eax           ; Set eax=0 for later
         mov     al, byte ptr[ebx]
         inc     ebx
         cmp     al, '.'
         je      Loop2
         mov     Work, eax          ; Set Work to number for loading
        fild     BaseVal            ; Load base for adding next digit
       fmulp     ST(1), ST          ; ST(1)=ST(1)*ST & pop ST(0)
        fild     Work               ; Load Work integer to ST(0)
       faddp     ST(1), ST          ; ST(1)=ST(1)+ST & pop ST(0)
        loop     Loop1              ; Next part of loop
        fldz                        ; Load a zero for decimal places
         jmp     NoMore             ; No more characters

Loop2:                              ; Now esi is used for an index
        fldz                        ; Load another zero for the decimal portion

Loop3:                              ; The actual loop after the decimal point
         dec     ecx
         jz      NoMore             ; If out of characters or last one was a '.'
         mov     al, byte ptr[esi]  ; get next character   *******************
         dec     esi
         mov     Work, eax          ; Store to Work
        fild     Work               ; Load Work
       faddp     ST(1), ST          ; Add new char to old value
        fild     BaseVal            ; Load base
       fdivp     ST(1), ST          ; Divide by base to retain decimal
         jmp     Loop3

NoMore:
       faddp     ST(1), ST          ; Add integer & decimal
      .if Min == 1
           fchs
      .endif
        fstp     tbyte ptr[RNum10]  ; Store real
GetOut:
       popad
         RET
AsciiFloat ENDP
