home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wunderki.zip / DF87.ASM < prev    next >
Assembly Source File  |  1993-08-16  |  7KB  |  499 lines

  1.  
  2. ; *******************************************************
  3. ; *                            *
  4. ; *     Turbo Pascal Run-time Library                   *
  5. ; *    8087 Binary/Decimal Routines            *
  6. ; *                            *
  7. ; *     Copyright (c) 1988,92 Borland International     *
  8. ; *                            *
  9. ; *******************************************************
  10.  
  11.     TITLE    DF87
  12.  
  13.     INCLUDE    SE.ASM
  14.  
  15. CODE    SEGMENT    BYTE PUBLIC
  16.  
  17.     ASSUME    CS:CODE
  18.  
  19. ; Externals
  20.  
  21.     EXTRN    Str2Int:NEAR
  22.  
  23. ; Publics
  24.  
  25.     PUBLIC    Float2Str,Str2Float
  26.  
  27. ; Constants
  28.  
  29. DCon1E0        DD    1
  30. DCon1E1        DD    10
  31. DCon1E2        DD    100
  32. DCon1E3        DD    1000
  33. DCon1E4        DD    10000
  34. DCon1E5        DD    100000
  35. DCon1E6        DD    1000000
  36. DCon1E7        DD    10000000
  37. FCon1E8        DT    1E8
  38. FCon1E16    DT    1E16
  39. FCon1E32    DT    1E32
  40. FCon1E64    DT    1E64
  41. FCon1E128    DT    1E128
  42. FCon1E256    DT    1E256
  43. FCon1E512    DT    1E512
  44. FCon1E1024    DT    1E1024
  45. FCon1E2048    DT    1E2048
  46. FCon1E4096    DT    1E4096
  47. FCon1E18    DT    1E18
  48. FConINF        DT    07FFF8000000000000000R
  49.  
  50. ; 8087 control word
  51.  
  52. CWNear        DW    133FH
  53.  
  54. ; Convert float to string
  55. ; In    CX    = Digit count (Float<0, Fixed>=0)
  56. ;    ES:DI = String pointer
  57. ;    ST(0) = Value
  58. ; Out    CX    = String length
  59. ;    ES:DI = String pointer
  60.  
  61. Float2Str:
  62.  
  63.     LOC    CtrlWord,WORD,1
  64.     LOC    StatWord,WORD,1
  65.     LOC    Digits,WORD,1
  66.     LOC    Exponent,WORD,1
  67.     LOC    Sign,WORD,1
  68.     LOC    Value,TBYTE,1
  69.     LOC    DigitBuf,BYTE,20
  70.  
  71.     ENTRY
  72.     FSTCW    CtrlWord
  73.     FLDCW    CWNear
  74.     FSTP    Value
  75.     PUSH    DI
  76.     CMP    CX,18
  77.     JLE    @@1
  78.     MOV    CX,18
  79. @@1:    CMP    CX,-18
  80.     JGE    @@2
  81.     MOV    CX,-18
  82. @@2:    MOV    Digits,CX
  83.     CLD
  84.     FWAIT
  85.     MOV    AX,Value.w8
  86.     MOV    Sign,AX
  87.     AND    AX,7FFFH
  88.     JE    @@5
  89.     CMP    AX,7FFFH
  90.     JNE    @@10
  91.     CMP    Value.w6,8000H
  92.     JE    @@3
  93.     MOV    AX,'AN'
  94.     STOSW
  95.     MOV    AL,'N'
  96.     STOSB
  97.     JMP    @@90
  98. @@3:    CMP    Sign,0
  99.     JNS    @@4
  100.     MOV    AL,'-'
  101.     STOSB
  102. @@4:    MOV    AX,'NI'
  103.     STOSW
  104.     MOV    AL,'F'
  105.     STOSB
  106.     JMP    @@90
  107. @@5:    MOV    Exponent,AX
  108.     MOV    DigitBuf,AL
  109.     JMP    @@30
  110. @@10:    MOV    Value.w8,AX
  111.     FLD    Value
  112.     SUB    AX,3FFFH
  113.     MOV    DX,19728
  114.     IMUL    DX
  115.     MOV    Exponent,DX
  116.     MOV    AX,17
  117.     SUB    AX,DX
  118.     CALL    Power10
  119.     FRNDINT
  120.     FLD    FCon1E18
  121.     FCOMP
  122.     FSTSW    StatWord
  123.     FWAIT
  124.     TEST    StatWord,mC0+mC3
  125.     JE    @@11
  126.     FIDIV    DCon1E1
  127.     INC    Exponent
  128. @@11:
  129.     IF WindowsVersion
  130.     CMP    BYTE PTR CS:@@12,0CDH
  131.     JNE    @@12
  132.     PUSH    ES
  133.     PUSH    DI
  134.     LEA    DI,DigitBuf
  135.     PUSH    SS
  136.     POP    ES
  137.     CALL    FStoreBCD
  138.     POP    DI
  139.     POP    ES
  140.     JMP    SHORT @@20
  141.     ENDIF
  142. @@12:    FBSTP    Value
  143.     LEA    BX,DigitBuf
  144.     MOV    CL,4
  145.     MOV    SI,9
  146.     FWAIT
  147. @@13:    MOV    AL,Value[SI-1].b0
  148.     MOV    AH,AL
  149.     SHR    AL,CL
  150.     AND    AH,0FH
  151.     ADD    AX,'00'
  152.     MOV    SS:[BX],AX
  153.     INC    BX
  154.     INC    BX
  155.     DEC    SI
  156.     JNE    @@13
  157.     MOV    SS:[BX],SI
  158. @@20:    CMP    Digits,0
  159.     JL    @@21
  160.     CMP    Exponent,36
  161.     JL    @@21
  162.     MOV    Digits,-18
  163. @@21:    MOV    SI,Digits
  164.     OR    SI,SI
  165.     JS    @@22
  166.     ADD    SI,Exponent
  167.     INC    SI
  168.     JNS    @@23
  169.     MOV    DigitBuf,0
  170.     JMP    SHORT @@30
  171. @@22:    NEG    SI
  172. @@23:    CMP    SI,18
  173.     JAE    @@30
  174.     CMP    DigitBuf[SI],'5'
  175.     MOV    DigitBuf[SI],0
  176.     JB    @@30
  177. @@24:    DEC    SI
  178.     JS    @@25
  179.     INC    DigitBuf[SI]
  180.     CMP    DigitBuf[SI],'9'
  181.     JBE    @@30
  182.     MOV    DigitBuf[SI],0
  183.     JMP    SHORT @@24
  184. @@25:    MOV    DigitBuf.w0,'1'
  185.     INC    Exponent
  186. @@30:    XOR    SI,SI
  187.     MOV    DX,Digits
  188.     OR    DX,DX
  189.     JS    @@40
  190.     CMP    Sign,0
  191.     JNS    @@31
  192.     MOV    AL,'-'
  193.     STOSB
  194. @@31:    MOV    CX,Exponent
  195.     OR    CX,CX
  196.     JNS    @@32
  197.     MOV    AL,'0'
  198.     STOSB
  199.     JMP    SHORT @@33
  200. @@32:    CALL    GetDigit
  201.     STOSB
  202.     DEC    CX
  203.     JNS    @@32
  204. @@33:    OR    DX,DX
  205.     JE    @@90
  206.     MOV    AL,'.'
  207.     STOSB
  208. @@34:    INC    CX
  209.     JE    @@35
  210.     MOV    AL,'0'
  211.     STOSB
  212.     DEC    DX
  213.     JNE    @@34
  214. @@35:    DEC    DX
  215.     JS    @@90
  216.     CALL    GetDigit
  217.     STOSB
  218.     JMP    SHORT @@35
  219. @@40:    MOV    AL,' '
  220.     CMP    Sign,0
  221.     JNS    @@46
  222.     MOV    AL,'-'
  223. @@46:    STOSB
  224.     CALL    GetDigit
  225.     STOSB
  226.     INC    DX
  227.     JE    @@42
  228.     MOV    AL,'.'
  229.     STOSB
  230. @@41:    CALL    GetDigit
  231.     STOSB
  232.     INC    DX
  233.     JNE    @@41
  234. @@42:    MOV    AL,'E'
  235.     STOSB
  236.     MOV    AL,'+'
  237.     MOV    DX,Exponent
  238.     OR    DX,DX
  239.     JNS    @@43
  240.     MOV    AL,'-'
  241.     NEG    DX
  242. @@43:    STOSB
  243.     MOV    AX,(100*256)+10
  244.     XCHG    AX,DX
  245.     DIV    DH
  246.     MOV    DH,AH
  247.     CBW
  248.     DIV    DL
  249.     ADD    AX,'00'
  250.     STOSW
  251.     MOV    AL,DH
  252.     CBW
  253.     DIV    DL
  254.     ADD    AX,'00'
  255.     STOSW
  256. @@90:    MOV    CX,DI
  257.     POP    DI
  258.     SUB    CX,DI
  259.     FCLEX
  260.     FLDCW    CtrlWord
  261.     FWAIT
  262.     EXIT
  263.  
  264. ; Get digit from digit buffer
  265.  
  266. GetDigit:
  267.  
  268.     MOV    AL,DigitBuf[SI]
  269.     INC    SI
  270.     OR    AL,AL
  271.     JNE    @@1
  272.     MOV    AL,'0'
  273.     DEC    SI
  274. @@1:    RET
  275.  
  276. ; Convert string to float
  277. ; In    CX    = String length
  278. ;    ES:DI = String pointer
  279. ; Out    CX    = Remaining characters
  280. ;    ES:DI = Pointer past string
  281. ;    CF    = 1 if error
  282. ;    ST(0) = Value
  283.  
  284. Str2Float:
  285.  
  286.     LOC    CtrlWord,WORD,1
  287.     LOC    TempWord,WORD,1
  288.     LOC    SignChar,BYTE,1
  289.     LOC    ExpoChar,BYTE,1
  290.  
  291.     ENTRY
  292.     FSTCW    CtrlWord
  293.     FCLEX
  294.     FLDCW    CWNear
  295.     FLDZ
  296.     JCXZ    @@7
  297.     MOV    AL,ES:[DI]
  298.     MOV    SignChar,AL
  299.     CMP    AL,' '
  300.     JE    @@1
  301.     CMP    AL,'+'
  302.     JE    @@1
  303.     CMP    AL,'-'
  304.     JNE    @@2
  305. @@1:    INC    DI
  306.     DEC    CX
  307. @@2:    PUSH    CX
  308.     CALL    DigitStr
  309.     XOR    BX,BX
  310.     JCXZ    @@3
  311.     MOV    AL,ES:[DI]
  312.     CMP    AL,'.'
  313.     JNE    @@3
  314.     INC    DI
  315.     DEC    CX
  316.     CALL    DigitStr
  317.     NEG    BX
  318. @@3:    POP    AX
  319.     CMP    AX,CX
  320.     JE    @@7
  321.     JCXZ    @@5
  322.     MOV    AL,ES:[DI]
  323.     CMP    AL,'E'
  324.     JE    @@4
  325.     CMP    AL,'e'
  326.     JNE    @@5
  327. @@4:    INC    DI
  328.     DEC    CX
  329.     PUSH    BX
  330.     CALL    Str2Int
  331.     POP    BX
  332.     JC    @@7
  333.     MOV    SI,DX
  334.     CWD
  335.     CMP    SI,DX
  336.     JNE    @@7
  337.     CMP    AX,4999
  338.     JGE    @@7
  339.     CMP    AX,-4999
  340.     JLE    @@7
  341.     ADD    BX,AX
  342. @@5:    MOV    AX,BX
  343.     CALL    Power10
  344.     CMP    SignChar,'-'
  345.     JNE    @@6
  346.     FCHS
  347. @@6:    FSTSW    TempWord
  348.     FWAIT
  349.     TEST    TempWord,mIE+mOE
  350.     JE    @@8
  351. @@7:    STC
  352. @@8:    FCLEX
  353.     FLDCW    CtrlWord
  354.     FWAIT
  355.     EXIT
  356.  
  357. ; Process string of digits
  358. ; Out    BX = Digit count
  359.  
  360. DigitStr:
  361.  
  362.     XOR    BX,BX
  363. @@1:    JCXZ    @@2
  364.     MOV    AL,ES:[DI]
  365.     SUB    AL,'0'+10
  366.     ADD    AL,10
  367.     JNC    @@2
  368.     FIMUL    DCon1E1
  369.     CBW
  370.     MOV    TempWord,AX
  371.     FIADD    TempWord
  372.     INC    BX
  373.     INC    DI
  374.     DEC    CX
  375.     JMP    @@1
  376. @@2:    RET
  377.  
  378. ; Multiply ST(0) by 10^AX
  379. ; In    AX = Power of 10
  380.  
  381. Power10:
  382.  
  383.     CMP    AX,4096
  384.     JLE    @@1
  385.     FLD    FCon1E4096
  386.     FMUL
  387.     SUB    AX,4096
  388. @@1:    CMP    AX,-4096
  389.     JGE    @@2
  390.     FLD    FCon1E4096
  391.     FDIV
  392.     ADD    AX,4096
  393. @@2:    MOV    BX,AX
  394.     OR    AX,AX
  395.     JE    @@8
  396.     JNS    @@3
  397.     NEG    AX
  398. @@3:    MOV    SI,AX
  399.     AND    SI,7
  400.     SHL    SI,1
  401.     SHL    SI,1
  402.     FILD    DCon1E0[SI]
  403.     SHR    AX,1
  404.     SHR    AX,1
  405.     SHR    AX,1
  406.     MOV    SI,OFFSET FCon1E8
  407.     JMP    SHORT @@6
  408. @@4:    SHR    AX,1
  409.     JNC    @@5
  410.     FLD    TBYTE PTR CS:[SI]
  411.     FMUL
  412. @@5:    ADD    SI,10
  413. @@6:    OR    AX,AX
  414.     JNE    @@4
  415.     OR    BX,BX
  416.     JS    @@7
  417.     FMUL
  418.     RET
  419. @@7:    FDIV
  420. @@8:    RET
  421.  
  422.     IF WindowsVersion
  423.  
  424. ; Store ST(0) as 18 decimal digits
  425. ; In    ES:DI = Digit buffer pointer
  426.  
  427. FStoreBCD:
  428.  
  429.     ADD    DI,18
  430.     XOR    AX,AX
  431.     STD
  432.     STOSW
  433.     SUB    SP,8
  434.     MOV    SI,SP
  435.     FISTP    QWORD PTR SS:[SI]
  436.     FWAIT
  437.     POP    BX
  438.     POP    CX
  439.     POP    AX
  440.     POP    DX
  441.     MOV    SI,10000
  442.     DIV    SI        ;CX:BX:AX = DX:AX:CX:BX div 10000
  443.     XCHG    AX,CX
  444.     DIV    SI
  445.     XCHG    AX,BX
  446.     DIV    SI
  447.     CALL    StoreDigits
  448.     XOR    DX,DX        ;BX:CX:AX = CX:BX:AX div 10000
  449.     XCHG    AX,CX
  450.     DIV    SI
  451.     XCHG    AX,BX
  452.     DIV    SI
  453.     XCHG    AX,CX
  454.     DIV    SI
  455.     CALL    StoreDigits
  456.     MOV    DX,BX        ;CX:AX = BX:CX:AX div 10000
  457.     XCHG    AX,CX
  458.     DIV    SI
  459.     XCHG    AX,CX
  460.     DIV    SI
  461.     CALL    StoreDigits
  462.     MOV    DX,CX        ;AX = CX:AX div 10000
  463.     DIV    SI
  464.     CALL    StoreDigits
  465.     AAM
  466.     XCHG    AL,AH
  467.     ADD    AX,'00'
  468.     STOSW
  469.     CLD
  470.     RET
  471.  
  472. ; Store four BCD digits
  473.  
  474. StoreDigits:
  475.  
  476.     PUSH    AX
  477.     MOV    AL,100
  478.     XCHG    AX,DX
  479.     DIV    DL
  480.     MOV    DL,AH
  481.     AAM
  482.     ADD    AX,'00'
  483.     XCHG    AL,AH
  484.     XCHG    AX,DX
  485.     AAM
  486.     ADD    AX,'00'
  487.     XCHG    AL,AH
  488.     STOSW
  489.     XCHG    AX,DX
  490.     STOSW
  491.     POP    AX
  492.     RET
  493.  
  494.     ENDIF
  495.  
  496. CODE    ENDS
  497.  
  498.     END
  499.