home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 April / Chip_1997-04_cd.bin / prezent / cb / data.z / FFMT.ASM < prev    next >
Assembly Source File  |  1997-01-16  |  16KB  |  1,112 lines

  1.  
  2. ; *******************************************************
  3. ; *                            *
  4. ; *     Delphi Runtime Library                          *
  5. ; *    Floating point formatting routines        *
  6. ; *                            *
  7. ; *    Copyright (c) 1995,96 Borland International    *
  8. ; *                            *
  9. ; *******************************************************
  10.  
  11.     TITLE    FFMT
  12.  
  13.     .386
  14.     .MODEL    FLAT
  15.  
  16.     INCLUDE    SE.ASM
  17.  
  18. ; TFloatRec layout
  19.  
  20. fdExponent    EQU    (WORD PTR 0)
  21. fdNegative    EQU    (BYTE PTR 2)
  22. fdDigits    EQU    (BYTE PTR 3)
  23. fdRecSize    EQU    24
  24.  
  25. ; TFloatValue constants
  26.  
  27. fvExtended    EQU    0
  28. fvCurrency    EQU    1
  29.  
  30. ; TFloatFormat constants
  31.  
  32. ffGeneral    EQU    0
  33. ffExponent    EQU    1
  34. ffFixed        EQU    2
  35. ffNumber    EQU    3
  36. ffCurrency    EQU    4
  37.  
  38. ; 1E18 as a 64-bit integer
  39.  
  40. Const1E18Lo    EQU    0A7640000H
  41. Const1E18Hi    EQU    00DE0B6B3H
  42.  
  43. ; Externals
  44.  
  45.     EXTRN    FPower10:NEAR
  46.     EXTRN    CurrencyString:DWORD
  47.     EXTRN    CurrencyFormat:BYTE
  48.     EXTRN    NegCurrFormat:BYTE
  49.     EXTRN    ThousandSeparator:BYTE
  50.     EXTRN    DecimalSeparator:BYTE
  51.  
  52. ; Publics
  53.  
  54.     PUBLIC    FloatToText,FloatToTextFmt,FloatToDecimal,TextToFloat
  55.  
  56.     .CODE
  57.  
  58. ; Constants
  59.  
  60. DCon10        DD    10
  61. DCon100        DD    100
  62. DCon1000    DD    1000
  63. DCon10000    DD    10000
  64.  
  65. FCon1E18    DT    1E18
  66.  
  67. ; 8087 control word
  68. ; Infinity control  = 1 Affine
  69. ; Rounding Control  = 0 Round to nearest or even
  70. ; Precision Control = 3 64 bits
  71. ; All interrupts masked
  72.  
  73. CWNear        DW    133FH
  74.  
  75. ; INF and NAN strings
  76.  
  77. INFNAN        DB    'INFNAN'
  78.  
  79. ; function FloatToText(Buffer: PChar; const Value; ValueType: TFloatValue;
  80. ;   Format: TFloatFormat; Precision, Digits: Integer): Integer;
  81.  
  82. FloatToText:
  83.  
  84.     ARG    BufferArg,DWORD,1
  85.     ARG    Value,DWORD,1
  86.     ARG    ValueType,BYTE,4
  87.     ARG    Format,BYTE,4
  88.     ARG    Precision,DWORD,1
  89.     ARG    Digits,DWORD,1
  90.     LOC    Buffer,DWORD,1
  91.     LOC    FloatRec,BYTE,fdRecSize
  92.  
  93.     ENTRY    FAR
  94.     PUSH    EDI
  95.     PUSH    ESI
  96.     PUSH    EBX
  97.     MOV    Buffer,EAX
  98.     MOV    EAX,19
  99.     CMP    CL,fvExtended
  100.     JNE    @@2
  101.     MOV    EAX,Precision
  102.     CMP    EAX,2
  103.     JGE    @@1
  104.     MOV    EAX,2
  105. @@1:    CMP    EAX,18
  106.     JLE    @@2
  107.     MOV    EAX,18
  108. @@2:    MOV    Precision,EAX
  109.     PUSH    EAX
  110.     MOV    EAX,9999
  111.     CMP    Format,ffFixed
  112.     JB    @@3
  113.     MOV    EAX,Digits
  114. @@3:    PUSH    EAX
  115.     LEA    EAX,FloatRec
  116.     CALL    FloatToDecimal
  117.     MOV    EDI,Buffer
  118.     MOVZX    EAX,FloatRec.fdExponent
  119.     SUB    EAX,7FFFH
  120.     CMP    EAX,2
  121.     JAE    @@4
  122.     LEA    ESI,INFNAN[EAX+EAX*2]
  123.     MOV    ECX,3
  124.     REP    MOVSB
  125.     JMP    @@7
  126. @@4:    LEA    ESI,FloatRec.fdDigits
  127.     MOVZX    EBX,Format
  128.     CMP    BL,ffExponent
  129.     JE    @@6
  130.     CMP    BL,ffCurrency
  131.     JA    @@5
  132.     MOVSX    EAX,FloatRec.fdExponent
  133.     CMP    EAX,Precision
  134.     JLE    @@6
  135. @@5:    MOV    BL,ffGeneral
  136. @@6:    CALL    DWORD PTR FormatVector[EBX*4]
  137. @@7:    MOV    EAX,EDI
  138.     SUB    EAX,Buffer
  139.     POP    EBX
  140.     POP    ESI
  141.     POP    EDI
  142.     EXIT
  143.  
  144. FormatVector    LABEL    DWORD
  145.  
  146.     DD    PutFGeneral
  147.     DD    PutFExponent
  148.     DD    PutFFixed
  149.     DD    PutFNumber
  150.     DD    PutFCurrency
  151.  
  152. ; Get digit or '0' if at end of digit string
  153.  
  154. GetDigit:
  155.  
  156.     LODSB
  157.     OR    AL,AL
  158.     JNE    @@1
  159.     MOV    AL,'0'
  160.     DEC    ESI
  161. @@1:    RET
  162.  
  163. ; Store '-' if number is negative
  164.  
  165. PutSign:
  166.  
  167.     CMP    FloatRec.fdNegative,0
  168.     JE    @@1
  169.     MOV    AL,'-'
  170.     STOSB
  171. @@1:    RET
  172.  
  173. ; Convert number using ffGeneral format
  174.  
  175. PutFGeneral:
  176.  
  177.     CALL    PutSign
  178.     MOVSX    ECX,FloatRec.fdExponent
  179.     XOR    EDX,EDX
  180.     CMP    ECX,Precision
  181.     JG    @@1
  182.     CMP    ECX,-3
  183.     JL    @@1
  184.     OR    ECX,ECX
  185.     JG    @@2
  186.     MOV    AL,'0'
  187.     STOSB
  188.     CMP    BYTE PTR [ESI],0
  189.     JE    @@6
  190.     MOV    AL,DecimalSeparator
  191.     STOSB
  192.     NEG    ECX
  193.     MOV    AL,'0'
  194.     REP    STOSB
  195.     JMP    @@3
  196. @@1:    MOV    ECX,1
  197.     INC    EDX
  198. @@2:    LODSB
  199.     OR    AL,AL
  200.     JE    @@4
  201.     STOSB
  202.     LOOP    @@2
  203.     LODSB
  204.     OR    AL,AL
  205.     JE    @@5
  206.     MOV    AH,AL
  207.     MOV    AL,DecimalSeparator
  208.     STOSW
  209. @@3:    LODSB
  210.     OR    AL,AL
  211.     JE    @@5
  212.     STOSB
  213.     JMP    @@3
  214. @@4:    MOV    AL,'0'
  215.     REP    STOSB
  216. @@5:    OR    EDX,EDX
  217.     JE    @@6
  218.     XOR    EAX,EAX
  219.     XOR    ECX,ECX
  220.     JMP    PutFloatExp
  221. @@6:    RET
  222.  
  223. ; Convert number using ffExponent format
  224.  
  225. PutFExponent:
  226.  
  227.     CALL    PutSign
  228.     CALL    GetDigit
  229.     MOV    AH,DecimalSeparator
  230.     STOSW
  231.     MOV    ECX,Precision
  232.     DEC    ECX
  233. @@1:    CALL    GetDigit
  234.     STOSB
  235.     LOOP    @@1
  236.     MOV    AH,'+'
  237.     MOV    ECX,Digits
  238.     CMP    ECX,4
  239.     JB    PutFloatExp
  240.     XOR    ECX,ECX
  241. ;    JMP    PutFloatExp
  242.  
  243. ; Store exponent
  244. ; In    AH  = Positive sign character ('+' or 0)
  245. ;    ECX = Minimum number of digits (0..4)
  246.  
  247. PutFloatExp:
  248.  
  249.     MOV    AL,'E'
  250.     MOV    BL,FloatRec.fdDigits
  251.     MOVSX    EDX,FloatRec.fdExponent
  252.     DEC    EDX
  253. ;    JMP    PutExponent
  254.  
  255. ; Store exponent
  256. ; In    AL  = Exponent character ('E' or 'e')
  257. ;    AH  = Positive sign character ('+' or 0)
  258. ;    BL  = Zero indicator
  259. ;    ECX = Minimum number of digits (0..4)
  260. ;    EDX = Exponent
  261.  
  262. PutExponent:
  263.  
  264.     STOSB
  265.     OR    BL,BL
  266.     JNE    @@0
  267.     XOR    EDX,EDX
  268.     JMP    @@1
  269. @@0:    OR    EDX,EDX
  270.     JGE    @@1
  271.     MOV    AL,'-'
  272.     NEG    EDX
  273.     JMP    @@2
  274. @@1:    OR    AH,AH
  275.     JE    @@3
  276.     MOV    AL,AH
  277. @@2:    STOSB
  278. @@3:    XCHG    EAX,EDX
  279.     PUSH    EAX
  280.     MOV    EBX,ESP
  281. @@4:    XOR    EDX,EDX
  282.     DIV    DCon10
  283.     ADD    DL,'0'
  284.     MOV    [EBX],DL
  285.     INC    EBX
  286.     DEC    ECX
  287.     OR    EAX,EAX
  288.     JNE    @@4
  289.     OR    ECX,ECX
  290.     JG    @@4
  291. @@5:    DEC    EBX
  292.     MOV    AL,[EBX]
  293.     STOSB
  294.     CMP    EBX,ESP
  295.     JNE    @@5
  296.     POP    EAX
  297.     RET
  298.  
  299. ; Convert number using ffFixed or ffNumber format
  300.  
  301. PutFFixed:
  302. PutFNumber:
  303.  
  304.     CALL    PutSign
  305.  
  306. ; Store number in fixed point format
  307.  
  308. PutNumber:
  309.  
  310.     MOV    EDX,Digits
  311.     CMP    EDX,18
  312.     JB    @@1
  313.     MOV    EDX,18
  314. @@1:    MOVSX    ECX,FloatRec.fdExponent
  315.     OR    ECX,ECX
  316.     JG    @@2
  317.     MOV    AL,'0'
  318.     STOSB
  319.     JMP    @@4
  320. @@2:    XOR    EBX,EBX
  321.     CMP    Format,ffFixed
  322.     JE    @@3
  323.     MOV    EAX,ECX
  324.     DEC    EAX
  325.     MOV    BL,3
  326.     DIV    BL
  327.     MOV    BL,AH
  328.     INC    EBX
  329. @@3:    CALL    GetDigit
  330.     STOSB
  331.     DEC    ECX
  332.     JE    @@4
  333.     DEC    EBX
  334.     JNE    @@3
  335.     MOV    AL,ThousandSeparator
  336.     STOSB
  337.     MOV    BL,3
  338.     JMP    @@3
  339. @@4:    OR    EDX,EDX
  340.     JE    @@7
  341.     MOV    AL,DecimalSeparator
  342.     STOSB
  343.     JECXZ    @@6
  344.     MOV    AL,'0'
  345. @@5:    STOSB
  346.     DEC    EDX
  347.     JE    @@7
  348.     INC    ECX
  349.     JNE    @@5
  350. @@6:    CALL    GetDigit
  351.     STOSB
  352.     DEC    EDX
  353.     JNE    @@6
  354. @@7:    RET
  355.  
  356. ; Convert number using ffCurrency format
  357.  
  358. PutFCurrency:
  359.  
  360.     XOR    EBX,EBX
  361.     MOV    BL,CurrencyFormat
  362.     MOV    ECX,0003H
  363.     CMP    FloatRec.fdNegative,0
  364.     JE    @@1
  365.     MOV    BL,NegCurrFormat
  366.     MOV    ECX,040FH
  367. @@1:    CMP    BL,CL
  368.     JBE    @@2
  369.     MOV    BL,CL
  370. @@2:    ADD    BL,CH
  371.     LEA    EBX,MoneyFormats[EBX+EBX*4]
  372.     MOV    ECX,5
  373. @@10:    MOV    AL,[EBX]
  374.     CMP    AL,'@'
  375.     JE    @@14
  376.     PUSH    ECX
  377.     PUSH    EBX
  378.     CMP    AL,'$'
  379.     JE    @@11
  380.     CMP    AL,'*'
  381.     JE    @@12
  382.     STOSB
  383.     JMP    @@13
  384. @@11:    CALL    PutCurSym
  385.     JMP    @@13
  386. @@12:    CALL    PutNumber
  387. @@13:    POP    EBX
  388.     POP    ECX
  389.     INC    EBX
  390.     LOOP    @@10
  391. @@14:    RET
  392.  
  393. ; Store currency symbol string
  394.  
  395. PutCurSym:
  396.  
  397.     PUSH    ESI
  398.     MOV    ESI,CurrencyString
  399.     TEST    ESI,ESI
  400.     JE    @@1
  401.     MOV    ECX,[ESI-4]
  402.     REP    MOVSB
  403. @@1:    POP    ESI
  404.     RET
  405.  
  406. ; Currency formatting templates
  407.  
  408. MoneyFormats    LABEL    BYTE
  409.  
  410.     DB    '$*@@@'
  411.     DB    '*$@@@'
  412.     DB      '$ *@@'
  413.     DB    '* $@@'
  414.     DB    '($*)@'
  415.     DB    '-$*@@'
  416.     DB    '$-*@@'
  417.     DB    '$*-@@'
  418.     DB    '(*$)@'
  419.     DB    '-*$@@'
  420.     DB    '*-$@@'
  421.     DB    '*$-@@'
  422.     DB    '-* $@'
  423.     DB    '-$ *@'
  424.     DB    '* $-@'
  425.     DB    '$ *-@'
  426.     DB    '$ -*@'
  427.     DB    '*- $@'
  428.     DB    '($ *)'
  429.     DB    '(* $)'
  430.  
  431. ; function FloatToTextFmt(Buffer: PChar; const Value; ValueType: TValueType;
  432. ;   Format: PChar): Integer;
  433.  
  434. FloatToTextFmt:
  435.  
  436.     ARG    BufferArg,DWORD,1
  437.     ARG    Value,DWORD,1
  438.     ARG    ValueType,BYTE,4
  439.     ARG    Format,DWORD,1
  440.     LOC    Buffer,DWORD,1
  441.     LOC    ThousandSep,BYTE,4
  442.     LOC    Scientific,BYTE,4
  443.     LOC    Section,DWORD,1
  444.     LOC    DigitCount,DWORD,1
  445.     LOC    DecimalIndex,DWORD,1
  446.     LOC    FirstDigit,DWORD,1
  447.     LOC    LastDigit,DWORD,1
  448.     LOC    DigitPlace,DWORD,1
  449.     LOC    DigitDelta,DWORD,1
  450.     LOC    FloatRec,BYTE,fdRecSize
  451.  
  452.     ENTRY    FAR
  453.     PUSH    EDI
  454.     PUSH    ESI
  455.     PUSH    EBX
  456.     MOV    Buffer,EAX
  457.     MOV    EDI,EDX
  458.     MOV    EBX,ECX
  459.     MOV    ECX,2
  460.     CMP    BL,fvExtended
  461.     JE    @@1
  462.     MOV    EAX,[EDI].d0
  463.     OR    EAX,[EDI].d4
  464.     JE    @@2
  465.     MOV    ECX,[EDI].d4
  466.     SHR    ECX,31
  467.     JMP    @@2
  468. @@1:    MOVZX    EAX,[EDI].w8
  469.     OR    EAX,[EDI].d0
  470.     OR    EAX,[EDI].d4
  471.     JE    @@2
  472.     MOVZX    ECX,[EDI].w8
  473.     SHR    ECX,15
  474. @@2:    CALL    FindSection
  475.     JE    @@5
  476.     CALL    ScanSection
  477.     MOV    EAX,DigitCount
  478.     MOV    EDX,9999
  479.     CMP    Scientific,0
  480.     JNE    @@3
  481.     SUB    EAX,DecimalIndex
  482.     MOV    EDX,EAX
  483.     MOV    EAX,18
  484. @@3:    PUSH    EAX
  485.     PUSH    EDX
  486.     LEA    EAX,FloatRec
  487.     MOV    EDX,EDI
  488.     MOV    ECX,EBX
  489.     CALL    FloatToDecimal
  490.     MOV    AX,FloatRec.fdExponent
  491.     CMP    AX,8000H
  492.     JE    @@5
  493.     CMP    AX,7FFFH
  494.     JE    @@5
  495.     CMP    BL,fvExtended
  496.     JNE    @@6
  497.     CMP    AX,18
  498.     JLE    @@6
  499.     CMP    Scientific,0
  500.     JNE    @@6
  501. @@5:    PUSH    ffGeneral
  502.     PUSH    15
  503.     PUSH    0
  504.     MOV    EAX,Buffer
  505.     MOV    EDX,EDI
  506.     MOV    ECX,EBX
  507.     CALL    FloatToText
  508.     JMP    @@8
  509. @@6:    CMP    FloatRec.fdDigits,0
  510.     JNE    @@7
  511.     MOV    ECX,2
  512.     CALL    FindSection
  513.     JE    @@5
  514.     CMP    ESI,Section
  515.     JE    @@7
  516.     CALL    ScanSection
  517. @@7:    CALL    ApplyFormat
  518. @@8:    POP    EBX
  519.     POP    ESI
  520.     POP    EDI
  521.     EXIT
  522.  
  523. ; Find format section
  524. ; In    ECX = Section index
  525. ; Out    ESI = Section offset
  526. ;    ZF  = 1 if section is empty
  527.  
  528. FindSection:
  529.  
  530.     MOV    ESI,Format
  531.     JECXZ    @@2
  532. @@1:    LODSB
  533.     CMP    AL,"'"
  534.     JE    @@4
  535.     CMP    AL,'"'
  536.     JE    @@4
  537.     OR    AL,AL
  538.     JE    @@2
  539.     CMP    AL,';'
  540.     JNE    @@1
  541.     LOOP    @@1
  542.     MOV    AL,[ESI]
  543.     OR    AL,AL
  544.     JE    @@2
  545.     CMP    AL,';'
  546.     JNE    @@3
  547. @@2:    MOV    ESI,Format
  548.     MOV    AL,[ESI]
  549.     OR    AL,AL
  550.     JE    @@3
  551.     CMP    AL,';'
  552. @@3:    RET
  553. @@4:    MOV    AH,AL
  554. @@5:    LODSB
  555.     CMP    AL,AH
  556.     JE    @@1
  557.     OR    AL,AL
  558.     JNE    @@5
  559.     JMP    @@2
  560.  
  561. ; Scan format section
  562.  
  563. ScanSection:
  564.  
  565.     PUSH    EBX
  566.     MOV    Section,ESI
  567.     MOV    EBX,32767
  568.     XOR    ECX,ECX
  569.     XOR    EDX,EDX
  570.     MOV    DecimalIndex,-1
  571.     MOV    ThousandSep,DL
  572.     MOV    Scientific,DL
  573. @@1:    LODSB
  574. @@2:    CMP    AL,'#'
  575.     JE    @@10
  576.     CMP    AL,'0'
  577.     JE    @@11
  578.     CMP    AL,'.'
  579.     JE    @@13
  580.     CMP    AL,','
  581.     JE    @@14
  582.     CMP    AL,"'"
  583.     JE    @@15
  584.     CMP    AL,'"'
  585.     JE    @@15
  586.     CMP    AL,'E'
  587.     JE    @@20
  588.     CMP    AL,'e'
  589.     JE    @@20
  590.     CMP    AL,';'
  591.     JE    @@30
  592.     OR    AL,AL
  593.     JNE    @@1
  594.     JMP    @@30
  595. @@10:    INC    EDX
  596.     JMP    @@1
  597. @@11:    CMP    EDX,EBX
  598.     JGE    @@12
  599.     MOV    EBX,EDX
  600. @@12:    INC    EDX
  601.     MOV    ECX,EDX
  602.     JMP    @@1
  603. @@13:    CMP    DecimalIndex,-1
  604.     JNE    @@1
  605.     MOV    DecimalIndex,EDX
  606.     JMP    @@1
  607. @@14:    MOV    ThousandSep,1
  608.     JMP    @@1
  609. @@15:    MOV    AH,AL
  610. @@16:    LODSB
  611.     CMP    AL,AH
  612.     JE    @@1
  613.     OR    AL,AL
  614.     JNE    @@16
  615.     JMP    @@30
  616. @@20:    LODSB
  617.     CMP    AL,'-'
  618.     JE    @@21
  619.     CMP    AL,'+'
  620.     JNE    @@2
  621. @@21:    MOV    Scientific,1
  622. @@22:    LODSB
  623.     CMP    AL,'0'
  624.     JE    @@22
  625.     JMP    @@2
  626. @@30:    MOV    DigitCount,EDX
  627.     CMP    DecimalIndex,-1
  628.     JNE    @@31
  629.     MOV    DecimalIndex,EDX
  630. @@31:    MOV    EAX,DecimalIndex
  631.     SUB    EAX,ECX
  632.     JLE    @@32
  633.     XOR    EAX,EAX
  634. @@32:    MOV    LastDigit,EAX
  635.     MOV    EAX,DecimalIndex
  636.     SUB    EAX,EBX
  637.     JGE    @@33
  638.     XOR    EAX,EAX
  639. @@33:    MOV    FirstDigit,EAX
  640.     POP    EBX
  641.     RET
  642.  
  643. ; Apply format string
  644.  
  645. ApplyFormat:
  646.  
  647.     CMP    Scientific,0
  648.     JE    @@1
  649.     MOV    EAX,DecimalIndex
  650.     XOR    EDX,EDX
  651.     JMP    @@3
  652. @@1:    MOVSX    EAX,FloatRec.fdExponent
  653.     CMP    EAX,DecimalIndex
  654.     JG    @@2
  655.     MOV    EAX,DecimalIndex
  656. @@2:    MOVSX    EDX,FloatRec.fdExponent
  657.     SUB    EDX,DecimalIndex
  658. @@3:    MOV    DigitPlace,EAX
  659.     MOV    DigitDelta,EDX
  660.     MOV    ESI,Section
  661.     MOV    EDI,Buffer
  662.     LEA    EBX,FloatRec.fdDigits
  663.     CMP    FloatRec.fdNegative,0
  664.     JE    @@10
  665.     CMP    ESI,Format
  666.     JNE    @@10
  667.     MOV    AL,'-'
  668.     STOSB
  669. @@10:    LODSB
  670.     CMP    AL,'#'
  671.     JE    @@20
  672.     CMP    AL,'0'
  673.     JE    @@20
  674.     CMP    AL,'.'
  675.     JE    @@10
  676.     CMP    AL,','
  677.     JE    @@10
  678.     CMP    AL,"'"
  679.     JE    @@25
  680.     CMP    AL,'"'
  681.     JE    @@25
  682.     CMP    AL,'E'
  683.     JE    @@30
  684.     CMP    AL,'e'
  685.     JE    @@30
  686.     CMP    AL,';'
  687.     JE    @@40
  688.     OR    AL,AL
  689.     JE    @@40
  690. @@11:    STOSB
  691.     JMP    @@10
  692. @@20:    CALL    PutFmtDigit
  693.     JMP    @@10
  694. @@25:    MOV    AH,AL
  695. @@26:    LODSB
  696.     CMP    AL,AH
  697.     JE    @@10
  698.     OR    AL,AL
  699.     JE    @@40
  700.     STOSB
  701.     JMP    @@26
  702. @@30:    MOV    AH,[ESI]
  703.     CMP    AH,'+'
  704.     JE    @@31
  705.     CMP    AH,'-'
  706.     JNE    @@11
  707.     XOR    AH,AH
  708. @@31:    MOV    ECX,-1
  709. @@32:    INC    ECX
  710.     INC    ESI
  711.     CMP    [ESI].b0,'0'
  712.     JE    @@32
  713.     CMP    ECX,4
  714.     JB    @@33
  715.     MOV    ECX,4
  716. @@33:    PUSH    EBX
  717.     MOV    BL,FloatRec.fdDigits
  718.     MOVSX    EDX,FloatRec.fdExponent
  719.     SUB    EDX,DecimalIndex
  720.     CALL    PutExponent
  721.     POP    EBX
  722.     JMP    @@10
  723. @@40:    MOV    EAX,EDI
  724.     SUB    EAX,Buffer
  725.     RET
  726.  
  727. ; Store formatted digit
  728.  
  729. PutFmtDigit:
  730.  
  731.     CMP    DigitDelta,0
  732.     JE    @@3
  733.     JL    @@2
  734. @@1:    CALL    @@3
  735.     DEC    DigitDelta
  736.     JNE    @@1
  737.     JMP    @@3
  738. @@2:    INC    DigitDelta
  739.     MOV    EAX,DigitPlace
  740.     CMP    EAX,FirstDigit
  741.     JLE    @@4
  742.     JMP    @@7
  743. @@3:    MOV    AL,[EBX]
  744.     INC    EBX
  745.     OR    AL,AL
  746.     JNE    @@5
  747.     DEC    EBX
  748.     MOV    EAX,DigitPlace
  749.     CMP    EAX,LastDigit
  750.     JLE    @@7
  751. @@4:    MOV    AL,'0'
  752. @@5:    CMP    DigitPlace,0
  753.     JNE    @@6
  754.     MOV    AH,AL
  755.     MOV    AL,DecimalSeparator
  756.     STOSW
  757.     JMP    @@7
  758. @@6:    STOSB
  759.     CMP    ThousandSep,0
  760.     JE    @@7
  761.     MOV    EAX,DigitPlace
  762.     CMP    EAX,1
  763.     JLE    @@7
  764.     MOV    DL,3
  765.     DIV    DL
  766.     CMP    AH,1
  767.     JNE    @@7
  768.     MOV    AL,ThousandSeparator
  769.     STOSB
  770. @@7:    DEC    DigitPlace
  771.     RET
  772.  
  773. ; procedure FloatToDecimal(var Result: TFloatDecimal; const Value;
  774. ;   ValueType: TValueType; Precision, Decimals: Integer);
  775.  
  776. FloatToDecimal:
  777.  
  778.     ARG    Result,DWORD,1
  779.     ARG    Value,DWORD,1
  780.     ARG    ValueType,BYTE,4
  781.     ARG    Precision,DWORD,1
  782.     ARG    Decimals,DWORD,1
  783.     LOC    StatWord,WORD,2
  784.     LOC    Exponent,DWORD,1
  785.     LOC    Temp,QWORD,1
  786.     LOC    BCDValue,TBYTE,1
  787.  
  788.     ENTRY   FAR
  789.     PUSH    EDI
  790.     PUSH    ESI
  791.     PUSH    EBX
  792.     MOV    EBX,EAX
  793.     MOV    ESI,EDX
  794.     CMP    CL,fvExtended
  795.     JE    @@1
  796.     CALL    CurrToDecimal
  797.     JMP    @@2
  798. @@1:    CALL    ExtToDecimal
  799. @@2:    POP    EBX
  800.     POP    ESI
  801.     POP    EDI
  802.     EXIT
  803.  
  804. ; Convert Extended to decimal
  805.  
  806. ExtToDecimal:
  807.  
  808.     MOV    AX,[ESI].w8
  809.     MOV    EDX,EAX
  810.     AND    EAX,7FFFH
  811.     JE    @@1
  812.     CMP    EAX,7FFFH
  813.     JNE    @@10
  814.     CMP    [ESI].w6,8000H
  815.     JE    @@2
  816.     INC    EAX
  817. @@1:    XOR    EDX,EDX
  818. @@2:    MOV    [EBX].fdDigits,0
  819.     JMP    @@31
  820. @@10:    FLD    TBYTE PTR [ESI]
  821.     SUB    EAX,3FFFH
  822.     IMUL    EAX,19728
  823.     SAR    EAX,16
  824.     INC    EAX
  825.     MOV    Exponent,EAX
  826.     MOV    EAX,18
  827.     SUB    EAX,Exponent
  828.     FABS
  829.     CALL    FPower10
  830.     FRNDINT
  831.     FLD    FCon1E18
  832.     FCOMP
  833.     FSTSW    StatWord
  834.     FWAIT
  835.     TEST    StatWord,mC0+mC3
  836.     JE    @@11
  837.     FIDIV    DCon10
  838.     INC    Exponent
  839. @@11:    FBSTP    BCDValue
  840.     LEA    EDI,[EBX].fdDigits
  841.     MOV    EDX,9
  842.     FWAIT
  843. @@12:    MOV    AL,BCDValue[EDX-1].b0
  844.     MOV    AH,AL
  845.     SHR    AL,4
  846.     AND    AH,0FH
  847.     ADD    AX,'00'
  848.     STOSW
  849.     DEC    EDX
  850.     JNE    @@12
  851.     XOR    AL,AL
  852.     STOSB
  853. @@20:    MOV    EDI,Exponent
  854.     ADD    EDI,Decimals
  855.     JNS    @@21
  856.     XOR    EAX,EAX
  857.     JMP    @@1
  858. @@21:    CMP    EDI,Precision
  859.     JB    @@22
  860.     MOV    EDI,Precision
  861. @@22:    CMP    EDI,18
  862.     JAE    @@26
  863.     CMP    [EBX].fdDigits[EDI],'5'
  864.     JB    @@25
  865. @@23:    MOV    [EBX].fdDigits[EDI],0
  866.     DEC    EDI
  867.     JS    @@24
  868.     INC    [EBX].fdDigits[EDI]
  869.     CMP    [EBX].fdDigits[EDI],'9'
  870.     JA    @@23
  871.     JMP    @@30
  872. @@24:    MOV    [EBX].fdDigits.w0,'1'
  873.     INC    Exponent
  874.     JMP    @@30
  875. @@26:    MOV    EDI,18
  876. @@25:    MOV    [EBX].fdDigits[EDI],0
  877.     DEC    EDI
  878.     JS    @@30
  879.     CMP    [EBX].fdDigits[EDI],'0'
  880.     JE    @@25
  881. @@30:    MOV    EAX,Exponent
  882.     MOV    DX,[ESI].w8
  883. @@31:    SHR    DX,15
  884.     MOV    [EBX].fdExponent,AX
  885.     MOV    [EBX].fdNegative,DL
  886.     RET
  887.  
  888. ; Convert Currency to decimal
  889.  
  890. CurrToDecimal:
  891.  
  892.     MOV    EAX,[ESI].d0
  893.     MOV    EDX,[ESI].d4
  894.     MOV    ECX,EAX
  895.     OR    ECX,EDX
  896.     JE    @@20
  897.     OR    EDX,EDX
  898.     JNS    @@1
  899.     NEG    EDX
  900.     NEG    EAX
  901.     SBB    EDX,0
  902. @@1:    XOR    ECX,ECX
  903.     MOV    EDI,Decimals
  904.     OR    EDI,EDI
  905.     JGE    @@2
  906.     XOR    EDI,EDI
  907. @@2:    CMP    EDI,4
  908.     JL    @@4
  909.     MOV    EDI,4
  910. @@3:    INC    ECX
  911.     SUB    EAX,Const1E18Lo
  912.     SBB    EDX,Const1E18Hi
  913.     JNC    @@3
  914.     DEC    ECX
  915.     ADD    EAX,Const1E18Lo
  916.     ADC    EDX,Const1E18Hi
  917. @@4:    MOV    Temp.d0,EAX
  918.     MOV    Temp.d4,EDX
  919.     FILD    Temp
  920.     MOV    EDX,EDI
  921.     MOV    EAX,4
  922.     SUB    EAX,EDX
  923.     JE    @@5
  924.     FIDIV    DCon10[EAX*4-4]
  925. @@5:    FBSTP    BCDValue
  926.     LEA    EDI,[EBX].fdDigits
  927.     FWAIT
  928.     OR    ECX,ECX
  929.     JNE    @@11
  930.     MOV    ECX,9
  931. @@10:    MOV    AL,BCDValue[ECX-1].b0
  932.     MOV    AH,AL
  933.     SHR    AL,4
  934.     JNE    @@13
  935.     MOV    AL,AH
  936.     AND    AL,0FH
  937.     JNE    @@14
  938.     DEC    ECX
  939.     JNE    @@10
  940.     JMP    @@20
  941. @@11:    MOV    AL,CL
  942.     ADD    AL,'0'
  943.     STOSB
  944.     MOV    ECX,9
  945. @@12:    MOV    AL,BCDValue[ECX-1].b0
  946.     MOV    AH,AL
  947.     SHR    AL,4
  948. @@13:    ADD    AL,'0'
  949.     STOSB
  950.     MOV    AL,AH
  951.     AND    AL,0FH
  952. @@14:    ADD    AL,'0'
  953.     STOSB
  954.     DEC    ECX
  955.     JNE    @@12
  956.     MOV    EAX,EDI
  957.     LEA    ECX,[EBX].fdDigits[EDX]
  958.     SUB    EAX,ECX
  959. @@15:    MOV    BYTE PTR [EDI],0
  960.     DEC    EDI
  961.     CMP    BYTE PTR [EDI],'0'
  962.     JE    @@15
  963.     MOV    EDX,[ESI].d4
  964.     SHR    EDX,31
  965.     JMP    @@21
  966. @@20:    XOR    EAX,EAX
  967.     XOR    EDX,EDX
  968.     MOV    [EBX].fdDigits,AL
  969. @@21:    MOV    [EBX].fdExponent,AX
  970.     MOV    [EBX].fdNegative,DL
  971.     RET
  972.  
  973. ; function TextToFloat(var Buffer; var Value;
  974. ;   ValueType: TFloatValue): Boolean;
  975.  
  976. TextToFloat:
  977.  
  978.     ARG    Buffer,DWORD,1
  979.     ARG    Value,DWORD,1
  980.     ARG    ValueType,BYTE,4
  981.     LOC    Temp,DWORD,1
  982.     LOC    CtrlWord,WORD,1
  983.  
  984.     ENTRY    FAR
  985.     PUSH    EDI
  986.     PUSH    ESI
  987.     PUSH    EBX
  988.     MOV    ESI,EAX
  989.     MOV    EDI,EDX
  990.     MOV    EBX,ECX
  991.     FSTCW    CtrlWord
  992.     FCLEX
  993.     FLDCW    CWNear
  994.     FLDZ
  995.     CALL    SkipBlanks
  996.     MOV    BH,[ESI]
  997.     CMP    BH,'+'
  998.     JE    @@1
  999.     CMP    BH,'-'
  1000.     JNE    @@2
  1001. @@1:    INC    ESI
  1002. @@2:    MOV    ECX,ESI
  1003.     CALL    GetDigitStr
  1004.     XOR    EDX,EDX
  1005.     MOV    AL,[ESI]
  1006.     CMP    AL,DecimalSeparator
  1007.     JNE    @@3
  1008.     INC    ESI
  1009.     CALL    GetDigitStr
  1010.     NEG    EDX
  1011. @@3:    CMP    ECX,ESI
  1012.     JE    @@9
  1013.     MOV    AL,[ESI]
  1014.     AND    AL,0DFH
  1015.     CMP    AL,'E'
  1016.     JNE    @@4
  1017.     INC    ESI
  1018.     PUSH    EDX
  1019.     CALL    GetExponent
  1020.     POP    EAX
  1021.     ADD    EDX,EAX
  1022. @@4:    CALL    SkipBlanks
  1023.     CMP    BYTE PTR [ESI],0
  1024.     JNE    @@9
  1025.     MOV    EAX,EDX
  1026.     CMP    BL,fvCurrency
  1027.     JNE    @@5
  1028.     ADD    EAX,4
  1029. @@5:    CALL    FPower10
  1030.     CMP    BH,'-'
  1031.     JNE    @@6
  1032.     FCHS
  1033. @@6:    CMP    BL,fvExtended
  1034.     JE    @@7
  1035.     FISTP    QWORD PTR [EDI]
  1036.     JMP    @@8
  1037. @@7:    FSTP    TBYTE PTR [EDI]
  1038. @@8:    FSTSW    AX
  1039.     TEST    AX,mIE+mOE
  1040.     JNE    @@10
  1041.     MOV    AL,1
  1042.     JMP    @@11
  1043. @@9:    FSTP    ST(0)
  1044. @@10:    XOR    EAX,EAX
  1045. @@11:    FCLEX
  1046.     FLDCW    CtrlWord
  1047.     FWAIT
  1048.     POP    EBX
  1049.     POP    ESI
  1050.     POP    EDI
  1051.     EXIT
  1052.  
  1053. ; Skip blanks
  1054.  
  1055. SkipBlanks:
  1056.  
  1057. @@1:    LODSB
  1058.     OR    AL,AL
  1059.     JE    @@2
  1060.     CMP    AL,' '
  1061.     JE    @@1
  1062. @@2:    DEC    ESI
  1063.     RET
  1064.  
  1065. ; Process string of digits
  1066. ; Out    EDX = Digit count
  1067.  
  1068. GetDigitStr:
  1069.  
  1070.     XOR    EAX,EAX
  1071.     XOR    EDX,EDX
  1072. @@1:    LODSB
  1073.     SUB    AL,'0'+10
  1074.     ADD    AL,10
  1075.     JNC    @@2
  1076.     FIMUL    DCon10
  1077.     MOV    Temp,EAX
  1078.     FIADD    Temp
  1079.     INC    EDX
  1080.     JMP    @@1
  1081. @@2:    DEC    ESI
  1082.     RET
  1083.  
  1084. ; Get exponent
  1085. ; Out    EDX = Exponent (-4999..4999)
  1086.  
  1087. GetExponent:
  1088.  
  1089.     XOR    EAX,EAX
  1090.     XOR    EDX,EDX
  1091.     MOV    CL,[ESI]
  1092.     CMP    CL,'+'
  1093.     JE    @@1
  1094.     CMP    CL,'-'
  1095.     JNE    @@2
  1096. @@1:    INC    ESI
  1097. @@2:    MOV    AL,[ESI]
  1098.     SUB    AL,'0'+10
  1099.     ADD    AL,10
  1100.     JNC    @@3
  1101.     INC    ESI
  1102.     IMUL    EDX,10
  1103.     ADD    EDX,EAX
  1104.     CMP    EDX,500
  1105.     JB    @@2
  1106. @@3:    CMP    CL,'-'
  1107.     JNE    @@4
  1108.     NEG    EDX
  1109. @@4:    RET
  1110.  
  1111.     END
  1112.