Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;*****************************************************************************
  2. ;*
  3. ;*                            Open Watcom Project
  4. ;*
  5. ;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. ;*
  7. ;*  ========================================================================
  8. ;*
  9. ;*    This file contains Original Code and/or Modifications of Original
  10. ;*    Code as defined in and that are subject to the Sybase Open Watcom
  11. ;*    Public License version 1.0 (the 'License'). You may not use this file
  12. ;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. ;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. ;*    provided with the Original Code and Modifications, and is also
  15. ;*    available at www.sybase.com/developer/opensource.
  16. ;*
  17. ;*    The Original Code and all software distributed under the License are
  18. ;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. ;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. ;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. ;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. ;*    NON-INFRINGEMENT. Please see the License for the specific language
  23. ;*    governing rights and limitations under the License.
  24. ;*
  25. ;*  ========================================================================
  26. ;*
  27. ;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
  28. ;*               DESCRIBE IT HERE!
  29. ;*
  30. ;*****************************************************************************
  31.  
  32.  
  33. ; This module converts a string to long_double
  34. ;       void __ZBuf2LD( char *buf, long_double *value );
  35. ;
  36. include mdef.inc
  37. include struct.inc
  38.  
  39.         modstart bufld386
  40.  
  41.         xdefp   __ZBuf2LD
  42.  
  43. ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
  44. ;<>                                                                   <>
  45. ;<>   __ZBuf2LD - convert buffer of significant digits into floating  <>
  46. ;<>             void __ZBuf2LD( char *buf, long_double *value )       <>
  47. ;<>                                                                   <>
  48. ;<>   input:  EAX - address of buffer of significant digits           <>
  49. ;<>           EDX - place to store value                              <>
  50. ;<>   output: [EDX]        - floating-point number                    <>
  51. ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
  52.  
  53.         defpe   __ZBuf2LD
  54.         push    EBP             ; save EBP
  55.         push    ESI             ; save ESI
  56.         push    EDI             ; save EDI
  57.         push    ECX             ; save ECX
  58.         push    EBX             ; save EBX
  59.         push    EDX             ; save pointer to result
  60.         mov     ESI,EAX         ; get address of buffer
  61.         sub     EDX,EDX         ; set 96-bit integer to 0
  62.         sub     ECX,ECX         ; ...
  63.         sub     EBP,EBP         ; ...
  64.         sub     EAX,EAX         ; zero out EAX
  65.         _loop                   ; loop (convert digits into 64-bit int)
  66.           mov   AL,[ESI]        ; - get next digit
  67.           cmp   AL,0            ; - quit if at end of buffer
  68.           _quif e               ; - . . .
  69.  
  70. ;[]  multiply current value in EDX:ECX:EBP by 10
  71.  
  72.           mov   EDI,EDX         ; - save current value
  73.           mov   EBX,ECX         ; - ...
  74.           mov   EAX,EBP         ; - ...
  75.           _shl  EBP,1           ; - multiply number by 4
  76.           _rcl  ECX,1           ; -   by shifting left 2 places
  77.           _rcl  EDX,1           ; - ...
  78.           _shl  EBP,1           ; - ...
  79.           _rcl  ECX,1           ; - ...
  80.           _rcl  EDX,1           ; - ...
  81.           add   EBP,EAX         ; - add original value
  82.           adc   ECX,EBX         ; -  (this will make it times 5)
  83.           adc   EDX,EDI         ; - ...
  84.           _shl  EBP,1           ; - shift left to make it times 10
  85.           _rcl  ECX,1           ; - ...
  86.           _rcl  EDX,1           ; - ...
  87.           sub   EAX,EAX         ; - zero eax
  88.           mov   AL,[ESI]        ; - get next digit
  89.           and   AL,0Fh          ; - isolate binary digit
  90.           add   EBP,EAX         ; - add in current digit
  91.           adc   ECX,0           ; - ...
  92.           adc   EDX,0           ; - ...
  93.           inc   ESI             ; - point to next digit in buffer
  94.         _endloop                ; endloop
  95.         mov     EAX,ECX         ; get low order word into EAX
  96.  
  97. ;[] Turn the integer in EDX:EAX:EBP into a real number
  98.  
  99.         mov     EDI,3FFFh+63+32 ; set exponent
  100.         call    Norm            ; convert the 64 bit integer to a float
  101.         pop     EBP             ; restore pointer to result
  102.         mov     4[EBP],EDX      ; store result
  103.         mov     0[EBP],EAX      ; ...
  104.         mov     8[EBP],SI       ; ...
  105.         pop     EBX             ; restore EBX
  106.         pop     ECX             ; restore ECX
  107.         pop     EDI             ; restore EDI
  108.         pop     ESI             ; restore ESI
  109.         pop     EBP             ; restore EBP
  110.         ret                     ; return to caller
  111.         endproc __ZBuf2LD
  112.  
  113.  
  114. ;[] Norm normalizes an unsigned real in EDX:EAX:EBP i.e grab top 64 bits
  115. ;[] expects the exponent to be in EDI.
  116. ;[]     SI contains the new exponent
  117.  
  118. Norm    proc    near            ; normalize floating point number
  119.         sub     ESI,ESI         ; clear out SI
  120.         or      ESI,EAX         ; see if the integer is zero
  121.         or      ESI,EDX         ; ...
  122.         or      ESI,EBP         ; ...
  123.         _if     ne              ; if number is non-zero
  124.           or    EDX,EDX         ; - see if high word is 0
  125.           _if   e               ; - if high word is 0
  126.             mov   EDX,EAX       ; - - shift by 32-bits
  127.             mov   EAX,EBP       ; - - ...
  128.             sub   EBP,EBP       ; - - ...
  129.             sub   EDI,32        ; - - adjust exponent by 32
  130.           _endif                ; - endif
  131.           or    EDX,EDX         ; - see if high word is 0
  132.           _if   e               ; - if high word is 0
  133.             mov   EDX,EAX       ; - - shift by 32-bits
  134.             mov   EAX,EBP       ; - - ...
  135.             sub   EBP,EBP       ; - - ...
  136.             sub   EDI,32        ; - - adjust exponent by 32
  137.           _endif                ; - endif
  138.           _loop                 ; - loop
  139.             or    EDX,EDX       ; - - quit if high bit is on
  140.             _quif s             ; - - ...
  141.             dec   EDI           ; - - decrement exponent
  142.             _shl  EBP,1         ; - - shift integer left by 1 bit
  143.             _rcl  EAX,1         ; - - ...
  144.             _rcl  EDX,1         ; - - ...
  145.           _endloop              ; - endloop
  146.           _shl  EBP,1           ; - get top bit of extra word
  147.           adc   EAX,0           ; - round up
  148.           adc   EDX,0           ; - ...
  149.           _if   c               ; - if carry out the top
  150.             rcr   EDX,1         ; - - shift fraction back 1
  151.             inc   EDI           ; - - increment exponent
  152.           _endif                ; - endif
  153.           mov   ESI,EDI         ; - get exponent
  154.         _endif                  ; endif
  155.         ret                     ; return
  156.         endproc Norm
  157.  
  158.         endmod
  159.         end
  160.