home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / FFB.ZIP / FFUTILS.ARC / SMITH.ARC / FLOAT.SEQ < prev    next >
Encoding:
Text File  |  1987-12-12  |  35.5 KB  |  1,578 lines

  1. \ FLOAT.SEQ    Floating point for 8087    Enhancements by: Robert L. Smith
  2. comment:
  3.         Prepared by:
  4.  
  5.                  *******************
  6.                  **  Mark Smiley  **
  7.                  *******************
  8.  
  9. A fine blend of Steve Pollack's 8087 Assembler
  10. and Floating-Point routines (from USER.BLK), combined with
  11. R.L. Davies's Turtle Graphics (from GRAPHICS.BLK),
  12. and Nathaniel Grossman's Polynomial Evaluation (from
  13. FORTH Dimensions, Vol. VII, No. 5, p. 27-34);
  14. with extra Floating Point Extensions, conversion
  15. of Turtle Graphics to floating-point,
  16. Function Plotting routines, and examples by:
  17.              Mark Smiley
  18.  
  19.              Dept. of Math
  20.              AUM
  21.              Montgomery, AL
  22.                      36193-0401
  23.  
  24.    5 LOAD \ ASM8087    \ Screens    5 -  16   8087 Assembler
  25.   17 LOAD \ FPING      \ Screens   17 -  65   Floating-point
  26.   66 LOAD \ FP-EXTN    \ Screens   66 -  67   Fl.-pt Extensions
  27.  
  28. comment;
  29.  
  30. WARNING OFF
  31. CR .( 8087/80287 Assembler extentions..)
  32.  
  33. HEX
  34. FORTH ALSO ASSEMBLER ALSO DEFINITIONS
  35.  
  36. VARIABLE WAIT? WAIT? ON
  37. VARIABLE <FW>
  38.  
  39. : NOWAIT WAIT? OFF ;
  40.  
  41. : COMP-WAIT WAIT? @ [ FORTH ] IF   9B C, ( WAIT )  THEN WAIT? ON ;
  42.  
  43. : FPSTACK?   ( -- f )
  44.          [ FORTH ] TS@ 6 = ;
  45.  
  46. \ Floating Point Source Registers
  47.  
  48. \     Reg  Type  W        Name
  49.       0    6     1  SREG  ST
  50.       0    6     1  SREG  ST0
  51.       0    6     1  SREG  ST(0)
  52.       1    6     1  SREG  ST1
  53.       1    6     1  SREG  ST(1)
  54.       2    6     1  SREG  ST2
  55.       2    6     1  SREG  ST(2)
  56.       3    6     1  SREG  ST3
  57.       3    6     1  SREG  ST(3)
  58.       4    6     1  SREG  ST4
  59.       4    6     1  SREG  ST(4)
  60.       5    6     1  SREG  ST5
  61.       5    6     1  SREG  ST(5)
  62.       6    6     1  SREG  ST6
  63.       6    6     1  SREG  ST(6)
  64.       7    6     1  SREG  ST7
  65.       7    6     1  SREG  ST(7)
  66.  
  67. \ Floating Point Destination Registers
  68. \     Reg  Type  W        Name
  69.  
  70.       0    6     1  DREG  ST,
  71.       0    6     1  DREG  ST0,
  72.       0    6     1  DREG  ST(0),
  73.       1    6     1  DREG  ST1,
  74.       1    6     1  DREG  ST(1),
  75.       2    6     1  DREG  ST2,
  76.       2    6     1  DREG  ST(2),
  77.       3    6     1  DREG  ST3,
  78.       3    6     1  DREG  ST(3),
  79.       4    6     1  DREG  ST4,
  80.       4    6     1  DREG  ST(4),
  81.       5    6     1  DREG  ST5,
  82.       5    6     1  DREG  ST(5),
  83.       6    6     1  DREG  ST6,
  84.       6    6     1  DREG  ST(6),
  85.       7    6     1  DREG  ST7,
  86.       7    6     1  DREG  ST(7),
  87.  
  88. : WORD-TYPE CREATE C, DOES> C@ <FW> ! ;
  89.  
  90. 07 WORD-TYPE INTEGER*2     2F WORD-TYPE INTEGER*8
  91. 03 WORD-TYPE INTEGER*4     01 WORD-TYPE REAL*4
  92. 05 WORD-TYPE REAL*8        2B WORD-TYPE TEMP_REAL
  93. 27 WORD-TYPE BCD
  94.  
  95. : MF    ( -- n )   <FW> @  [ FORTH ] 6 AND ;
  96.  
  97. : ESC,  ( n -- )   [ FORTH ] D8 OR C, ;
  98.  
  99. : 1FPF
  100.         COMP-WAIT DUP 1+ C@ ESC,  C@ C, RESET ;
  101.  
  102. : 1FP CREATE C, C, DOES> ['] 1FPF A;!  A; ;
  103.  
  104. \ NON-VARIANT 8087 INSTRUCTIONS                    08Jun86RLS
  105.  
  106. 6  D9 1FP FCOMPP    1 E4 1FP FTST      1 E5 1FP FXAM
  107. 1  EE 1FP FLDZ      1 E8 1FP FLD1      1 EB 1FP FLDPI
  108. 1  E9 1FP FLDL2T    1 EA 1FP FLDL2E    1 EC 1FP FLDLG2
  109. 1 0ED 1FP FLDLN2    1 FA 1FP FSQRT,    1 FD 1FP FSCALE
  110. 1  F8 1FP FPREM     1 FC 1FP FRNDINT   1 F4 1FP FXTRACT
  111. 1  E1 1FP FABS,     1 E0 1FP FCHS      1 F2 1FP FPTAN
  112. 1  F3 1FP FPATAN    1 F0 1FP F2XM1     1 F1 1FP FYL2X
  113. 1  F9 1FP FYL2XP1   3 E3 1FP FINIT     3 E0 1FP FENI
  114. 3  E1 1FP FDISI     1 E7 1FP FINCSTP   1 F6 1FP FDECSTP
  115. 1  D0 1FP FNOP      3 E2 1FP FCLEX
  116.  
  117. : 2FPF
  118.         COMP-WAIT DUP 1+ C@ ESC, C@ M/RS, RESET ;
  119.  
  120. : 2FP
  121.         CREATE C, C,
  122.         DOES>  ['] 2FPF A;! A; ;
  123.  
  124. 1 28 2FP FLDCW   1 38 2FP FSTCW   5 38 2FP FSTSW
  125. 1 30 2FP FSTENV  1 20 2FP FLDENV  5 30 2FP FSAVE
  126. 5 20 2FP FRSTOR
  127.  
  128. : 3FPF
  129.         COMP-WAIT FPSTACK? [ FORTH ]
  130.         IF     DUP 2+ C@ ESC, 1+ C@ RS@ OR C,
  131.         ELSE   MF 1 OR ESC, C@ <FW> @ 7 >
  132.                IF   10 AND <FW> @ 28 AND OR   THEN
  133.                M/RS,
  134.         THEN RESET ;
  135.  
  136. : 3FP
  137.         CREATE C, C, C,
  138.         DOES>  ['] 3FPF A;! A;  ;
  139.  
  140. 01  C0  00  3FP  FLD
  141. 05  D8  18  3FP  FSTP
  142.  
  143. : 4FPF
  144.         COMP-WAIT [ FORTH ] DUP 1+ C@ ESC, C@ RS@ OR C, RESET ;
  145.  
  146. : 4FP
  147.         CREATE C, C,
  148.         DOES>  ['] 4FPF A;! A;  ;
  149.  
  150. 01  C8  4FP  FXCH
  151. 05  C0  4FP  FFREE
  152.  
  153. : 5FPF
  154.         COMP-WAIT 6 ESC, C@ RD@ [ FORTH ] OR C, RESET ;
  155.  
  156. : 5FP
  157.         CREATE C,  DOES>  ['] 5FPF A;! A; ;
  158.  
  159. C0  5FP  FADDP
  160. C8  5FP  FMULP
  161. E0  5FP  FSUBP
  162. E8  5FP  FSUBRP
  163. F0  5FP  FDIVP
  164. F8  5FP  FDIVRP
  165.  
  166. : 6FPF
  167.         COMP-WAIT FPSTACK?  [ FORTH ]
  168.         IF   DUP C@ ESC, 1+ C@ RS@ OR C,
  169.         ELSE  DUP 1+ C@ 1 AND MF OR ESC,  C@ 38 AND M/RS,
  170.         THEN RESET ;
  171.  
  172. : 6FP
  173.         CREATE C, C,
  174.         DOES>  ['] 6FPF A;! A; ;
  175.  
  176. D0  00  6FP  FCOM
  177. D8  00  6FP  FCOMP
  178. D0  05  6FP  FST
  179.  
  180. : 7FPF
  181.         [ FORTH ] COMP-WAIT FPSTACK?
  182.         IF      RD@ 0=
  183.                 IF    0 ESC, C@ RS@ OR C,
  184.                 ELSE  4 ESC, C@ RD@ OR C,
  185.                 THEN
  186.         ELSE    MF ESC, 1+ C@ M/RS,
  187.         THEN RESET ;
  188.  
  189. : 7FP
  190.         CREATE C, C,
  191.         DOES>  ['] 7FPF A;! A; ;
  192.  
  193. 00  C0  7FP  FADD
  194. 08  C8  7FP  FMUL
  195. 20  E0  7FP  FSUB
  196. 28  E8  7FP  FSUBR
  197. 30  F0  7FP  FDIV
  198. 38  F8  7FP  FDIVR
  199.  
  200. DECIMAL
  201.  
  202. : WSS: ( -- ) WAIT SS: NOWAIT ;
  203.  
  204. : WCS: ( -- ) WAIT CS: NOWAIT ;
  205.  
  206. : WDS: ( -- ) WAIT DS: NOWAIT ;
  207.  
  208. : WES: ( -- ) WAIT ES: NOWAIT ;
  209.  
  210. ONLY FORTH DEFINITIONS ALSO
  211.  
  212. .( ..Loaded)
  213.  
  214. CR .( F83 8087/80287 Floating point support..)
  215.  
  216. comment:
  217.  
  218. These screens load the higher level 8087 support words.  The
  219. floating point assembler must be loaded prior to these words.
  220.  
  221. Unless otherwise specified, real is in the Intel 8087 64-bit
  222. floating point (REAL*8) format.
  223.  
  224. In this version, floating point numbers are stored on a separate
  225. stack.
  226.  
  227. comment;
  228.  
  229. 64   CONSTANT FSTACK-SIZE
  230.  
  231. CREATE FPSTACK  FSTACK-SIZE 2+ 8* ALLOT
  232.  
  233. FPSTACK FSTACK-SIZE 1+ 8 * + CONSTANT FSP0
  234.  
  235. CREATE FLOAT-WORK 10 ALLOT
  236.  
  237. VARIABLE FSP
  238.  
  239. : FSP@ ( -- u ) FSP @ ;
  240.  
  241. : FSP! ( u -- ) FSP ! ;    FSP0 FSP!
  242.  
  243. : ?FSTACK  ( -- )
  244.         FSP@ FSP0 SWAP U< IF FSP0 FSP!
  245.         TRUE ABORT" Floating Point Stack Underflow " THEN
  246.         FSP@ FSP0 FSTACK-SIZE 8 * - U< IF FSP0 FSP!
  247.         TRUE ABORT" Floating point Stack Overflow " THEN (?STACK) ;
  248.  
  249. ' ?FSTACK IS ?STACK
  250.  
  251. CODE FPOP   ( -- )
  252.         ADD   FSP # 8 
  253.         NEXT
  254.         END-CODE
  255.  
  256. CODE FPUSH   ( -- )
  257.         SUB   FSP # 8
  258.         NEXT
  259.         END-CODE
  260.  
  261. : FCONSTANT ( r -- ) ( compiling)
  262.             ( -- r ) ( run-time )
  263.         CREATE 8 0
  264.                 DO
  265.                         FSP@ I + @ ,
  266.                 2 +LOOP
  267.                 FPOP
  268.         DOES>   FPUSH 8 0
  269.                 DO
  270.                         DUP @ FSP@ I + ! 2+ 2
  271.                 +LOOP
  272.         DROP ;
  273.  
  274. : FVARIABLE ( -- )      ( compiling)
  275.             ( -- addr ) ( run-time )
  276.         CREATE 8 ALLOT
  277.         DOES> ;
  278.  
  279. CODE FP>R    ( -- r )
  280.         PUSH  BP 
  281.         MOV   BP, FSP  
  282.         SUB   BP, # 8  
  283.         MOV   FSP BP
  284.         FSTP  REAL*8 0 [BP]
  285.         POP   BP
  286.         NEXT
  287.         END-CODE
  288.  
  289. CODE R>FP    ( r -- )
  290.         PUSH  BP 
  291.         MOV   BP, FSP
  292.         FLD   REAL*8 0 [BP]
  293.         ADD   BP, # 8
  294.         MOV   FSP BP
  295.         POP   BP
  296.         NEXT
  297.         END-CODE
  298.  
  299. CODE FP>I    ( -- 16b)
  300.         XCHG  BP, SP  
  301.         DEC   BP 
  302.         DEC   BP 
  303.         FRNDINT
  304.         FSTP  INTEGER*2 0 [BP]  
  305.         XCHG  BP, SP  
  306.         NEXT
  307.         END-CODE
  308.  
  309. CODE I>FP    ( 16b -- )
  310.         XCHG  BP, SP  
  311.         FLD   INTEGER*2 0 [BP]  
  312.         INC   BP 
  313.         INC   BP 
  314.         XCHG  BP, SP  
  315.         NEXT
  316.         END-CODE
  317.  
  318. CODE FP>DI    ( -- 32b )
  319.         XCHG  BP, SP  
  320.         SUB   BP, # 4  
  321.         FRNDINT
  322.         FSTP  INTEGER*4 0 [BP]  
  323.         XCHG  BP, SP  
  324.         NEXT
  325.         END-CODE
  326.  
  327. CODE DI>FP    ( 32b -- )
  328.         XCHG  BP, SP  
  329.         FLD   INTEGER*4 0 [BP]  
  330.         ADD   BP, # 4 
  331.         XCHG  BP, SP  
  332.         NEXT
  333.         END-CODE
  334.  
  335. CODE FP>QI    ( -- 64b)
  336.         XCHG  BP, SP  
  337.         SUB   BP, # 8  
  338.         FRNDINT
  339.         FSTP  INTEGER*8 0 [BP] 
  340.         XCHG  BP, SP  
  341.         NEXT
  342.         END-CODE
  343.  
  344. CODE QI>FP    ( 64b -- )
  345.         XCHG  BP, SP  
  346.         FLD   INTEGER*8 0 [BP] 
  347.         ADD   BP, # 8  
  348.         XCHG  BP, SP  
  349.         NEXT
  350.         END-CODE
  351.  
  352. CODE FP>SR    ( -- 32bit-real )
  353.         XCHG  BP, SP  
  354.         SUB   BP, # 4 
  355.         FSTP  REAL*4 0 [BP] 
  356.         XCHG  BP, SP  
  357.         NEXT
  358.         END-CODE
  359.  
  360. CODE SR>FP    ( 32bit-real -- )
  361.         XCHG  BP, SP  
  362.         FLD   REAL*4 0 [BP] 
  363.         ADD   BP, # 4 
  364.         XCHG  BP, SP  
  365.         NEXT
  366.         END-CODE
  367.  
  368. CODE FPSW>    ( -- n )
  369.         XCHG  BP, SP  
  370.         DEC   BP 
  371.         DEC   BP 
  372.         FSTSW 0 [BP] 
  373.         XCHG  BP, SP  
  374.         NEXT
  375.         END-CODE
  376.  
  377. CODE FPCW>    ( -- n )
  378.         XCHG  BP, SP  
  379.         DEC   BP 
  380.         DEC   BP 
  381.         FSTCW 0 [BP] 
  382.         XCHG  BP, SP  
  383.         NEXT
  384.         END-CODE
  385.  
  386. CODE >FPCW    ( n -- )
  387.         XCHG  BP, SP  
  388.         FLDCW 0 [BP] 
  389.         INC   BP 
  390.         INC   BP 
  391.         XCHG  BP, SP  
  392.         NEXT
  393.         END-CODE
  394.  
  395. CODE INITFP    ( -- )
  396.         FINIT
  397.         FDISI
  398.         NEXT
  399.         END-CODE
  400.  
  401. CODE CLEARFP    ( -- )
  402.         FCLEX
  403.         NEXT
  404.         END-CODE
  405.  
  406. CODE PI    ( -- pi )
  407.         PUSH  BP 
  408.         FLDPI
  409.         MOV   BP, FSP  
  410.         SUB   BP, # 8 
  411.         MOV   FSP BP
  412.         FSTP  REAL*8 0 [BP] 
  413.         POP   BP 
  414.         NEXT
  415.         END-CODE
  416.  
  417. CODE F1.0    ( -- 1.0 )
  418.         PUSH  BP 
  419.         FLD1
  420.         MOV   BP, FSP  
  421.         SUB   BP, # 8 
  422.         MOV   FSP BP
  423.         FSTP  REAL*8 0 [BP] 
  424.         POP   BP 
  425.         NEXT
  426.         END-CODE
  427.  
  428. CODE F0.0    ( -- 0.0 )
  429.         PUSH  BP 
  430.         FLDZ
  431.         MOV   BP, FSP
  432.         SUB   BP, # 8 
  433.         MOV   FSP BP
  434.         FSTP  REAL*8 0 [BP] 
  435.         POP   BP 
  436.         NEXT
  437.         END-CODE
  438.  
  439. CODE F*   ( r1 r2 -- r1*r2)
  440.         PUSH  BP 
  441.         MOV   BP, FSP
  442.         FLD   REAL*8 0 [BP] 
  443.         ADD   BP, # 8 
  444.         FMUL  0 [BP] 
  445.         FSTP  0 [BP] 
  446.         MOV   FSP BP 
  447.         POP   BP 
  448.         NEXT
  449.         END-CODE
  450.  
  451. CODE F+    ( r1 r2 -- r1+r2)
  452.         PUSH  BP 
  453.         MOV   BP, FSP
  454.         FLD   REAL*8 0 [BP] 
  455.         ADD   BP, # 8 
  456.         FADD  0 [BP] 
  457.         FSTP  0 [BP] 
  458.         MOV   FSP BP
  459.         POP   BP 
  460.         NEXT
  461.         END-CODE
  462.  
  463. CODE F-    ( r1 r2 -- r1-r2)
  464.         PUSH  BP 
  465.         MOV   BP, FSP  
  466.         FLD   REAL*8 0 [BP] 
  467.         ADD   BP, # 8 
  468.         FLD   0 [BP] 
  469.         FSUB  ST(0), ST(1) 
  470.         FXCH  ST(1) 
  471.         FSTP  0 [BP] 
  472.         FSTP  0 [BP]
  473.         MOV   FSP BP
  474.         POP   BP 
  475.         NEXT
  476.         END-CODE
  477.  
  478. CODE F/    ( r1 r2 -- r1/r2)
  479.         PUSH  BP 
  480.         MOV   BP, FSP  
  481.         FLD   REAL*8 0 [BP] 
  482.         ADD   BP, # 8 
  483.         FLD   0 [BP] 
  484.         FDIV  ST(0), ST(1) 
  485.         FXCH  ST(1) 
  486.         FSTP  0 [BP] 
  487.         FSTP  0 [BP] 
  488.         MOV   FSP BP
  489.         POP   BP 
  490.         NEXT
  491.         END-CODE
  492.  
  493. CODE FABS    ( r1 -- |r1|)
  494.         PUSH  BP 
  495.         MOV   BP, FSP 
  496.         FLD   REAL*8 0 [BP] 
  497.         FABS,
  498.         FSTP  0 [BP] 
  499.         POP   BP 
  500.         NEXT
  501.         END-CODE
  502.  
  503. CODE FNEGATE    ( r1 -- -r1 )
  504.         PUSH  BP 
  505.         MOV   BP, FSP 
  506.         FLD   REAL*8 0 [BP] 
  507.         FCHS
  508.         FSTP  0 [BP] 
  509.         POP   BP 
  510.         NEXT
  511.         END-CODE
  512.  
  513. CODE FSQRT    ( r1 -- SQRT[r1])
  514.         PUSH  BP 
  515.         MOV   BP, FSP 
  516.         FLD   REAL*8 0 [BP] 
  517.         FSQRT,
  518.         FSTP  0 [BP] 
  519.         POP   BP 
  520.         NEXT
  521.         END-CODE
  522.  
  523. CODE FLOG    ( r1 -- LOG10[r1])
  524.         PUSH  BP 
  525.         MOV   BP, FSP 
  526.         FLDLG2
  527.         FLD   REAL*8 0 [BP] 
  528.         FYL2X
  529.         FSTP  0 [BP] 
  530.         POP   BP 
  531.         NEXT
  532.         END-CODE
  533.  
  534. CODE FLN    ( r1 -- LN[r1])
  535.         PUSH  BP 
  536.         MOV   BP, FSP 
  537.         FLDLN2
  538.         FLD   REAL*8 0 [BP] 
  539.         FYL2X
  540.         FSTP  0 [BP] 
  541.         POP   BP 
  542.         NEXT
  543.         END-CODE
  544.  
  545. CODE 1/F  ( r -- r^-1)
  546.         PUSH  BP 
  547.         MOV   BP, FSP 
  548.         FLD   REAL*8 0 [BP] 
  549.         FLD1
  550.         FDIVP ST(1), ST(0) 
  551.         FSTP  0 [BP] 
  552.         POP   BP 
  553.         NEXT
  554.         END-CODE
  555.  
  556. : D>R  ( d -- r )
  557.         SWAP DI>FP FP>R ;
  558. HEX
  559. : (ROUND)    ( r n -- r )
  560.         FPCW> DUP >R  F3FF AND OR >FPCW
  561.         R>FP FP>DI SWAP R> >FPCW ;
  562.  
  563. : FIX   ( r -- d )  0000 (ROUND) ;
  564.  
  565. : INT   ( r -- d )  0C00 (ROUND) ;
  566.  
  567. : RND>+INF  ( r -- d )  0800 (ROUND) ;
  568.  
  569. : RND>-INF  ( r -- d )  0400 (ROUND) ;
  570.  
  571. : FDROP    ( r -- )  FPOP ;
  572.  
  573. DECIMAL
  574.  
  575. CODE FDUP    ( r -- r r )
  576.         PUSH  BP 
  577.         MOV   BP, FSP
  578.         FLD   REAL*8 0 [BP]
  579.         SUB   BP, # 8 
  580.         FSTP  0 [BP] 
  581.         MOV   FSP BP
  582.         POP   BP 
  583.         NEXT   
  584.         END-CODE
  585.  
  586. CODE FOVER    ( r1 r2 -- r1 r2 r1 )
  587.         PUSH  BP 
  588.         MOV   BP, FSP 
  589.         ADD   8 # BP 
  590.         FLD   REAL*8 0 [BP] 
  591.         SUB   BP, # 16 
  592.         FSTP  0 [BP] 
  593.         MOV   FSP BP 
  594.         POP   BP 
  595.         NEXT
  596.         END-CODE
  597.  
  598. CODE FSWAP   ( r1 r2 -- r2 r1 )
  599.         PUSH  BP 
  600.         MOV   BP, FSP 
  601.         FLD   REAL*8 0 [BP] 
  602.         ADD   BP, # 8 
  603.         FLD   0 [BP] 
  604.         FXCH  ST(1) 
  605.         FSTP  0 [BP] 
  606.         SUB   BP, # 8 
  607.         FSTP  0 [BP] 
  608.         POP   BP 
  609.         NEXT
  610.         END-CODE
  611.  
  612. CODE FROT    ( r1 r2 r3 -- r2 r3 r1 )
  613.         PUSH  BP 
  614.         MOV   BP, FSP 
  615.         ADD   BP, # 8 
  616.         FLD   REAL*8 0 [BP] 
  617.         MOV   BP, FSP 
  618.         FLD   0 [BP] 
  619.         ADD   BP, # 16 
  620.         FLD   0 [BP] 
  621.         MOV   BP, FSP 
  622.         FSTP  0 [BP] 
  623.         ADD   BP, # 8 
  624.         FSTP  0 [BP] 
  625.         ADD   BP, # 8 
  626.         FSTP  0 [BP] 
  627.         POP   BP 
  628.         NEXT
  629.         END-CODE
  630.  
  631. CODE FNIP    ( r1 r2 -- r2 )
  632.         PUSH  BP 
  633.         MOV   BP, FSP 
  634.         FLD   REAL*8 0 [BP] 
  635.         ADD   BP, # 8 
  636.         FSTP  0 [BP] 
  637.         MOV   FSP BP 
  638.         POP   BP 
  639.         NEXT
  640.         END-CODE
  641.  
  642. CODE FTUCK    ( r1 r2 -- r2 r1 r2 )
  643.         PUSH  BP 
  644.         MOV   BP, FSP 
  645.         FLD   REAL*8 0 [BP] 
  646.         ADD   BP, # 8 
  647.         FLD   0 [BP] 
  648.         FXCH  ST1 
  649.         FST   0 [BP] 
  650.         FXCH  ST1 
  651.         SUB   BP, # 8 
  652.         FSTP  0 [BP] 
  653.         SUB   BP, # 8 
  654.         FSTP  0 [BP] 
  655.         MOV   FSP BP 
  656.         POP   BP 
  657.         NEXT
  658.         END-CODE
  659.  
  660. CODE FPICK    ( rX ... rn ... r2 r1 r0 n --- ... r1 r0 rn )
  661.         POP   AX 
  662.         PUSH  BP 
  663.         MOV   8 # AH 
  664.         MUL   AH 
  665.         MOV   BP, FSP 
  666.         ADD   BP, AX  
  667.         FLD   REAL*8 0 [BP]  
  668.         MOV   BP, FSP 
  669.         SUB   BP, # 8 
  670.         FSTP  0 [BP] 
  671.         MOV   FSP BP 
  672.         POP   BP 
  673.         NEXT
  674.         END-CODE
  675.  
  676. CODE (RVS0)     ( r -- fpsw )
  677.         PUSH  BP 
  678.         MOV   BP, FSP 
  679.         FLD   REAL*8 0 [BP] 
  680.         FTST
  681.         FSTP  ST(0) 
  682.         ADD   BP, # 8 
  683.         MOV   FSP BP 
  684.         POP   BP 
  685.         XCHG  BP, SP  
  686.         DEC   BP 
  687.         DEC   BP 
  688.         FSTSW 0 [BP] 
  689.         XCHG  SP, BP  
  690.         NEXT
  691.         END-CODE
  692.  
  693. HEX
  694. : C3C0X    ( fpsw -- n )
  695.         DUP  4000 AND 0= NOT
  696.         IF   2
  697.         ELSE 0
  698.         THEN
  699.         SWAP 0100 AND 0= NOT
  700.         IF   1+
  701.         THEN ;
  702.  
  703. DECIMAL
  704.  
  705. : F0=  ( r -- f )
  706.         (RVS0) C3C0X 2 = ;
  707.  
  708. : F0<  ( r -- f)  (RVS0) C3C0X 1 = ;
  709.  
  710. : F0>  ( r -- f)  (RVS0) C3C0X 0= ;
  711.  
  712. CODE (RVSR)    ( r1 r2 -- fpsw )
  713.         PUSH  BP 
  714.         MOV   BP, FSP 
  715.         FLD   REAL*8 0 [BP] 
  716.         ADD   BP, # 8 
  717.         FLD   0 [BP] 
  718.         FCOMPP
  719.         ADD   BP, # 8 
  720.         MOV   FSP BP 
  721.         POP   BP 
  722.         XCHG  BP, SP  
  723.         DEC   BP 
  724.         DEC   BP 
  725.         FSTSW 0 [BP] 
  726.         XCHG  SP, BP  
  727.         NEXT
  728.         END-CODE
  729.  
  730. : F=    ( r1 r2 -- f )
  731.         (RVSR) C3C0X 2 = ;
  732.  
  733. : F<    ( r1 r2 -- f )
  734.         (RVSR) C3C0X 1 = ;
  735.  
  736. : F>    ( r1 r2 -- f )
  737.         (RVSR) C3C0X 0=  ;
  738.  
  739. : FMIN   ( r1 r2 -- rmin )
  740.         FOVER FOVER F<
  741.         IF   FDROP
  742.         ELSE
  743.              FNIP
  744.         THEN ;
  745.  
  746. : FMAX    ( r1 r2 -- rmax )
  747.         FOVER FOVER F>
  748.         IF    FDROP
  749.         ELSE
  750.               FNIP
  751.         THEN ;
  752.  
  753. CODE F@    ( addr -- r )
  754.         POP   BX 
  755.         PUSH  BP 
  756.         FLD   REAL*8 0 [BX] 
  757.         MOV   BP, FSP 
  758.         SUB   BP, # 8 
  759.         FSTP  0 [BP] 
  760.         MOV   FSP BP
  761.         POP   BP 
  762.         NEXT
  763.         END-CODE
  764.  
  765. CODE F!   ( r addr -- )
  766.         POP   BX 
  767.         PUSH  BP 
  768.         MOV   BP, FSP
  769.         FLD   REAL*8 0 [BP] 
  770.         ADD   BP, # 8 
  771.         MOV   FSP BP
  772.         FSTP  0 [BX] 
  773.         POP   BP 
  774.         NEXT
  775.  
  776.         END-CODE
  777.  
  778. CODE (FLIT)   ( -- r )
  779.         PUSH  BP 
  780.         MOV   BP, FSP
  781.         SUB   BP, # 8 
  782.         LODSW ES:
  783.         MOV   0 [BP], AX 
  784.         LODSW ES:
  785.         MOV   2 [BP], AX
  786.         LODSW ES:
  787.         MOV   4 [BP], AX 
  788.         LODSW ES:
  789.         MOV   6 [BP], AX
  790.         MOV   FSP BP
  791.         POP   BP 
  792.         NEXT
  793.         END-CODE
  794.  
  795. : FLITERAL  ( r -- )
  796.         COMPILE (FLIT) FSP@
  797.         4 0 DO
  798.                 DUP I 2* +  @ X,
  799.         LOOP
  800.         DROP FDROP ; IMMEDIATE
  801.  
  802. VARIABLE TRIG-MODE     TRIG-MODE ON
  803.  
  804. : DEGREES    ( -- )
  805.         TRIG-MODE ON ;
  806.  
  807. : RADIANS    ( -- )
  808.         TRIG-MODE OFF ;
  809.  
  810. : DEG->RAD   ( r -- r )
  811.         [ 180. D>R ] FLITERAL F/
  812.         [ PI ] FLITERAL F* ;
  813.  
  814. : RAD->DEG    ( r -- r )
  815.         [ 180. D>R ] FLITERAL F*
  816.         [ PI ] FLITERAL F/ ;
  817.  
  818. INITFP CLEARFP
  819.  
  820. FVARIABLE 2PI   PI PI F+ 2PI F!
  821.  
  822. FVARIABLE PI/4  PI 4. D>R  F/ PI/4 F!
  823.  
  824. FVARIABLE PI/2  PI 2. D>R  F/ PI/2 F!
  825.  
  826. : ANGLE->+    ( r -- r )
  827.         TRIG-MODE @
  828.         IF    DEG->RAD   THEN
  829.         BEGIN FDUP F0<
  830.         WHILE
  831.               2PI F@ F+
  832.         REPEAT ;
  833.  
  834. HEX
  835.  
  836. CODE OCTANT>    ( r -- n )
  837.         MOV   DX, BP  
  838.         MOV   BP, FSP
  839.         FLD   REAL*8 0 [BP] 
  840.         ADD   BP, # 8 
  841.         MOV   FSP BP
  842.         MOV   BP, SP  
  843.         DEC   BP 
  844.         DEC   BP 
  845.         FLD   2PI
  846.         FXCH  ST(1) 
  847.         FPREM
  848.         FXCH  ST(1) 
  849.         FSTP  ST(0) 
  850.         FSTCW 0 [BP] 
  851.         MOV   AX, 0 [BP] 
  852.         MOV   CX, AX  
  853.         OR    AX, # 0C00 
  854.         MOV   0 [BP], AX
  855.         FLDCW 0 [BP] 
  856.         FLD   PI/4 
  857.         FXCH  ST(1) 
  858.         FDIVP ST(1), ST(0) 
  859.         FSTP  INTEGER*2 0 [BP] 
  860.         MOV   SP, BP  
  861.         MOV   FLOAT-WORK CX
  862.         FLDCW FLOAT-WORK
  863.         MOV   BP, DX  
  864.         NEXT
  865.         END-CODE
  866.  
  867. DECIMAL
  868.  
  869. CODE TRIG-ARG>    ( r -- r )
  870.         PUSH  BP 
  871.         MOV   BP, FSP
  872.         FLD   REAL*8 0 [BP] 
  873.         FLD   PI/4
  874.         FXCH  ST(1) 
  875.         FPREM
  876.         FXCH  ST(1) 
  877.         FSTP  ST(0) 
  878.         FSTP  0 [BP] 
  879.         POP   BP 
  880.         NEXT
  881.         END-CODE
  882.  
  883. CODE [SIN]    ( r -- sin<r> )
  884.         PUSH  BP 
  885.         MOV   BP, FSP
  886.         FLD   REAL*8 0 [BP] 
  887.         FLD1
  888.         FLD   ST(0) 
  889.         FADDP ST(1), ST(0) 
  890.         FXCH  ST(1) 
  891.         FDIVP ST(1), ST(0) 
  892.         FPTAN
  893.         FXCH  ST(1) 
  894.         FDIVP ST(1), ST(0) 
  895.         FLD   ST(0) 
  896.         FLD   ST(0) 
  897.         FMULP ST(1), ST(0) 
  898.         FLD1
  899.         FADDP ST(1), ST(0) 
  900.         FXCH  ST(1) 
  901.         FLD1
  902.         FLD   ST(0) 
  903.         FADDP ST(1), ST(0)
  904.         FMULP ST(1), ST(0)
  905.         FDIVP ST(1), ST(0)
  906.         FSTP  0 [BP] 
  907.         POP   BP 
  908.         NEXT
  909.         END-CODE
  910.  
  911. CODE [COS]    ( r -- cos<r> )
  912.         PUSH  BP 
  913.         MOV   BP, FSP
  914.         FLD   REAL*8 0 [BP] 
  915.         FLD1
  916.         FLD1
  917.         FADDP ST(1), ST(0)
  918.         FXCH  ST(1) 
  919.         FDIVP ST(1), ST(0)
  920.         FPTAN
  921.         FXCH  ST(1) 
  922.         FDIVP ST(1), ST(0)
  923.         FLD   ST(0) 
  924.         FMULP ST(1), ST(0)
  925.         FLD   ST(0)
  926.         FLD1
  927.         FADDP ST(1), ST(0)
  928.         FXCH  ST(1) 
  929.         FLD1
  930.         FSUBP ST(1), ST(0)
  931.         FDIVP ST(1), ST(0)
  932.         FSTP  0 [BP] 
  933.         POP   BP 
  934.         NEXT
  935.         END-CODE
  936.  
  937. CODE [TAN]    ( r -- tan<r> )
  938.         PUSH  BP 
  939.         MOV   BP, FSP
  940.         FLD   REAL*8 0 [BP] 
  941.         FPTAN
  942.         FXCH  ST(1) 
  943.         FDIVP ST(1), ST(0)
  944.         FSTP  0 [BP] 
  945.         POP   BP 
  946.         NEXT
  947.         END-CODE
  948.  
  949. : FSIN    ( r -- SIN<r> )
  950.         [ FORTH ] ANGLE->+ FDUP OCTANT> TRIG-ARG> 4 /MOD SWAP
  951.         DUP 0 =
  952.         IF      DROP [SIN]                              ELSE
  953.                 DUP 1 = IF DROP PI/4 F@ FSWAP F- [COS]  ELSE
  954.                 DUP 2 = IF DROP [COS]                   ELSE
  955.                 DUP 3 = IF DROP PI/4 F@ FSWAP F- [SIN]  ELSE
  956.         THEN THEN THEN THEN
  957.         IF  FNEGATE THEN ;
  958.  
  959. : FCOS ( r -- COS<r> )    [ FORTH ]
  960.     ANGLE->+ FDUP OCTANT> TRIG-ARG> DUP 4 MOD
  961.       DUP 0 = IF DROP [COS]                   ELSE
  962.       DUP 1 = IF DROP PI/4 F@ FSWAP F- [SIN]  ELSE
  963.       DUP 2 = IF DROP [SIN]                   ELSE
  964.       DUP 3 = IF DROP PI/4 F@ FSWAP F- [COS]  ELSE
  965.       THEN THEN THEN THEN
  966.       2+ 4 / 1 = IF FNEGATE THEN ;
  967.  
  968. F0.0 1/F FCONSTANT INFINITY
  969.  
  970. : TANARG<>0 ( r n -- TAN<r> )
  971.         [ FORTH ] 4 MOD
  972.         DUP 0 = IF DROP [TAN]                          EXIT THEN
  973.         DUP 1 = IF DROP PI/4 F@ FSWAP F- [TAN] 1/F     EXIT THEN
  974.         DUP 2 = IF DROP [TAN] FNEGATE 1/F              EXIT THEN
  975.         DUP 3 = IF DROP PI/4 F@ FSWAP F- [TAN] FNEGATE EXIT THEN ;
  976.  
  977. : TANARG=0    ( n -- TAN<r> )
  978.         [ FORTH ] 4 MOD
  979.         DUP 0 IF DROP F0.0           EXIT THEN
  980.         DUP 1 IF DROP F1.0           EXIT THEN
  981.         DUP 2 IF DROP INFINITY       EXIT THEN
  982.         DUP 3 IF DROP F1.0 FNEGATE   EXIT THEN ;
  983.  
  984. : FTAN    ( r -- TAN<r> )
  985.         ANGLE->+ FDUP OCTANT> TRIG-ARG> FDUP F0=
  986.         IF  FDROP TANARG=0
  987.         ELSE  TANARG<>0  THEN ;
  988.  
  989. HEX
  990.  
  991. ASSEMBLER ALSO
  992.  
  993. LABEL (POWER)    ( -- )
  994.         FMULP ST(1), ST(0)
  995.         FLD   ST(0) 
  996.         FSTCW FLOAT-WORK
  997.         MOV   AX, FLOAT-WORK
  998.         MOV   CX, AX  
  999.         AND   AX, # F3FF 
  1000.         OR    AX, # 0400
  1001.         MOV   FLOAT-WORK AX
  1002.         FLDCW FLOAT-WORK
  1003.         FRNDINT
  1004.         MOV   FLOAT-WORK CX
  1005.         FLDCW FLOAT-WORK
  1006.         FLD   ST(0) 
  1007.         FSTP  REAL*8 FLOAT-WORK
  1008.         FXCH  ST(1) 
  1009.         FSUBP ST(1), ST(0)
  1010.         FLD1
  1011.         FCHS
  1012.         FXCH  ST(1) 
  1013.         FSCALE
  1014.         FXCH  ST(1) 
  1015.         FSTP  ST(0) 
  1016.         F2XM1
  1017.         FLD1
  1018.         FADDP ST(1), ST(0)
  1019.         FLD   ST(0) 
  1020.         FMULP ST(1), ST(0)
  1021.         FLD   REAL*8 FLOAT-WORK
  1022.         FXCH  ST(1) 
  1023.         FSCALE
  1024.         FXCH  ST(1) 
  1025.         FSTP  ST(0) 
  1026.         RET
  1027.         END-CODE
  1028.  
  1029. PREVIOUS FORTH
  1030. DECIMAL
  1031.  
  1032. CODE (FALN)    ( -- )
  1033.         FLDL2E
  1034.         CALL (POWER)
  1035.         NEXT
  1036.         END-CODE
  1037.  
  1038. CODE (FALOG)    ( -- )
  1039.         FLDL2T
  1040.         CALL (POWER) 
  1041.         NEXT
  1042.         END-CODE
  1043.  
  1044. : FALN ( r -- e**r )
  1045.         FDUP  699. D>R  F>
  1046.         IF   ." FALN ARGUMENT TOO LARGE" FDROP QUIT
  1047.         THEN
  1048.         R>FP (FALN) FP>R ;
  1049.  
  1050. : FALOG    ( r -- 10**r )
  1051.         FDUP  304. D>R  F>
  1052.         IF   ." FALOG ARGUMENT TOO LARGE" FDROP QUIT
  1053.         THEN
  1054.         R>FP (FALOG) FP>R ;
  1055.  
  1056. : FLOAT    ( d -- r )
  1057.         D>R DPL @ 0 D>R FALOG F/ ;
  1058.  
  1059. : F**    ( r1 r2 -- r1^r2 )
  1060.         FSWAP FLOG F* FALOG ;
  1061.  
  1062. ASSEMBLER ALSO   HEX
  1063.  
  1064. LABEL (FATAN)
  1065.         FLD1
  1066.         FCOM  ST(1) 
  1067.         FSTSW FLOAT-WORK
  1068.         MOV   AX, FLOAT-WORK
  1069.         AND   AX, # 4100
  1070.         0=
  1071.         IF
  1072.                 FPATAN
  1073.         ELSE
  1074.                 FXCH  ST(1) 
  1075.                 FPATAN
  1076.                 FLD1
  1077.                 FLD   ST(0) 
  1078.                 FADDP ST(1), ST(0)
  1079.                 FLDPI
  1080.                 FDIVP ST(1), ST(0)
  1081.                 FSUBP ST(1), ST(0)
  1082.          THEN
  1083.          RET
  1084.          END-CODE
  1085.  
  1086. PREVIOUS FORTH
  1087.  
  1088. CODE FATAN    ( r -- arctan<r>)
  1089.         PUSH  BP 
  1090.         MOV   BP, FSP
  1091.         FLD   REAL*8 0 [BP] 
  1092.         FTST
  1093.         FSTSW FLOAT-WORK
  1094.         MOV   AX, FLOAT-WORK
  1095.         AND   AX, # 4100
  1096.         SUB   AX, # 0100
  1097.         0=
  1098.         IF
  1099.                 FCHS
  1100.                 CALL  (FATAN)
  1101.                 FCHS
  1102.         ELSE
  1103.                 CALL  (FATAN)
  1104.         THEN
  1105.         FSTP  0 [BP] 
  1106.         POP   BP 
  1107.         NEXT
  1108.         END-CODE
  1109.  
  1110. DECIMAL
  1111.  
  1112. : ARCRANGE    ( r -- r f )
  1113.         FDUP  F1.0  F>   FDUP  F1.0 FNEGATE F< OR ;
  1114.  
  1115. : FASIN    ( r -- SIN-1<r> )
  1116.         ARCRANGE
  1117.         IF      FDROP ." INVALID FASIN ARGUMENT" QUIT
  1118.         ELSE
  1119.                 FDUP  F0< FABS  F1.0  FOVER  FDUP  F*  F-  FSQRT
  1120.                 F/  FATAN
  1121.                 IF FNEGATE  THEN
  1122.         THEN ;
  1123.  
  1124. : FACOS    ( r -- COS-1<r> )
  1125.         ARCRANGE
  1126.         IF      FDROP ." INVALID FACOS ARGUMENT" QUIT
  1127.         ELSE    FDUP  F0<   FABS  F1.0  FOVER  FDUP  F*  F-  FSQRT
  1128.                 FSWAP  F/  FATAN
  1129.                 IF      PI  FSWAP  F-
  1130.                 THEN
  1131.         THEN ;
  1132.  
  1133. : VALUE
  1134.         CREATE , DOES> @ ;
  1135.  
  1136. FALSE VALUE FP?
  1137.  
  1138. : FLOATS    ( -- )
  1139.         TRUE IS FP?   ;
  1140.  
  1141. : DOUBLES    ( -- )
  1142.         FALSE IS FP? ;
  1143.  
  1144. VARIABLE EXP?  EXP? OFF
  1145.  
  1146. VARIABLE FLOATING   FLOATING OFF
  1147.  
  1148. : FLOATING?
  1149.         FLOATING @ ;
  1150.  
  1151. : (FP-CHECK)    ( f addr -- f' addr )
  1152.         [ FORTH ] DUP C@ DUP ASCII e =
  1153.         IF   DROP ASCII E OVER C!  EXP? ON  EXIT
  1154.         THEN
  1155.         DUP ASCII 0 ASCII 9 BETWEEN
  1156.         IF DROP EXIT THEN
  1157.         DUP ASCII E =
  1158.         IF DROP EXP? ON      EXIT THEN
  1159.         DUP ASCII - =
  1160.         IF DROP EXIT THEN
  1161.         DUP ASCII + =
  1162.         IF DROP EXIT THEN
  1163.         ASCII . =
  1164.         IF EXIT THEN
  1165.         NIP 0 SWAP ;
  1166.  
  1167. : FP-CHECK    ( addr -- addr f )
  1168.         EXP? OFF DUP TRUE SWAP COUNT BOUNDS
  1169.         DO
  1170.                 I (FP-CHECK) DROP
  1171.         LOOP ;
  1172.  
  1173. CODE FMUL10    ( -- )
  1174.         MOV   FLOAT-WORK # 10 WORD
  1175.         FLD   INTEGER*2 FLOAT-WORK 
  1176.         FMULP ST(1), ST(0)
  1177.         NEXT
  1178.         END-CODE
  1179.  
  1180. CODE (FADDI)    ( n -- )
  1181.         XCHG  BP, SP  
  1182.         FLD   INTEGER*2 0 [BP] 
  1183.         FADDP ST(1), ST(0)
  1184.         INC   BP 
  1185.         INC   BP 
  1186.         XCHG  SP, BP  
  1187.         NEXT
  1188.         END-CODE
  1189.  
  1190. : QCONVERT    ( +q1 adr1 -- +q2 adr2 )
  1191.         >R QI>FP R>
  1192.         BEGIN
  1193.                 1+ DUP >R C@ 10 DIGIT
  1194.         WHILE
  1195.                 FMUL10  (FADDI) DOUBLE? IF 1 DPL +! THEN R>
  1196.         REPEAT
  1197.         DROP FP>QI R> ;
  1198.  
  1199. CODE QNEGATE    ( +q -- -q )
  1200.         XCHG    BP, SP
  1201.         FLD     0 [BP] INTEGER*8
  1202.         FCHS
  1203.         FSTP    0 [BP]
  1204.         XCHG    BP, SP
  1205.         NEXT
  1206.         END-CODE
  1207.  
  1208. : QFLOAT    ( q -- r )
  1209.         DPL @ 0 MAX DPL !
  1210.         QI>FP FP>R DPL @ S>D D>R FALOG F/ ;
  1211.  
  1212. : (MANTISSA)   ( addr -- r addr | - )
  1213.         DUP 1+ C@ ASCII + = ?MISSING            ( lead "+" invalid)
  1214.         DUP 1+ C@ ASCII - = DUP >R IF 1+ THEN   ( check for lead "-")
  1215.         -1 DPL ! >R 0 0 0 0 R>
  1216.         BEGIN
  1217.                 QCONVERT DUP C@ ASCII . =       ( convert till "E" )
  1218.         WHILE
  1219.                 0 DPL !                         ( reset DPL at "." )
  1220.         REPEAT
  1221.         R> SWAP >R
  1222.         IF QNEGATE
  1223.         THEN
  1224.         QFLOAT R> ;                             ( set sign and float )
  1225.  
  1226. : (EXP)    ( addr -- d )
  1227.         1+ DUP C@ ASCII + =
  1228.         IF 1+ THEN                              ( bypass "+" if present)
  1229.         DUP C@ ASCII - = DUP >R
  1230.         IF 1+ THEN                              ( check for "-")
  1231.         0 DPL ! 0 0 ROT 1- CONVERT DROP         ( convert it )
  1232.         2DUP 308. DU< 0= ?MISSING R>
  1233.         IF DNEGATE THEN 0 DPL ! ;
  1234.  
  1235. DECIMAL
  1236.  
  1237. : FNUMBER    ( addr -- r | n | d | ; )
  1238.         [ FORTH ] FLOATING OFF FP-CHECK EXP? @ AND BASE @ 10 = AND 0=
  1239.         IF                    ( not a valid FP, valid # ?)
  1240.                 (NUMBER) DOUBLE?
  1241.                 IF
  1242.                         FP?   ( was double, if in FP mode, float it)
  1243.                         IF FLOAT FLOATING ON THEN
  1244.                 THEN
  1245.         ELSE                  ( has exponent, so convert it)
  1246.         (MANTISSA) (EXP) FLOAT FALOG F* DPL OFF FLOATING ON
  1247.         THEN ;
  1248.  
  1249. ' FNUMBER IS NUMBER
  1250.  
  1251. : F]    ( -- )
  1252.         STATE ON
  1253.         BEGIN
  1254.                 ?STACK  DEFINED DUP
  1255.                 IF    0>
  1256.                         IF   EXECUTE
  1257.                         ELSE  X,
  1258.                         THEN
  1259.                 ELSE
  1260.                         DROP  NUMBER  FLOATING?
  1261.                         IF
  1262.                                 [COMPILE] FLITERAL ELSE DOUBLE?
  1263.                                 IF
  1264.                                         [COMPILE] DLITERAL
  1265.                                 ELSE
  1266.                                         DROP [COMPILE] LITERAL
  1267.                                 THEN
  1268.                         THEN
  1269.                 THEN
  1270.                 TRUE  DONE?
  1271.         UNTIL ;
  1272.  
  1273. ' F] IS ]
  1274.  
  1275. : FMAG   ( r -- r n )
  1276.         FDUP FLOG RND>-INF DROP ;
  1277.  
  1278. CREATE FLOAT-BCD 10 ALLOT
  1279.  
  1280. VARIABLE #BCD   17 #BCD !
  1281.  
  1282. CODE R>BCD!    ( r n -- ; full precision bcd-string to FLOAT-BCD )
  1283.        FLD    #BCD INTEGER*2
  1284.        XCHG   BP, SP
  1285.        FLD    INTEGER*2 0 [BP]
  1286.        INC    BP
  1287.        INC    BP
  1288.        XCHG   SP, BP
  1289.        PUSH   BP
  1290.        MOV    BP, FSP
  1291.        FSUBRP ST(1), ST(0) 
  1292.        FLD1
  1293.        FSUBRP ST1, ST0  
  1294.        FLDL2T
  1295.        CALL   (POWER)
  1296.        FLD    REAL*8 0 [BP]
  1297.        ADD    BP, # 8
  1298.        FMULP  ST(1), ST(0)
  1299.        FSTP   FLOAT-BCD BCD
  1300.        MOV    FSP BP
  1301.        POP    BP
  1302.        WAIT
  1303.        NEXT
  1304.        END-CODE
  1305.  
  1306. : .DIGITS    ( last first -- )
  1307.         2DUP > ABORT" FP I/O error, FP stack underflow"
  1308.         DO I 1- 2/ FLOAT-BCD + C@ 16 /MOD I 2 MOD
  1309.         IF
  1310.                 DROP
  1311.         ELSE
  1312.                 NIP
  1313.         THEN
  1314.         ASCII 0 + EMIT -1 +LOOP ;
  1315.  
  1316. : FULL2    ( n -- )
  1317.         0 <# # # #> TYPE ;
  1318.  
  1319. : E.    ( r -- )
  1320.         FDUP F0=
  1321.         IF
  1322.                 FDROP SPACE ." .00000000000000000E+00 " EXIT
  1323.         THEN
  1324.         FDUP INFINITY F=
  1325.         IF
  1326.                 FDROP SPACE ." INFINITY               " EXIT
  1327.         THEN
  1328.         FMAG DUP >R R>BCD! FLOAT-BCD 9 + C@
  1329.         IF
  1330.                 ASCII - ELSE BL
  1331.         THEN
  1332.         EMIT ASCII . EMIT
  1333.         1 17 .DIGITS ASCII E EMIT R> 1+ DUP 0<
  1334.         IF
  1335.                 ASCII - ELSE ASCII +
  1336.         THEN
  1337.         EMIT ABS DUP 99 <
  1338.         IF
  1339.                 FULL2 SPACE
  1340.         ELSE
  1341.                 .
  1342.         THEN ;
  1343.  
  1344. VARIABLE #PLACES
  1345.  
  1346. : PLACES    ( n -- )
  1347.         17 MIN 1 MAX #PLACES ! ;
  1348.  
  1349.         4 PLACES
  1350.  
  1351. HEX
  1352.  
  1353. CODE FPARSE    ( r -- int-part frac-part )
  1354.         PUSH    BP
  1355.         MOV     BP, FSP
  1356.         FLD     REAL*8 0 [BP]
  1357.         FLD     ST0
  1358.         FSTCW   FLOAT-WORK
  1359.         MOV     AX, FLOAT-WORK
  1360.         MOV     CX, AX
  1361.         OR      AX, # 0C00
  1362.         MOV     FLOAT-WORK AX
  1363.         FLDCW   FLOAT-WORK
  1364.         FRNDINT
  1365.         MOV     FLOAT-WORK CX
  1366.         FLDCW   FLOAT-WORK
  1367.         FLD     ST0
  1368.         FSTP    REAL*8 0 [BP]
  1369.         FSUBRP  ST1, ST0
  1370.         SUB     BP, # 8
  1371.         FSTP    REAL*8 0 [BP]
  1372.         MOV     FSP BP
  1373.         POP     BP
  1374.         NEXT
  1375.         END-CODE
  1376.  
  1377. DECIMAL
  1378.  
  1379. : .INT    ( r -- )
  1380.         FDUP F0=
  1381.         IF
  1382.                 FDROP ASCII 0 EMIT
  1383.         ELSE
  1384.                 FMAG DUP >R R>BCD!
  1385.                 #BCD @ DUP R> - SWAP .DIGITS
  1386.         THEN ;
  1387.  
  1388. CODE FRNDFRC    ( +r -- +r )
  1389.         PUSH    BP
  1390.         FLD1
  1391.         FLD1
  1392.         FADDP   ST1, ST0       ( 2.0 ON TOP OF STACK )
  1393.         FLD    INTEGER*2 #PLACES
  1394.         FCHS
  1395.         FLDL2T
  1396.         CALL    (POWER)
  1397.         FDIVP   ST(1), ST(0)
  1398.         MOV     BP, FSP
  1399.         FLD     REAL*8 0 [BP]
  1400.         FADDP   ST(1), ST(0)
  1401.         FSTP    REAL*8 0 [BP]
  1402.         POP     BP
  1403.         NEXT
  1404.         END-CODE
  1405.  
  1406. : .FRAC    ( r -- )
  1407.         FDUP F0=
  1408.         IF
  1409.                 FDROP #PLACES @ 0
  1410.                 DO ASCII 0 EMIT
  1411.                 LOOP
  1412.         ELSE
  1413.                 -1 R>BCD! #BCD @ DUP #PLACES @ 1- - SWAP .DIGITS
  1414.         THEN ;
  1415.  
  1416. : F.    ( r -- )
  1417.         FDUP INFINITY F=
  1418.         IF
  1419.                 FDROP ." INFINITY" EXIT
  1420.         THEN
  1421.         FDUP F0<
  1422.         IF
  1423.                 ASCII - ELSE BL
  1424.         THEN
  1425.         EMIT FABS FPARSE FRNDFRC
  1426.         FDUP INT D>R FROT F+ .INT ASCII . EMIT .FRAC SPACE ;
  1427.  
  1428. : E.R0    ( #DEC   #col -- )
  1429.         OVER - 5 - SPACES ASCII . EMIT 0
  1430.         DO
  1431.                 ASCII 0 EMIT
  1432.         LOOP
  1433.         ." E+00" ;
  1434.  
  1435. : E.R#    ( r #DEC   -- )
  1436.         >R FDUP F0<
  1437.         IF
  1438.                 ASCII -
  1439.         ELSE
  1440.                 BL
  1441.         THEN
  1442.         EMIT ASCII . EMIT
  1443.         FABS R> #PLACES @ >R PLACES  FMAG DUP >R
  1444.         1+ S>D D>R FALOG F/ FMAG >R FRNDFRC FMAG DUP R> - >R
  1445.         R>BCD! #PLACES @ 17 DUP ROT - 1+ SWAP .DIGITS
  1446.         ASCII E EMIT R> R> + 1+
  1447.         DUP 0<
  1448.         IF
  1449.                 ASCII - ELSE ASCII +
  1450.         THEN
  1451.         EMIT ABS DUP 100 <
  1452.         IF
  1453.                 FULL2
  1454.         ELSE
  1455.                 .
  1456.         THEN
  1457.         R> PLACES ;
  1458.  
  1459. : E.R    ( r #DEC   #col -- )
  1460.         FDUP F0=
  1461.         IF                            \ Handle zero.
  1462.                 FDROP E.R0 EXIT
  1463.         THEN
  1464.         FDUP INFINITY F=
  1465.         IF FDROP ." INFINITY " EXIT THEN \ infinity
  1466.         FDUP FABS FLOG FABS 100.E0 F< >R \ get exponent
  1467.         2DUP SWAP - R@ IF 6 ELSE 7 THEN - 0< \ get # characters
  1468.         IF
  1469.                 0 DO ASCII * EMIT LOOP DROP FDROP R> DROP \ too big, *'s
  1470.         ELSE
  1471.                 OVER - R>
  1472.                 IF 6
  1473.                 ELSE 7
  1474.                 THEN
  1475.                 - SPACES E.R# \ ok, print it
  1476.         THEN ;
  1477.  
  1478. : F.R0    ( #DEC   #col -- )
  1479.         2DUP SWAP - 3 - 0<
  1480.         IF
  1481.                 0 DO ASCII * EMIT LOOP
  1482.                 DROP
  1483.         ELSE
  1484.                 OVER - 2- SPACES ." 0." 0
  1485.                 DO ASCII 0 EMIT LOOP
  1486.         THEN ;
  1487.  
  1488. VARIABLE F.R+-
  1489.  
  1490. VARIABLE F.R#INT
  1491.  
  1492. : (F.R)    ( |r| #DEC   #col -- +frac #DEC )
  1493.         F.R#INT @ - OVER - 2 - SPACES         \ output lead blanks
  1494.         F.R+- @
  1495.         IF
  1496.                 ASCII -
  1497.         ELSE
  1498.                 BL
  1499.         THEN
  1500.         EMIT                                  \ output sign
  1501.         >R FSWAP F.R#INT @  R>BCD! F.R#INT @  \ convert to BCD
  1502.         #BCD @ DUP ROT - SWAP 1- .DIGITS R> ; \ output digits
  1503.  
  1504. : F.R ( r #dec #col -- )
  1505.         FDUP F0=   \ test for a zero
  1506.         IF                           \ if found, handle specially
  1507.                 FDROP F.R0 EXIT      \ if found, handle specially
  1508.         THEN
  1509.         FDUP INFINITY F=
  1510.         IF
  1511.                 ." INFINITY " EXIT
  1512.         THEN
  1513.         FDUP F0< F.R+- ! FDUP                   \ store the sign flag
  1514.         FABS OVER #PLACES @ SWAP #PLACES !
  1515.         >R FRNDFRC R> PLACES
  1516.                         \ round the number to the proper number of digits
  1517.         FMAG 1+ 1 MAX DUP F.R#INT !             \ get exponent
  1518.         >R 2DUP R> - SWAP - 2 - 0<              \ get the digit count
  1519.         IF
  1520.                 FDROP E.R                       \ too big, use E.R
  1521.         ELSE
  1522.                 FNIP FPARSE (F.R) ASCII . EMIT  \ output integer
  1523.                 >R 0 R>BCD! R> #BCD @ DUP ROT - SWAP 1- .DIGITS
  1524.         THEN ;   \ convert and output fractional part
  1525.  
  1526. : FDEPTH     ( -- n )
  1527.         FSP@ FSP0 SWAP - 8 / ;
  1528.  
  1529. : .F  ( -- )
  1530.         FDEPTH ?DUP
  1531.         IF      0
  1532.                 DO
  1533.                         FDEPTH I - 1- FPICK 3 10 F.R  KEY? ?LEAVE
  1534.                 LOOP
  1535.         ELSE ." Empty "
  1536.         THEN ;
  1537.  
  1538. : ROUND    ( r -- d )
  1539.         FDUP  F0>
  1540.         IF      RND>-INF
  1541.         ELSE    RND>+INF
  1542.         THEN ;
  1543.  
  1544. : N>R    ( n -- r )
  1545.         S>D  D>R  ;
  1546.  
  1547. : R>N    ( r -- n )
  1548.         ROUND  ( INT )  DROP  ;
  1549.         ( Like  F>S  in PLOT.BLK )
  1550.  
  1551. : F>S       ( r -- n )
  1552.         INT  DROP  ;
  1553.  
  1554. : F2DUP    ( r1 r2 -- r1 r2 r1 r2 )
  1555.         FOVER  FOVER  ;
  1556.  
  1557. : FMOD    ( r1 r2 -- r3 )
  1558.         F2DUP F/  INT  D>R  F*  F-  ;
  1559.  
  1560. 8 CONSTANT  F#BYTES
  1561.  
  1562. : F,    ( r -- )
  1563.     HERE  F#BYTES  ALLOT  F!  ;
  1564.  
  1565. : FARRAY   ( Comp:  rn ... r1 r0 n+1 -- ) ( Run:  k -- rk_addr)
  1566.     CREATE
  1567.         DUP  ,   0   DO   F,   LOOP
  1568.     DOES>                               ( index pfa )
  1569.         SWAP DUP  0<
  1570.         IF
  1571.                 DROP  @
  1572.         ELSE
  1573.                 F#BYTES * 2+  +
  1574.         THEN    ;
  1575.  
  1576. .( ..Loaded)
  1577. WARNING ON
  1578.