home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 225_01 / zmath.azm < prev   
Text File  |  1987-06-09  |  15KB  |  1,130 lines

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