home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / dmuldiv.seq < prev    next >
Text File  |  1987-01-03  |  6KB  |  235 lines

  1. \ Division of unsigned quad by double.          08:45 31Oct87RLS
  2.  
  3. \ Version for sequential files and forward assembler.  Use with Tom Zimmer's
  4. \   FF Forth.
  5.  
  6. comment:
  7.  This file contains a Code (8086) routine for a true double
  8.  precision divide routine  UMD/MOD .  The numerator is an
  9.  unsigned quad precision number and the divisor is an unsigned
  10.  double precision number.  The result returned is an unsigned
  11.  double quotient (1st and 2nd on stack), and an unsigned double
  12.  remainder (3rd and 4th on stack).  Another routine multiplies
  13.  two unsigned double numbers, yielding an unsigned quad product.
  14.  The file also contains a simple method for using labels in
  15.  code routines in F83.
  16.  
  17.                   Robert L. Smith
  18.                 2300 St. Francis Dr.
  19.                 Palo Alto, CA 94303
  20. comment;
  21.  
  22. comment:
  23.  
  24.       The divide routine is based on the article "Unsigned
  25.       Division Code Routines" by Robert L. Smith (Forth
  26.       Dimensions, Vol. VIII, No. 6, March/April, 1987), and
  27.       on a subsequent letter "Mods Quad Divides" by Michael
  28.       Barr (Forth Dimensions, Vol. IX, No. 2, July/August,
  29.       1987).
  30.  
  31.       Note that the F83 assembler uses the sequence
  32.              BX AX MOV
  33.       to mean (in INTEL or MASM mnemonics):
  34.              MOV AX,BX
  35.  
  36. comment;
  37.  
  38. comment:
  39.  
  40. \ Labels for Assembler                          03:54 02Nov87RLS
  41.  
  42.  30 CONSTANT MAXLABELS       HEX
  43. CREATE SHORT_LABELS    MAXLABELS 4 * ALLOT
  44. : SXBYTE   ( -- )  DUP 80 AND IF  FF00 OR  THEN ;   DECIMAL
  45.  
  46. : CLEAR_LABELS   ( -- )  SHORT_LABELS MAXLABELS 4 * 0 FILL ;
  47.  
  48. : CHECKLABEL   ( n -- m ) \ Or abort
  49.      DUP MAXLABELS 1- U> ABORT"  Bad Label "
  50.      2* 2* SHORT_LABELS + ;
  51.  
  52. : $     ( n1 -- n2 )
  53.      CHECKLABEL DUP @
  54.      IF  @  ELSE  2+ DUP @ SWAP HERE 2+ SWAP !
  55.          DUP 0=  IF  HERE 2+ +  THEN
  56.      THEN ;
  57.  
  58. comment;
  59.  
  60. comment:
  61.  
  62. Typical use would be:
  63.  
  64.    CODE FOO
  65.    CLEAR_LABELS
  66.      n1 $ JB  ...  n2 $ JA  ...   ( Forward references )
  67.      ...
  68.      n1 $: AX BX ADD  ...         ( Define label n1 )
  69.      ...
  70.      n1 $ #) JMP                  ( Backward reference )
  71.      n2 $: ...                    ( Define label n2 )
  72.    END-CODE
  73.  
  74. comment;
  75.  
  76. comment:
  77.  
  78. : $RESOLVE   ( linkaddr -- )
  79.      @ DUP 0= IF  DROP EXIT  THEN  0
  80.      BEGIN
  81.           + DUP 1- C@ OVER HERE OVER - SWAP 1- C!
  82.           SXBYTE DUP 0=
  83.      UNTIL
  84.      2DROP ;
  85.  
  86. : $:   ( n -- )
  87.      CHECKLABEL DUP 2+ $RESOLVE  0 OVER 2+ !
  88.      HERE SWAP ! ;
  89.  
  90. : CLEAR_LABEL   ( n -- )
  91.      CHECKLABEL 4 0 FILL ;
  92.  
  93. comment;
  94.  
  95. comment:
  96.  
  97. MAXLABELS     Maximum number of short labels.
  98. SHORT_LABELS  Vector for 30 short labels.
  99. SXBYTE        Sign extension for a byte.
  100.  
  101. CLEAR_LABELS  Routine to clear the local short labels.
  102.  
  103. CHECKLABELS   Verify that the input argument is in the allowed
  104.               range.  Then point to the beginning of the
  105.               label information for that argument.
  106.  
  107. $             Takes an argument from 0 to 29.  Used to reference
  108.               a label for relative jumps in the assembler.  The
  109.               label may be referenced before and/or after its
  110.               definition.
  111.  
  112. comment;
  113.  
  114. \ Unsigned quad divided by double.              10:46 13Oct87RLS
  115.  
  116. CODE UMD/MOD   ( uquad uddiv -- udquot udmod )
  117.         CLEAR_LABELS
  118.         POP  CX
  119.         POP  DX
  120.         POP  AX
  121.         POP  BX
  122.         POP  DI
  123.         PUSH SI
  124.         PUSH BP
  125.         MOV  BP, SP
  126.         MOV  SI, 4 [BP]
  127.         MOV  BP, CX
  128.         CMP  BP, AX
  129.         JA   6 $
  130.         JNE  7 $
  131.         CMP  DX, BX
  132.         JA   6 $
  133.  7 $: ( INT  0)       \ Remove parens if you have a Divide Interrupt.
  134.         MOV  AX, DI
  135.         MOV  BX, SI
  136.         MOV  SI, # -1
  137.         MOV  DI, SI
  138.         JMP  8 $
  139.  6 $:   MOV  CX, # 32
  140.         CLC
  141.  1 $:   RCL  SI
  142.         RCL  DI
  143.         RCL  BX
  144.         RCL  AX
  145.         JAE  3 $
  146.  2 $:   SUB  BX, DX
  147.         SBB  AX, BP
  148.         STC
  149.         LOOP 1 $
  150.         JMP  5 $
  151.  3 $:   CMP  AX, BP
  152.         JB   4 $
  153.         JNE  2 $
  154.         CMP  BX, DX
  155.         JAE  2 $
  156.  4 $:   CLC
  157.         LOOP 1 $
  158.  5 $:   RCL  SI
  159.         RCL  DI
  160.  8 $:   MOV  CX, SI
  161.         POP  BP
  162.         POP  SI
  163.         POP  DX
  164.         PUSH BX
  165.         PUSH AX
  166.         PUSH CX
  167.         PUSH DI
  168.         NEXT
  169.         END-CODE
  170.  
  171. comment:
  172.  
  173. $RESOLVE     Used to resolve forward short label references.
  174.  
  175. $:           Used to define a local label for short references.
  176.              The input argument is a label number in the range
  177.              of 0 to 29.
  178.  
  179. CLEAR_LABEL  Clear the specified label.
  180.  
  181. comment;
  182.  
  183. \ Double precision Multiply.                    08:40 13Oct87RLS
  184.  
  185. CODE UMD*   ( ud1 ud2 -- qprod )
  186.         POP  DI
  187.         POP  BX
  188.         POP  CX
  189.         POP  DX
  190.         SUB  SP, # 2            \ Get room for L.S. Product.
  191.         PUSH BP
  192.         PUSH SI
  193.         MOV  SI, DX
  194.         MOV  AX, BX
  195.         MUL  DX                 \ BD
  196.         MOV  BP, SP
  197.         MOV  4 [BP], AX         \ BDlo to stack.
  198.         XCHG SI, DX             \ BDhi to SI, D to DX
  199.         MOV  AX, DI
  200.         MUL  DX                 \ AD
  201.         ADD  SI, AX             \ BDhi + ADlo
  202.         ADC  DX, # 0            \ ADhi + carry
  203.         MOV  AX, BX
  204.         MOV  BX, DX
  205.         MUL  CX                 \ BC
  206.         XOR  BP, BP
  207.         ADD  SI, AX             \ BDhi + ADlo + BClo
  208.         ADC  BX, DX             \ ADhi + BChi
  209.         ADC  BP, # 0            \ Carry into MS part
  210.         MOV  AX, CX
  211.         MUL  DI                 \ AC
  212.         ADD  AX, BX             \ AClo + ADhi + BC hi
  213.         ADC  DX, BP             \ AChi + carrys
  214.         MOV  BX, SI
  215.         POP  SI
  216.         POP  BP
  217.         PUSH BX
  218.         PUSH AX
  219.         PUSH DX
  220.         NEXT
  221.         END-CODE
  222.  
  223. : D*    ( d1 d2 -- dprod )
  224.      UMD* 2DROP ;
  225.  
  226. comment:
  227.  
  228. UMD/MOD    Unsigned division of a quad number by a double,
  229.            yielding an unsigned quotient and remainder.
  230.            If you wish to use Interrupt 0 for reporting
  231.            errors, remove the parentheses from line 6.
  232.  
  233. comment;
  234.  
  235.