home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CASM.ARJ / FREXP.ASM < prev    next >
Assembly Source File  |  1988-09-06  |  2KB  |  134 lines

  1. ;_ frexp.asm   Mon Feb 15 1988   Modified by: Walter Bright */
  2. ; Written by Walter Bright
  3. ; Copyright (C) 1984-1988 by Northwest Software
  4. ; All rights reserved
  5.  
  6.     include    macros.asm
  7.  
  8.     .8087
  9.  
  10.     begdata
  11.     c_extrn    _8087,word
  12.     enddata
  13.  
  14.     begcode    frexp
  15.  
  16. longexp    =    07FF0h
  17. longbias =    03FFh
  18.  
  19. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20. ;
  21. ;    double frexp(value,eptr)
  22. ;    double value;
  23. ;    int *eptr;
  24. ; Returns:
  25. ;    x such that value=x*2**n, .5 < |x| <= 1.0
  26. ;    x has same sign as value.
  27. ;    if value is 0, x and *eptr are 0.
  28. ;    *eptr = n
  29.  
  30.     c_public frexp
  31.  
  32. func    frexp
  33.     push    BP
  34.     mov    BP,SP
  35.     .if    _8087 e 0, FR4        ;if no 8087
  36.     fld    qword ptr P[BP]
  37.     fxtract
  38.     fstp    qword ptr P[BP]
  39.     if SPTR
  40.     mov    BX,P+8[BP]
  41.     fistp    word ptr [BX]        ;store *eptr
  42.     else ;LPTR
  43.     les    BX,P+8[BP]
  44.     fistp    word ptr ES:[BX]
  45.     endif
  46.     mov    AX,P+6[BP]
  47.     mov    CX,P+2[BP]
  48.     mov    DX,P+0[BP]
  49.     fwait
  50.     if SPTR
  51.     .if    <word ptr [BX]> e 08000h, FR5        ;check for -infinity
  52.     else
  53.     .if    <word ptr ES:[BX]> e 08000h, FR5    ;check for -infinity
  54.     endif
  55. FR6:    mov    BX,P+4[BP]
  56.     pop    BP
  57.     ret
  58.  
  59.     ;The 80387 gives -infinity as a result if value is 0.0. To
  60.     ;conform to ANSI, set *eptr to 0. The 8087 and 80287 already yield 0.
  61. FR5:
  62.     if SPTR
  63.     shl    word ptr [BX],1        ;make it 0
  64.     else
  65.     shl    word ptr ES:[BX],1    ;make it 0
  66.     endif
  67.     jmp    FR6
  68.  
  69. FR4:    .save    <DI>
  70.     mov    AX,P+6[BP]
  71.     mov    BX,P+4[BP]
  72.     mov    CX,P+2[BP]
  73.     mov    DX,P+0[BP]
  74.  
  75.     mov    DI,AX
  76.     shl    DI,1
  77.     or    DI,BX
  78.     or    DI,CX
  79.     or    DI,DX            ;is value 0?
  80.  
  81.     if LPTR
  82.     les    DI,P+8[BP]        ;ES:DI = eptr
  83.     else
  84.     mov    DI,P+8[BP]        ;DI = eptr
  85.     endif
  86.     jz    FR1            ;yes
  87.  
  88.     and    AX,longexp        ;isolate exponent
  89.     shr    AX,1
  90.     shr    AX,1
  91.     shr    AX,1
  92.     shr    AX,1            ;right justify it
  93.     sub    AX,longbias        ;un-bias it
  94.     if LPTR
  95.     mov    ES:[DI],AX
  96.     else
  97.     mov    [DI],AX
  98.     endif
  99.     mov    AX,P+6[BP]
  100.     and    AX,800Fh            ;scrap exponent bits
  101.     push    AX
  102.     shl    AX,1
  103.     or    AX,BX
  104.     or    AX,CX
  105.     or    AX,DX
  106.     pop    AX                ;see if even power of 2
  107.     jz    FR3                ;yes
  108.     if LPTR
  109.     inc    word ptr ES:[DI]
  110.     else
  111.     inc    word ptr [DI]
  112.     endif
  113.     or    AX,(longbias - 1) SHL 4        ;to get .5 < |x| <= 1
  114.     jmps    FR2
  115.  
  116. FR3:    or    AX,(longbias) SHL 4        ;to get .5 < |x| <= 1
  117. FR2:    .restore <DI>
  118.     pop    BP
  119.     ret
  120.  
  121. FR1:
  122.     if LPTR
  123.     mov    ES:[DI],BX        ;*eptr = 0
  124.     else
  125.     mov    [DI],BX            ;*eptr = 0
  126.     endif
  127.     jmp    FR2
  128.  
  129. c_endp    frexp
  130.  
  131.     endcode    frexp
  132.  
  133.     end
  134.