home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / z1.ark / ZMATH.AZM < prev   
Encoding:
Text File  |  1987-09-02  |  14.3 KB  |  1,156 lines

  1.  
  2.     LIST    C,P        ; For Z1 assembler, generates .COM file
  3. ;                   directly in a single pass.
  4. ;
  5. ; revised 9-2-87: IEEE revised format notes        24 Oct 1986
  6. ;
  7. ; by Neil R. Koozer
  8. ;    Kellogg Star Rt. Box 125
  9. ;    Oakland, OR 97462
  10. ;
  11. ; This code is hereby released to the public domain for unrestricted
  12. ; usage.  The only thing you may not do is to copyright it as your own
  13. ; or restrict its unlimited usage in any way.
  14. ;
  15. ; This file assembles under Z1.COM (public domain assembler).  To assem-
  16. ; ble, type:
  17. ;            B>Z1 ZMATH
  18. ;
  19. ; The 2-character symbols starting with $ are psuedo-labels used in the
  20. ; single-pass assembler Z1.COM.  The psuedo-labels $A thru $Z are re-
  21. ; usable local labels for forward references only.  $_ is similar but
  22. ; with a nesting behavior.  The rest of the psuedo-labels ($1, $@, etc)
  23. ; are for backward references only.
  24. ;
  25. ; The three principal routines, MULT, DIV, and SQRT, illustrate fast Z80
  26. ; code for double precision floating point operations.    These routines
  27. ; use more memory than is customary in order to achieve high speed.  The
  28. ; example drivers at the end of this file illustrate how to call the
  29. ; floating point routines.
  30. ;
  31. ; revised IEEE double precision format (8 bytes):
  32. ;
  33. ;  byte 0        low exponent (bias 03FFh)
  34. ;  byte 1, bits 0 to 2    high exponent (bias 03FFfh), 11 bit exponent
  35. ;       bits 3 to 7    least significant mantissa
  36. ;  byte 2        lleast significant+1 mantissa
  37. ;  ...            increasingly significant mantissi
  38. ;  byte 7, bits 0 to 6    most significant mantissa, implicit (base 2) 0.1
  39. ;              assumed
  40. ;       bit 7    sign bit
  41. ;
  42. ; 15 or 16 decimal digits precision
  43. ; range: 4.19 * 10^-307 <= n <= 1.67 * 10^+308
  44. ;
  45. ;examples:
  46. ;  0    all 64 bits 0
  47. ;  1    00 04 00 00 00 00 00 00
  48. ; -1    00 04 00 00 00 00 00 80
  49. ; +2    01 04 00 ...
  50. ; -2    01 04 00 00 00 00 00 80
  51. ; +3    01 04 00 00 00 00 00 40
  52. ; -3    01 04 00 00 00 00 00 c0
  53. ;  4    02 04 00 ...
  54. ;  5    02 04 00 00 00 00 00 20
  55. ;  6    02 04 00 00 00 00 00 40
  56. ;  7    02 04 00 00 00 00 00 60
  57. ;  8    03 04 00 ...
  58. ;  9    03 04 00 00 00 00 00 10
  59. ; 10    03 04 00 00 00 00 00 20
  60. ;
  61. ;
  62.     ORG    100H
  63. ;
  64. OPER1    DW    0        ; Force the following DS's to be stored
  65.     DS    6        ;   in the .COM file
  66. OPER2    DS    8
  67. RESULT    DS    8
  68. SIGN    DS    1
  69. NORM    DS    1
  70. SAVESP    DS    2
  71.  
  72. ; The routines MUL8, MUL16, MUL32, DIV8, DIV16, DIV32, and DIV56 are for
  73. ; multiplying and dividing binary fractions (as opposed to binary
  74. ; integers).
  75. ;
  76. MUL8    XOR    A        ; H = H * D
  77.     LD    B,8
  78. ;
  79. $1    RR    H
  80.     JR    NC,$A
  81.     ADD    A,D
  82. ;
  83. $A    RRA
  84.     DJNZ    $1
  85.     LD    H,A
  86.     RET    NC
  87.     INC    H        ; Round
  88.     RET
  89. ;
  90. MUL16    LD    C,H        ; HL = HL * DE
  91.     LD    A,L
  92.     LD    HL,0
  93.     CALL    $+4
  94.     LD    A,C
  95. ;
  96. M1    LD    B,8
  97. ;
  98. $1    RRA
  99.     JR    NC,$+3
  100.     ADD    HL,DE
  101.     RR    H
  102.     RR    L
  103.     DJNZ    $1
  104.     RET    NC
  105.     INC    HL        ; Round
  106.     RET
  107. ;
  108. MUL32    LD    C,H        ; HL,HL' = HL,HL' * DE,DE'
  109.     LD    A,L
  110.     EX    AF,AF'
  111.     LD    HL,0
  112.     EXX
  113.     LD    C,H
  114.     LD    A,L
  115.     LD    HL,0
  116.     EXX
  117.     CALL    M1
  118.     EXX
  119.     LD    A,C
  120.     EXX
  121.     CALL    $_
  122.     EX    AF,AF'
  123.     CALL    $_
  124.     LD    A,C
  125. ;
  126. $_    LD    B,8
  127. ;
  128. $2    RRA
  129.     JR    NC,$A
  130.     EXX
  131.     ADD    HL,DE
  132.     EXX
  133.     ADC    HL,DE
  134. ;
  135. $A    RR    H
  136.     RR    L
  137.     EXX
  138.     RR    H
  139.     RR    L
  140.     EXX
  141.     DJNZ    $2
  142.     RET    NC
  143.     EXX
  144.     INC    L
  145.     JR    NZ,$A
  146.     INC    H
  147. ;
  148. $A    EXX
  149.     RET    NZ
  150.     INC    HL
  151.     RET
  152. ;
  153. $1    SUB    D
  154. ;
  155. $2    SCF
  156.     DEC    B
  157.     RET    Z
  158. ;
  159. D1    RL    C
  160.     ADD    A,A
  161.     JR    C,$1
  162.     SUB    D
  163.     JR    NC,$2
  164.     ADD    A,D
  165.     OR    A
  166.     DJNZ    D1
  167.     RET
  168. ;
  169. DIV8    LD    A,H        ; H = H / D
  170.     LD    B,9
  171.     CALL    D1
  172.     LD    H,C
  173.     RET    NC
  174.     INC    H        ; Rounding
  175.     RET
  176. ;
  177. $1    OR    A
  178.     SBC    HL,DE
  179. ;
  180. $2    SCF
  181.     DEC    B
  182.     RET    Z
  183. ;
  184. D2    RLA
  185.     ADD    HL,HL
  186.     JR    C,$1
  187.     SBC    HL,DE
  188.     JR    NC,$2
  189.     ADD    HL,DE
  190.     OR    A
  191.     DJNZ    D2
  192.     RET
  193. ;
  194. DIV16    LD    B,9        ; HL = HL / DE
  195.     CALL    D2
  196.     LD    C,A
  197.     LD    B,3
  198.     CALL    D2
  199.     LD    L,C
  200.     LD    C,A
  201.     LD    A,H
  202.     LD    H,L
  203.     LD    B,5
  204.     CALL    D1
  205.     LD    L,C
  206.     RET    NC
  207.     INC    HL        ; Rounding
  208.     RET
  209. ;
  210. $1    OR    A
  211. ;
  212. $2    EXX
  213.     SBC    HL,DE
  214. ;
  215. $3    EXX
  216.     SBC    HL,DE
  217.     SCF
  218.     DEC    B
  219.     RET    Z
  220. ;
  221. D4    RL    C
  222.     EXX
  223.     ADD    HL,HL
  224.     EXX
  225.     ADC    HL,HL
  226.     JR    C,$1
  227.     LD    A,H
  228.     CP    D
  229.     JR    C,$_
  230.     JP    NZ,$2
  231.     LD    A,L
  232.     CP    E
  233.     JR    C,$_
  234.     JR    NZ,$2
  235.     EXX
  236.     SBC    HL,DE
  237.     JR    NC,$3
  238.     ADD    HL,DE
  239.     EXX
  240. ;
  241. $_    OR    A
  242.     DJNZ    D4
  243.     RET
  244.  
  245. DIV32    LD    B,9        ; HL,HL' = HL,HL' / DE,DE'
  246.     CALL    D4
  247.     DB    0FDH
  248.     LD    H,C
  249.     LD    B,8
  250.     CALL    D4
  251.     DB    0FDH
  252.     LD    B,H
  253.     PUSH    BC
  254.     LD    B,3
  255.     CALL    D4
  256.     LD    A,C
  257.     LD    B,5
  258.     CALL    D2
  259.     EXX
  260.     LD    H,A
  261.     EXX
  262.     LD    B,3
  263.     CALL    D2
  264.     LD    C,A
  265.     LD    A,H
  266.     LD    B,5
  267.     CALL    D1
  268.     POP    HL
  269.     LD    A,C
  270.     EXX
  271.     LD    L,A
  272.     JR    C,$A
  273. ;
  274. $1    EXX
  275.     RET
  276. ;
  277. $A    INC    L        ; Rounding
  278.     JR    NZ,$1
  279.     INC    H
  280.     EXX
  281.     RET    NZ
  282.     INC    HL
  283.     RET
  284. ;
  285. $1    EXX
  286. ;
  287. $2    LD    A,B
  288.     DB    0FDH
  289.     SUB    H
  290. ;
  291. $3    LD    B,A
  292.     SBC    HL,DE
  293.     EXX
  294.     SBC    HL,DE
  295.     SCF
  296.     DEC    B
  297.     RET    Z
  298. ;
  299. D5    RL    C
  300.     EXX
  301.     SLA    B
  302.     ADC    HL,HL
  303.     EXX
  304.     ADC    HL,HL
  305.     JR    C,$1
  306.     LD    A,H        ; Do a compare to see if we should subtract
  307.     CP    D
  308.     JR    C,$_
  309.     JP    NZ,$1
  310.     LD    A,L
  311.     CP    E
  312.     JR    C,$_
  313.     JR    NZ,$1
  314.     EXX
  315.     LD    A,H
  316.     CP    D
  317.     JR    C,$_
  318.     JR    NZ,$2
  319.     LD    A,L
  320.     CP    E
  321.     JR    C,$_
  322.     JR    NZ,$2
  323.     LD    A,B
  324.     DB    0FDH
  325.     SUB    H
  326.     JR    NC,$3
  327. ;
  328. $_    EXX
  329. ;
  330. $_    OR    A
  331.     DJNZ    D5
  332.     RET
  333. ;
  334. $1    EXX
  335. ;
  336. $2    LD    A,C
  337.     DB    0FDH
  338.     SUB    L
  339. ;
  340. $3    LD    C,A
  341.     LD    A,B
  342.     DB    0FDH
  343.     SBC    A,H
  344.     LD    B,A
  345.     SBC    HL,DE
  346.     EXX
  347.     SBC    HL,DE
  348.     SCF
  349.     DEC    B
  350.     RET    Z
  351. ;
  352. D6    RL    C        ; Do a left shift
  353.     EXX
  354.     SLA    C
  355.     RL    B
  356.     ADC    HL,HL
  357.     EXX
  358.     ADC    HL,HL
  359.     JR    C,$1
  360.     LD    A,H        ; Do a compare to see if we should subtract
  361.     CP    D
  362.     JR    C,$_
  363.     JP    NZ,$1
  364.     LD    A,L
  365.     CP    E
  366.     JR    C,$_
  367.     JR    NZ,$1
  368.     EXX
  369.     LD    A,H
  370.     CP    D
  371.     JR    C,$_
  372.     JR    NZ,$2
  373.     LD    A,L
  374.     CP    E
  375.     JR    C,$_
  376.     JR    NZ,$2
  377.     LD    A,B
  378.     DB    0FDH
  379.     CP    H
  380.     JR    C,$_
  381.     JR    NZ,$2
  382.     LD    A,C
  383.     DB    0FDH
  384.     SUB    L
  385.     JR    NC,$3
  386. ;
  387. $_
  388. $_
  389. $_    EXX
  390. ;
  391. $_
  392. $_    OR    A
  393.     DJNZ    D6
  394.     RET
  395. ;
  396. $2    EXX
  397. ;
  398. $1    LD    A,C
  399.     SUB    B
  400. ;
  401. $3    LD    C,A
  402.     EXX
  403.     LD    A,C
  404.     DB    0FDH
  405.     SBC    A,L
  406.     LD    C,A
  407.     LD    A,B
  408.     DB    0FDH
  409.     SBC    A,H
  410.     LD    B,A
  411.     SBC    HL,DE
  412.     EXX
  413.     SBC    HL,DE
  414.     EX    AF,AF'
  415.     SCF
  416.     RET
  417. ;
  418. D7_8    CALL    $+3
  419.     CALL    $+3
  420.     CALL    $+3
  421. ;
  422. D7_1    RLA
  423.     EX    AF,AF'
  424.     SLA    C
  425.     EXX
  426.     RL    C
  427.     RL    B
  428.     ADC    HL,HL
  429.     EXX
  430.     ADC    HL,HL
  431.     JR    C,$1
  432. ;
  433. COMP    LD    A,H        ; Do a compare to see if we should subtract
  434.     CP    D
  435.     JR    C,$_
  436.     JP    NZ,$1
  437.     LD    A,L
  438.     CP    E
  439.     JR    C,$_
  440.     JR    NZ,$1
  441.     EXX
  442.     LD    A,H
  443.     CP    D
  444.     JR    C,$_
  445.     JR    NZ,$2
  446.     LD    A,L
  447.     CP    E
  448.     JR    C,$_
  449.     JR    NZ,$2
  450.     LD    A,B
  451.     DB    0FDH
  452.     CP    H
  453.     JR    C,$_
  454.     JR    NZ,$2
  455.     LD    A,C
  456.     DB    0FDH
  457.     CP    L
  458.     JR    C,$_
  459.     JR    NZ,$2
  460.     EXX
  461.     LD    A,C
  462.     SUB    B
  463.     JR    NC,$3
  464.     EXX
  465. ;
  466. $_
  467. $_
  468. $_
  469. $_    EXX
  470. ;
  471. $_
  472. $_    EX    AF,AF'
  473.     OR    A
  474.     RET
  475. ;
  476. RSHIFT    SRL    H
  477.     RR    L
  478.     EXX
  479.     RR    H
  480.     RR    L
  481.     RR    B
  482.     RR    C
  483.     EXX
  484.     RR    C
  485.     RET
  486. ;
  487. DIV56    EQU    $        ; HL,HL',BC',C = HL,HL',BC',C / DE,DE',IY,B
  488. ;
  489.     CALL    D7_1        ; Divisor is preserved
  490. ;
  491. DIV55    PUSH    BC        ; Save divisor lsbyte
  492.     CALL    D7_8
  493.     DB    0DDH
  494.     LD    H,A
  495.     LD    B,8
  496.     CALL    D6
  497.     DB    0DDH
  498.     LD    L,C
  499.     PUSH    IX
  500.     LD    B,8
  501.     CALL    D5
  502.     DB    0DDH
  503.     LD    H,C
  504.     LD    B,8
  505.     CALL    D4
  506.     DB    0DDH
  507.     LD    L,C
  508.     PUSH    IX
  509.     LD    B,8
  510.     CALL    D4
  511.     DB    0DDH
  512.     LD    H,C
  513.     LD    B,8
  514.     CALL    D2
  515.     DB    0DDH
  516.     LD    L,A
  517.     LD    A,H
  518.     LD    B,8
  519.     CALL    D1
  520.     EXX
  521.     DB    0DDH
  522.     LD    C,L
  523.     DB    0DDH
  524.     LD    B,H
  525.     POP    HL
  526.     EXX
  527.     POP    HL
  528.     LD    A,C
  529.     POP    BC        ; Restore divisor lsbyte
  530.     LD    C,A
  531.     RET    NC
  532.     INC    C        ; Rounding
  533.     RET    NZ
  534. ;
  535. RIPPLE    EXX
  536.     INC    C
  537.     JR    Z,$A
  538. ;
  539. $1    EXX
  540.     RET
  541. ;
  542. $A    INC    B
  543.     JR    NZ,$1
  544.     INC    L
  545.     JR    NZ,$1
  546.     INC    H
  547.     EXX
  548.     RET    NZ
  549.     INC    L
  550.     RET    NZ
  551.     INC    H
  552.     RET
  553. ;
  554. DOVER    LD    A,7FH
  555.     DB    0FEH
  556. ;
  557. DUNDER    XOR    A
  558.     LD    B,A
  559.     LD    A,(SIGN)
  560.     OR    B
  561.     LD    (IX+7),A
  562.     RLA
  563.     SRA    A
  564.     PUSH    IX
  565.     POP    HL
  566.     LD    B,7
  567. ;
  568. $1    LD    (HL),A
  569.     INC    HL
  570.     DJNZ    $1
  571.     RET
  572. ;
  573. ; Floating point divide, 53-bit mantissa, 11-bit exponent
  574. ;
  575. DIV    LD    A,(DE)        ; Dividend exponent lo
  576.     INC    DE
  577.     SUB    (HL)        ; Divisor exponent lo
  578.     INC    HL
  579.     DB    0FDH
  580.     LD    L,A
  581.     EX    AF,AF'     ;save carry flag
  582.     LD    A,(HL)        ; Divisor exponent hi
  583.     AND    7
  584.     LD    B,A
  585.     LD    A,(DE)        ; Dividend exponent hi
  586.     AND    7
  587.     LD    C,A
  588.     EX    AF,AF'     ;retrieve carry flag
  589.     LD    A,C
  590.     SBC    A,B
  591.     DB    0FDH
  592.     LD    H,A
  593.     PUSH    IY        ; Save exponent
  594.     LD    A,(DE)        ; ;dividend mantissa ls 5 bits
  595.     INC    DE
  596.     AND    0F8H
  597.     LD    C,A
  598.     LD    A,(HL)        ; ;divisor mantissa ls 5 bits
  599.     INC    HL
  600.     AND    0F8H
  601.     LD    B,A
  602.     LD    (SAVESP),SP
  603.     LD    SP,HL
  604.     EX    DE,HL
  605.     POP    IY        ; Now get rest of divisor mantissa
  606.     EXX
  607.     POP    DE
  608.     EXX
  609.     POP    DE
  610.     LD    SP,HL
  611.     EXX            ; Now get rest of dividend mantissa
  612.     POP    BC
  613.     POP    HL
  614.     EXX
  615.     POP    HL
  616.     LD    SP,(SAVESP)
  617.     LD    A,D        ; Sign of divisor
  618.     XOR    H        ; Sign of dividend
  619.     AND    80H        ; Clean the sign bit
  620.     LD    (SIGN),A    ; Sign of result
  621.     SET    7,D        ; Make the implicit 1 explicit
  622.     SET    7,H        ; Ditto
  623. ;
  624. ; Begin the divide
  625. ;
  626.     CALL    COMP
  627.     RLA
  628.     LD    (NORM),A    ; Save normalization flag
  629.     RRA
  630.     JR    C,$A
  631.     CALL    D7_1
  632. ;
  633. $A    PUSH    IX
  634.     CALL    DIV55
  635.     POP    IX
  636.     LD    A,C
  637.     ADD    A,4        ; Rounding bit
  638.     LD    C,A
  639.     LD    DE,400H        ; Exponent correction
  640.     JR    NC,$A
  641.     CALL    RIPPLE        ; Do ripple carry because of rounding
  642.     JR    NZ,$B        ; Norm flag (no right shift needed
  643.     INC    DE        ;   because it's all 0's)
  644. ;
  645. $A
  646. $B    RES    7,H        ; Remove msbit
  647.     LD    A,(SIGN)
  648.     OR    H        ; Append sign bit
  649.     LD    (IX+7),A
  650.     LD    (IX+6),L
  651.     POP    HL        ; Exponent
  652.     ADD    HL,DE
  653.     LD    A,(NORM)
  654.     RRA
  655.     JR    C,$A
  656.     DEC    HL
  657. ;
  658. $A    BIT    7,H
  659.     JP    NZ,DUNDER    ; Negative means underflow
  660.     BIT    3,H        ; See if overflow
  661.     JP    NZ,DOVER
  662.     LD    A,C        ; Get lsbyte
  663.     AND    0F8H
  664.     OR    H        ; Append 3 hi bits of exponent
  665.     LD    (IX+1),A
  666.     LD    (IX+0),L
  667.     EXX
  668.     LD    (IX+2),C
  669.     LD    (IX+3),B
  670.     LD    (IX+4),L
  671.     LD    (IX+5),H
  672.     EXX
  673.     RET
  674. ;
  675. MAXDE    LD    DE,0FFFFH
  676.     EXX
  677.     LD    DE,0FFFFH
  678.     EXX
  679.     RET
  680. ;
  681. MAXHL    LD    HL,0FFFFH
  682.     EXX
  683.     LD    HL,0FFFFH
  684.     LD    B,H
  685.     LD    C,L
  686.     EXX
  687.     LD    C,H
  688.     RET
  689. ;
  690. SQRT    LD    (SAVESP),SP    ; Floating point square root, 53-bit
  691.     LD    SP,HL        ;   mantissa, 11-bit exponential
  692.     POP    BC
  693.     EXX
  694.     POP    BC
  695.     POP    HL
  696.     EXX
  697.     POP    HL
  698.     LD    SP,(SAVESP)
  699.     PUSH    DE        ; Dest. addr.
  700.     LD    D,B        ; Save mantissa lo byte
  701.     LD    A,B        ; Get exponent hi byte
  702.     AND    7        ; Clean exponent
  703.     ADD    A,4        ; Fix offset
  704.     RRA            ; Divide by 2
  705.     RR    C        ; Carry = 'odd exp.'
  706.     LD    B,A
  707.     PUSH    BC        ; Save exponent
  708.     EX    AF,AF'     ;save 'EXP ODD' flag
  709.     LD    A,D        ; Get mantissa lsb
  710.     AND    0F8H
  711.     LD    C,A
  712.     SET    7,H        ; Make the implicit 1 explicit
  713.     CALL    RSHIFT        ; HalfX
  714.     EX    AF,AF'
  715.     LD    D,0D7H        ; Y seed = 1.68...
  716.     JR    C,$A
  717.     CALL    RSHIFT
  718.     LD    D,98H        ; Y seed = 1.189...
  719. ;
  720. $A    PUSH    BC
  721.     PUSH    HL
  722.     CALL    DIV8        ; H = halfX / Y
  723.     SRL    D        ; D = Y / 2
  724.     LD    A,H
  725.     ADD    A,D
  726.     LD    D,A        ; D = new Y
  727.     CALL    C,MAXDE
  728.     POP    HL
  729.     PUSH    HL        ; HL = halfX
  730.     CALL    DIV16        ; HL = halfX / Y
  731.     SRL    D
  732.     RR    E        ; DE = Y/2
  733.     ADD    HL,DE
  734.     EX    DE,HL        ; DE = new Y
  735.     CALL    C,MAXDE
  736.     POP    HL
  737.     PUSH    HL
  738.     EXX
  739.     PUSH    HL
  740.     EXX
  741.     CALL    DIV32        ; HL,HL' = halfX / Y
  742.     SRL    D
  743.     RR    E
  744.     EXX
  745.     RR    D
  746.     RR    E        ; DE,DE' = Y/2
  747.     ADD    HL,DE
  748.     EX    DE,HL
  749.     POP    HL
  750.     EXX
  751.     ADC    HL,DE
  752.     EX    DE,HL        ; DE,DE' = new Y
  753.     CALL    C,MAXDE
  754.     POP    HL
  755.     POP    BC
  756.     CALL    DIV56
  757.     SRL    D
  758.     RR    E
  759.     EXX
  760.     RR    D
  761.     RR    E
  762.     DB    0FDH
  763.     LD    A,H
  764.     RRA
  765.     DB    0FDH
  766.     LD    H,A
  767.     DB    0FDH
  768.     LD    A,L
  769.     RRA
  770.     DB    0FDH
  771.     LD    L,A
  772.     EXX
  773.     LD    A,B
  774.     RRA
  775.     ADD    A,C
  776.     LD    C,A
  777.     EXX
  778.     LD    A,C
  779.     DB    0FDH
  780.     ADC    A,L
  781.     LD    C,A
  782.     LD    A,B
  783.     DB    0FDH
  784.     ADC    A,H
  785.     LD    B,A
  786.     ADC    HL,DE
  787.     EXX
  788.     ADC    HL,DE
  789.     CALL    C,MAXHL
  790.     LD    A,C
  791.     ADD    A,4        ; Rounding
  792.     LD    C,A
  793.     CALL    C,RIPPLE
  794.     CALL    Z,MAXHL
  795.     RES    7,H
  796.     LD    A,C
  797.     POP    BC        ; Exponent
  798.     AND    0F8H
  799.     OR    B
  800.     LD    B,A
  801.     EX    DE,HL
  802.     POP    HL        ; Dest. addr.
  803.     LD    SP,HL
  804.     PUSH    DE
  805.     EXX
  806.     PUSH    HL
  807.     PUSH    BC
  808.     EXX
  809.     PUSH    BC
  810.     LD    SP,(SAVESP)
  811.     RET
  812. ;
  813. M7_8    CALL    $A
  814. ;
  815. M7_7    CALL    $B
  816.     CALL    $+6
  817.     CALL    $+3
  818.     CALL    $+3
  819. ;
  820. $B
  821. $A    RRA
  822.     JR    NC,$A
  823. ;
  824. M7_0    EX    AF,AF'
  825.     LD    A,C
  826.     ADD    A,B
  827.     LD    C,A
  828.     EXX
  829.     LD    A,C
  830.     DEFB    0FDH
  831.     ADC    A,L
  832.     LD    C,A
  833.     LD    A,B
  834.     DEFB    0FDH
  835.     ADC    A,H
  836.     LD    B,A
  837.     ADC    HL,DE
  838.     EXX
  839.     ADC    HL,DE
  840. ;
  841. M72    RR    H
  842.     RR    L
  843.     EXX
  844.     RR    H
  845.     RR    L
  846.     RR    B
  847.     RR    C
  848.     EXX
  849.     RR    C
  850.     EX    AF,AF'
  851.     RET
  852. ;
  853. $A    SRL    H
  854.     RR    L
  855.     EXX
  856.     RR    H
  857.     RR    L
  858.     RR    B
  859.     RR    C
  860.     EXX
  861.     RR    C
  862.     RET
  863. ;
  864. M4    LD    B,8
  865. ;
  866. $1    RRA
  867.     JR    NC,$A
  868.     EXX
  869.     ADD    HL,DE
  870.     EXX
  871.     ADC    HL,DE
  872. ;
  873. $A    RR    H
  874.     RR    L
  875.     EXX
  876.     RR    H
  877.     RR    L
  878.     EXX
  879.     DJNZ    $1
  880.     RET
  881. ;
  882. UNDER    LD    A,D
  883.     AND    80H
  884.     JR    $A
  885. ;
  886. OVER    LD    A,D
  887.     OR    7FH
  888. ;
  889. $A    POP    HL        ; Destination address
  890.     DEC    HL
  891.     LD    (HL),A
  892.     RLA
  893.     SRA    A
  894.     LD    B,7
  895. ;
  896. $1    DEC    HL
  897.     LD    (HL),A
  898.     DJNZ    $1
  899.     RET
  900. ;
  901. MULT    PUSH    DE        ; Floating point multiply, 53-bit
  902.     LD    (SAVESP),SP    ;   mantissa, 11-bit exponential
  903.     LD    SP,HL
  904.     LD    L,(IX+0)
  905.     LD    A,(IX+1)
  906.     AND    7
  907.     LD    H,A
  908.     POP    BC
  909.     LD    E,C
  910.     LD    A,B
  911.     AND    7
  912.     LD    D,A
  913.     ADD    HL,DE        ; New exponent
  914.     EXX
  915.     POP    IY
  916.     POP    DE
  917.     EXX
  918.     POP    DE
  919.     LD    SP,(SAVESP)
  920.     PUSH    HL
  921.     LD    A,B
  922.     AND    0F8H
  923.     LD    B,A
  924.     LD    A,(IX+7)
  925.     XOR    D
  926.     AND    80H
  927.     LD    (SIGN),A
  928.     SET    7,D        ; Make implicit 1 explicit
  929. ;
  930. ; Zero the accumulator
  931. ;
  932.     XOR    A
  933.     LD    C,A
  934.     EXX
  935.     LD    C,A
  936.     LD    B,A
  937.     LD    L,A
  938.     LD    H,A
  939.     EXX
  940.     LD    L,A
  941.     PUSH    BC
  942.     LD    A,(IX+1)
  943.     RRA
  944.     RRA
  945.     RRA
  946.     LD    H,A
  947.     XOR    A
  948.     LD    B,5
  949. ;
  950. $1    RR    H
  951.     JR    NC,$+3
  952.     ADD    A,D
  953.     RRA
  954.     DJNZ    $1
  955.     LD    H,A
  956.     LD    A,(IX+2)
  957.     LD    B,8
  958. ;
  959. $1    RRA
  960.     JR    NC,$+3
  961.     ADD    HL,DE
  962.     RR    H
  963.     RR    L
  964.     DJNZ    $1
  965.     LD    A,(IX+3)
  966.     CALL    M4
  967.     LD    A,(IX+4)
  968.     CALL    M4
  969.     LD    C,(IX+5)
  970.     LD    B,8
  971. ;
  972. $1    RR    C
  973.     JR    NC,$A
  974.     EXX
  975.     LD    A,B
  976.     DEFB    0FDH
  977.     ADD    A,H
  978.     LD    B,A
  979.     ADC    HL,DE
  980.     EXX
  981.     ADC    HL,DE
  982. ;
  983. $A    RR    H
  984.     RR    L
  985.     EXX
  986.     RR    H
  987.     RR    L
  988.     RR    B
  989.     EXX
  990.     DJNZ    $1
  991.     LD    C,(IX+6)
  992.     LD    B,8
  993. ;
  994. $1    RR    C
  995.     JR    NC,$A
  996.     EXX
  997.     LD    A,C
  998.     DEFB    0FDH
  999.     ADD    A,L
  1000.     LD    C,A
  1001.     LD    A,B
  1002.     DEFB    0FDH
  1003.     ADC    A,H
  1004.     LD    B,A
  1005.     ADC    HL,DE
  1006.     EXX
  1007.     ADC    HL,DE
  1008. ;
  1009. $A    RR    H
  1010.     RR    L
  1011.     EXX
  1012.     RR    H
  1013.     RR    L
  1014.     RR    B
  1015.     RR    C
  1016.     EXX
  1017.     DJNZ    $1
  1018.     POP    BC
  1019.     LD    A,(IX+7)
  1020.     CALL    M7_7
  1021.     CALL    M7_0        ; Skip the test because ms bit is always 1
  1022.     LD    B,1        ; Normalization counter
  1023.     BIT    7,H
  1024.     JR    NZ,$A
  1025.     DEC    B
  1026. ;
  1027. ; Shift left to normalize
  1028. ;
  1029.     SLA    C
  1030.     EXX
  1031.     RL    C
  1032.     RL    B
  1033.     ADC    HL,HL
  1034.     EXX
  1035.     ADC    HL,HL
  1036. ;
  1037. $A    LD    A,4        ; Round it to 53-bit precision instead
  1038.     ADD    A,C        ;   of truncating
  1039.     LD    C,A
  1040.     JR    NC,$_
  1041.     CALL    RIPPLE
  1042.     JR    NZ,$_
  1043.     INC    B        ; Right shift not needed because it's all 0's
  1044. ;
  1045. $_
  1046. $_    EX    DE,HL
  1047.     LD    HL,SIGN
  1048.     LD    A,D
  1049.     AND    7FH
  1050.     OR    (HL)
  1051.     LD    D,A
  1052.     LD    A,C
  1053.     AND    0F8H
  1054.     LD    H,A
  1055.     LD    A,B        ; Norm flag
  1056.     POP    BC        ; Get exponent
  1057.     ADD    A,C        ; Correct for norm.
  1058.     LD    C,A
  1059.     LD    A,0FCH        ; Fix offset
  1060.     ADC    A,B
  1061.     JP    NC,UNDER
  1062.     BIT    3,A
  1063.     JP    NZ,OVER
  1064.     OR    H
  1065.     LD    B,A
  1066.     POP    HL        ; Dest. addr.
  1067.     LD    (SAVESP),SP
  1068.     LD    SP,HL
  1069.     PUSH    DE
  1070.     EXX
  1071.     PUSH    HL
  1072.     PUSH    BC
  1073.     EXX
  1074.     PUSH    BC
  1075.     LD    SP,(SAVESP)
  1076.     RET
  1077. ;
  1078. ; A driver to do 1000 multiplies for timing purposes
  1079. ;
  1080. MULTEST    LD    BC,1000
  1081. ;
  1082. $1    PUSH    BC
  1083. ;
  1084. ; Here is a segment which represents compiled code for a high level
  1085. ;
  1086. ; Statement like a = b * c
  1087. ;
  1088.     LD    IX,OPER1    ; Address of one operand
  1089.     LD    HL,OPER2    ; Address of other operand
  1090.     LD    DE,RESULT+8
  1091.     CALL    MULT
  1092.     POP    BC
  1093.     DEC    BC
  1094.     LD    A,B
  1095.     OR    C
  1096.     JR    NZ,$1
  1097.     RET
  1098. ;
  1099. ;Here is a driver to do 1000 divides for timing purposes
  1100. ;
  1101. DIVTEST    LD    BC,1000
  1102. ;
  1103. $1    PUSH    BC
  1104. ;
  1105. ; Here is a segment which represents compiled code for a high level
  1106. ;
  1107. ; Statement like a = b / c
  1108. ;
  1109.     LD    DE,OPER1    ; Addr of dividend
  1110.     LD    HL,OPER2    ; Addr of divisor
  1111.     LD    IX,RESULT
  1112.     CALL    DIV
  1113.     POP    BC
  1114.     DEC    BC
  1115.     LD    A,B
  1116.     OR    C
  1117.     JR    NZ,$1
  1118.     RET
  1119. ;
  1120. ; Here is an empty loop for comparison.  It loops 65536 times.
  1121. ;
  1122. EMPTY    LD    BC,0
  1123. ;
  1124. $1    PUSH    BC
  1125.     POP    BC
  1126.     DEC    BC
  1127.     LD    A,B
  1128.     OR    C
  1129.     JR    NZ,$1
  1130.     RET
  1131. ;
  1132. ; Here is a driver to do 1000 square roots for timing purposes
  1133. ;
  1134. SQRTTEST EQU    $
  1135. ;
  1136.     LD    BC,1000
  1137. ;
  1138. $1    PUSH    BC
  1139. ;
  1140. ; Here is a segment which represents compiled code for a high level
  1141. ;
  1142. ; Statement like a = sqrt(b)
  1143. ;
  1144.     LD    HL,OPER2    ; Address of operand
  1145.     LD    DE,RESULT+8
  1146.     CALL    SQRT
  1147.     POP    BC
  1148.     DEC    BC
  1149.     LD    A,B
  1150.     OR    C
  1151.     JR    NZ,$1
  1152.     RET
  1153. ;
  1154. ;
  1155.     END
  1156.