home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 181_01 / carne_fp.cod < prev    next >
Text File  |  1986-01-09  |  22KB  |  716 lines

  1. Reprinted from: Micro/Systems Journal, Volume 1. No. 5. Nov/Dec 1985    
  2. Article Title: "Faster Floating Point Math"
  3. Author: Ted Carnevale
  4. -----------------------------------------------------------------
  5. Copy of back issue may be obtained for $4.50 (foreign $6) from:
  6. Micro/Systems Journal
  7. Box 1192
  8. Mountainside NJ 07092
  9. -----------------------------------------------------------------
  10. Copyright 1986
  11. Micro/Systems Journal, Box 1192, Mountainside NJ 07092
  12. This software is released into the public domain for
  13.  non-commercial use only.
  14. -----------------------------------------------------------------
  15.  
  16.  
  17.                                   Listing 1
  18.  
  19.                                   =========
  20.  
  21. /* fpc.c--tests conversion to/from amd9511 fpp format */
  22.  
  23. #include fprintf.h
  24. #include c80def.h
  25.  
  26. #define MESSAGE  "\nFloating-point format conversion program")
  27. #define DASHES "\n\n----------------------------------------")
  28.  
  29. #define MAX 6   /* how many different values to feed 
  30.                      to the format conversion routines */
  31.  
  32. /* replace the next two functions with 
  33.      your own format conversion routines as needed */
  34. extern long c2amd();    /* link .rel file containing these */
  35. extern float amd2c();   /*   to fpc.rel */
  36.  
  37. main()
  38. {
  39.         int i;
  40.         static int sx=10;
  41.         float x;
  42.         static float dx=1.0;
  43.  
  44.         printf(MESSAGE);
  45.         printf(DASHES);
  46.  
  47.         /* a geometric series of positive values */
  48.         for (i = 0, x = 100.0; i<=MAX; x /= sx, i++) showbits(x);
  49.         printf(DASHES);
  50.  
  51.         /* a geometric series of negative values */
  52.         for (i = 0, x = -100.0; i<=MAX; x /= sx, i++) showbits(x);
  53.         printf(DASHES);
  54.  
  55.         /* a linear series of positive and negative values */
  56.         for (i = -MAX, x=(float)(-MAX); i<=MAX; x += dx, i++) showbits(x);
  57. }
  58.  
  59.  
  60. /* show bit patterns used by C80 and AMD FPP floating point formats 
  61.      to represent the float n */
  62. showbits(n)
  63. float n;
  64. {
  65.         int i;
  66.         union {
  67.                 float f;
  68.                 long l;
  69.         } x,z;  /* unions are easier to use here than pointers */
  70.         long y;
  71.  
  72.         x.f=n;
  73.  
  74.         /* show C80's preconversion bit pattern */
  75.         printf("\n\nx = %e,\t\tBCDE = ",x.f);
  76.         prntlong(x.l);
  77.  
  78. /* eliminate next few lines if you just want to check the format
  79.      used by your version of C */
  80.         /* show AMD formatted data */
  81.         y=c2amd(x.f);
  82.         printf("\n\t\t\t\t AMD = ");
  83.         prntlong(y);
  84.  
  85.         /* convert back to C80's format */
  86.         z.f=amd2c(y);
  87.         printf("\nz = %e,\t\tBCDE = ",z.f);
  88.         prntlong(z.l);
  89. /* end of C80 -> AMD -> C80 format conversion test */
  90. }
  91.  
  92.  
  93. /* print bit pattern of a long, starting with the high-order bit
  94.      of the most significant byte, working down from left to right */
  95. prntlong(k)
  96. long k;
  97. {
  98.         int i;
  99.         union {
  100.                 long l;
  101.                 char b[4];
  102.         } datum;
  103.  
  104.         datum.l=k;
  105.         for (i=3; i>=0; i--) {
  106.                 prntbyt(datum.b[i]);
  107.                 printf(" ");
  108.         }
  109. }
  110.  
  111.  
  112. /* print the bit pattern for a byte from left to right, 
  113.      high order bit first (does the dirty work for prntlong) */
  114. prntbyte(i)
  115. int i;
  116. {
  117.         int j;
  118.         char bit;
  119.  
  120.         for (j=0x80; j>0; j=j>>1) {
  121.                 if (i & j) bit='1';
  122.                 else bit='0';
  123.                 printf("%c",bit);
  124.         }
  125. }
  126.                                   Listing 2
  127.                                   =========
  128.  
  129.         TITLE FLTLB
  130.         PAGE 64
  131. ; Floating point library
  132. ; C/80 3.0 (7/7/83) - (c) 1983 Walter Bilofsky
  133. ;MODIFIED 8/84 to use amd9511 for floating point multiply/divide 
  134. ;and MATHLIB functions as well.  
  135. ;Replaces modules FLTLIB and MATHLIB
  136. ; -- N.T.Carnevale
  137. ;
  138. ;
  139. ;these were gleaned from LIB's listing of FLIBRARY.REL:
  140. ;
  141. ENTRY Bf.Bl,Bf.Hc,Bf.Hi,Bf.Hu,Bl.Bf
  142. ENTRY cf.eq,cf.ge,cf.gt,cf.le,cf.lt,cf.ne
  143. ENTRY div10.,mul10.
  144. ENTRY dum_
  145. ENTRY errcod
  146. ENTRY F.add,F.div,F.mul,F.neg,F.not,F.sub
  147. ENTRY facl_,facl_1,facl_2,fac_,fac_1
  148. ENTRY fadd.,fadda.,fcomp.,fdiv_a,fdiv_b,fdiv_c,fdiv_g
  149. ENTRY flneg.,float.,flt.0,flt_pk
  150. ENTRY fmlt_1,fmlt_2
  151. ENTRY Hc.Bf,Hi.Bf,Hu.Bf
  152. ENTRY inxhr.
  153. ENTRY movfm.,movfr.,movmf.,movrf.
  154. ENTRY pushf.,qint.,save_,save_1,sign.,zero.
  155. ;
  156. EXTRN c.neg,c.sxt,eq.4,g.,Hc.Bl,Hi.Bl,Hu.Bl,L.add,L.neg
  157. EXTRN llong.,movrm.,neq.4,slong.
  158. ;
  159. ;this preserves the 15 byte data area revealed by LIB:
  160.         DSEG
  161. ;
  162. facl_:  DB      0
  163. facl_1: DB      0
  164. facl_2: DB      0
  165. fac_:   DB      0
  166. fac_1:  DB      0
  167. save_:  DB      0
  168. fmlt_1: DB      0
  169. fmlt_2: DB      0
  170. dum_:   DB      0
  171. save_1: DB      0
  172. errcod: DB      0
  173. fdiv_a: DB      0
  174. fdiv_b: DB      0
  175. fdiv_c: DB      0
  176. fdiv_g: DB      0
  177. ;
  178. ;       CSEG
  179. ;
  180. flt_pk: DS      0
  181. F.add:  XRA     A
  182.         JMP     Dual
  183. F.sub:  MVI     A,1
  184.         JMP     Dual
  185. F.mul:  JMP     fpmul           ;jump to new routines
  186. ;       MVI     A,2
  187. ;       JMP     Dual
  188. F.div:  JMP     fpdiv
  189. ;       MVI     A,3
  190. Dual:   CALL    movfr.
  191.      
  192.  
  193.                                   Listing 3
  194.                                   =========
  195.  
  196. Ftab:   DW      fadd.
  197.         DW      fsub            ;next two addresses not used
  198. ;       DW      fpmul
  199. ;       DW      fpdiv
  200.                                   Listing 4
  201.                                   =========
  202.  
  203. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  204. ;
  205. ;
  206. ;What follows replaces the original code in the FLTLIB section of
  207. ;FLOATLIB.ASM that started with fmult3: and ended just before pophrt:.
  208.         ;
  209.         ;
  210. CR      EQU 0DH
  211. LF      EQU 0AH
  212. BDOS    EQU 5
  213. BOOT    EQU 0
  214. PSTRNG  EQU 9
  215.         ;
  216.         ;
  217.         ;send message to console
  218. PRMSG:
  219.         PUSH PSW
  220.         PUSH B
  221.         PUSH D
  222.         PUSH H
  223.         MVI C,PSTRNG
  224.         CALL BDOS
  225.         POP H
  226.         POP D
  227.         POP B
  228.         POP PSW
  229.         RET
  230.         ;
  231. ;**************************************************************
  232.         ;
  233.         ;
  234.         ;Port addresses
  235.         ;
  236. BASE    EQU 050H        ;base address of Compupro SS1 board
  237. CREG    EQU BASE+9      ;location of 9511's control & data ports
  238. DREG    EQU BASE+8
  239.         ;
  240.         ;
  241.         ;FPP error codes
  242.         ;
  243. ERRBITS EQU 1EH         ;the status register's error bits
  244. OVRFLO  EQU 2           ;overflow
  245. UNRFLO  EQU 4           ;underflow
  246. NEGARG  EQU 8           ;negative argument to sqrt or log function
  247. DIVZER  EQU 10H         ;divide by zero
  248. TOOBIG  EQU 18H         ;arg of asin, acos, or exp too big
  249.         ;
  250.         ;
  251.         ;FPP command codes
  252.         ;
  253. FMUL    EQU 12H
  254. FDIV    EQU 13H
  255. XCHF    EQU 19H         ;swap top two locations in fpp's stack
  256. FSQRT   EQU 1
  257. FSIN    EQU 2
  258. FCOS    EQU 3
  259. FTAN    EQU 4
  260. FASIN   EQU 5
  261. FACOS   EQU 6
  262. FATAN   EQU 7
  263. FLOG    EQU 8           ;log base 10
  264. FLN     EQU 9           ;natural logarithm
  265. FEXP    EQU 0AH         ;e^x
  266. FPWR    EQU 0BH         ;x^y
  267.         ;
  268. ;**************************************************************
  269. ;**************************************************************
  270. ;
  271. ;
  272. ;note:  timing indicated for some of the following
  273. ;
  274. ;This block converts c80 float in BD to FPP format, then loads it into FPP.  
  275. ;If out of range for FPP, aborts with warning.
  276. ;
  277. ;Data format conversion routine C2AMD--
  278. ;converts c80's float to amd's fp format.
  279. ;Based on suggestions by J.Shook, Electronics Lab, Dept.of Chemistry,
  280. ;SUNY Stony Brook
  281. ;
  282. ;Floating point formats
  283. ;----------------------
  284. ;C80 stores floats as:
  285. ;        mantissa sign in C7
  286. ;        mantissa  =  24 bit two's complement in CDE, 
  287. ;                        with bit 23 assumed = 1.
  288. ;        exponent is added to 128 (80H) and stored in B.  
  289. ;                        If the number is 0, B=0.
  290. ;
  291. ;FPP stores floats as:
  292. ;        mantissa sign in B7
  293. ;        mantissa  =  24 bit two's complement in CDE,
  294. ;                        with bit 23 = 1.  However, 
  295. ;                        the value 0 is represented by BD=0.
  296. ;        exponent sign in B6
  297. ;        exponent in B5-B0 (only 6 bits).
  298. ;
  299. ;
  300.         ;Call with value to convert in BD.
  301. C2AMD:
  302.         MOV A,B         ; 4
  303.         ORA A           ; 4
  304.         JZ FPPZERO      ;10--B=0 implies x=0
  305.         ;take care of register B
  306.         SUI 80H         ; 7--corrects exponent
  307.         ;does exponent lie in FPP's range?
  308.         CPI 64          ; 7
  309.         JP EXPHI        ;10--exceeds 2^63
  310.         CPI -64         ; 7
  311.         JM EXPLO        ;10--smaller than 2^-64
  312.         ;exponent ok, proceed
  313.         ANI 7FH         ; 7--mask out hi bit of B
  314.         MOV B,A         ; 4-- and save til later
  315.         MOV A,C         ; 4
  316.         ANI 80H         ; 7--isolate mantissa sign bit
  317.         ORA B           ; 4--fix mantissa sign bit for FPP
  318.         MOV B,A         ; 4--done with B
  319.         ;take care of C
  320.         MVI A,80H       ; 7
  321.         ORA C           ; 4--set hi bit of C
  322.         MOV C,A         ; 4
  323.         JMP LOADFPP     ;10--put data in FPP
  324.         ;114 t cycles @ 4mHz = 28.5usec
  325.         ;
  326. FPPZERO:                ;x=0
  327.         XRA A
  328.         MOV C,A
  329.         MOV D,A
  330.         MOV E,A
  331.         ;a short cut, time not calculated
  332.         ;fall through to next routine
  333.         ;
  334.         ;
  335.         ;Data transfer routine
  336.         ;LOADFPP puts BD into fpp
  337. LOADFPP:
  338.         MOV A,E         ; 4
  339.         OUT DREG        ;11
  340.         MOV A,D         ; 4
  341.         OUT DREG        ;11
  342.         MOV A,C         ; 4
  343.         OUT DREG        ;11
  344.         MOV A,B         ; 4
  345.         OUT DREG        ;11
  346.         RET             ;10
  347.         ;70 t cycles = 17.5usec
  348.         ;
  349.         ;TOTAL TIME for C2AMD & LOADFPP = 46usec
  350.         ;
  351. ;**************************************************************
  352.         ;
  353.         ;
  354.         ;C2AMD found float to be out of range for FPP--warn & abort
  355. EXPHI:
  356.         LXI D,HIMSG
  357.         JMP ERREXIT
  358. EXPLO:
  359.         LXI D,LOMSG
  360. ERREXIT:
  361.         CALL PRMSG
  362.         JMP BOOT        ;bail out!
  363.         ;
  364.         ;
  365. HIMSG:  DB CR,LF,'float --> FPP exponent overflow ( > 2^63)$'
  366. LOMSG:  DB CR,LF,'float --> FPP exponent underflow ( < 2^-64)$'
  367.         ;
  368. ;**************************************************************
  369. ;**************************************************************
  370.         ;
  371.         ;
  372.         ;
  373.         ;FLD1 gets 1 float from the stack, puts it into fpp,
  374.         ;and DOES NOT restore stack.  Called by "intrinsic"
  375.         ;float arithmetic operations, e.g. fpmul and fpdiv.
  376. FLD1:
  377.         POP H           ;10--return addr for this block
  378.         SHLD RETADR     ;16
  379.         POP H           ;10--return addr for calling function
  380.         POP D           ;10
  381.         POP B           ;10--BD = argument
  382.         CALL C2AMD      ;17--convert format & load FPP
  383.         ;
  384.         PUSH H          ;11--restore return address of calling function
  385.         LHLD RETADR     ;16--return to calling function
  386.         PCHL            ; 4--  without disturbing stack
  387.         ;104 t cycles = 26usec, + 46 for C2AMD = 72usec
  388.         ;
  389. ;**************************************************************
  390.         ;
  391.         ;
  392.         ;FLOAD1 gets 1 float from the stack, puts it into fpp,
  393.         ;and restores stack for c80.  Called by "user-defined"
  394.         ;functions, not by fpmul or fpdiv.
  395. FLOAD1:
  396.         POP H           ;10--return addr for this block
  397.         SHLD RETADR     ;16
  398.         POP H           ;10--return addr for calling function
  399.         POP D           ;10
  400.         POP B           ;10--BD = argument
  401.         CALL C2AMD      ;17--convert format & load FPP
  402.         ;fix stack for c80
  403.         PUSH H          ;11
  404.         PUSH H          ;11
  405.         PUSH H          ;11--restore return address of calling function
  406.         LHLD RETADR     ;16--return to calling function
  407.         PCHL            ; 4--  without disturbing stack
  408.         ;126 t cycles = 31.5usec, + 46 for C2AMD = 77.5usec
  409.         ;
  410. ;**************************************************************
  411.         ;
  412.         ;
  413.         ;FLOAD2 gets 2 floats from the stack, puts them into fpp,
  414.         ;  and restores the stack for c80
  415. FLOAD2:
  416.         POP H           ;10--return addr for this block
  417.         SHLD RETADR     ;16
  418.         POP H           ;10--return addr for calling function
  419.         POP D           ;10
  420.         POP B           ;10--BD = second argument
  421.         CALL C2AMD      ;17--convert format & load FPP
  422.         POP D           ;10
  423.         POP B           ;10--BD = first argument
  424.         CALL C2AMD      ;17
  425.         ;fix stack for c80
  426.         PUSH H          ;11 x 5 = 55
  427.         PUSH H
  428.         PUSH H
  429.         PUSH H
  430.         PUSH H          ;restore return address of calling function
  431.         LHLD RETADR     ;16--return to calling function
  432.         PCHL            ; 4--  without disturbing stack
  433.         ;185 t cycles = 46.25usec, + 2 * 46 (for C2AMD) = 138.25usec
  434.         ;
  435. RETADR: DS 2            ;used by all FPP load routines
  436.         ;
  437. ;**************************************************************
  438. ;**************************************************************
  439.         ;
  440.         ;
  441.         ;
  442.         ;fpmask() allows the user to specify which error bits
  443.         ;are tested for error detection.  The argument to fpmask
  444.         ;becomes the ERRMASK that is ANDed with the status word 
  445.         ;to detect a hardware (FPP) error.
  446.  
  447.         PUBLIC fpmask
  448. fpmask: 
  449.         POP H           ;return address
  450.         POP B           ;argument
  451.         PUSH B          ;fix stack
  452.         PUSH H
  453.         MOV A,C         ;get the user-specified error mask
  454.         ANI ERRBITS     ; and mask out all but the genuine error bits
  455.         STA ERRTEST+1
  456.         RET
  457.         ;
  458. ;**************************************************************
  459.         ;
  460.         ;
  461.         ;FPP Error handling routine
  462.         ;print message according to what sort of error occurred
  463. FPERR:
  464.         LXI D,EMSG0
  465.         CALL PRMSG      ;print general message
  466.         MOV C,A         ;save error code
  467.         MVI B,MSGPTR-ETYPES     ;# of codes to check
  468.         LXI H,ETYPES    ;M=first code in the list
  469.         LXI D,MSGPTR    ;(DE) = address that contains 
  470.                         ;  location of message for first error code
  471. ERCHEK:
  472.         ANA M
  473.         JMP ERMATCH
  474.         MOV A,C         ;restore error code
  475.         INX H           ;advance to next code and message
  476.         INX D
  477.         INX D
  478.         DCR B
  479.         JNZ ERCHEK      ;more codes to test
  480.         ;should never fall through, but if it does, will print 'huh?'
  481.         ;
  482. ERMATCH:
  483.         XCHG            ;(HL) holds address of error message
  484.         MOV E,M
  485.         INX H
  486.         MOV D,M
  487.         JMP ERREXIT     
  488.         ;
  489.         ;
  490. EMSG0:  DB CR,LF,,LF,'FPP error:  $'
  491. EMSG1:  DB 'overflow$'
  492. EMSG2:  DB 'underflow$'
  493. EMSG3:  DB 'sqrt or log of negative number$'
  494. EMSG4:  DB 'divide by 0$'
  495. EMSG5:  DB 'argument of asin, acos, or exp too large$'
  496. EMSGX:  DB 'huh?$'      ;should never occur!
  497.         ;
  498.         ;
  499. ETYPES: DB OVRFLO,UNRFLO,TOOBIG,NEGARG,DIVZER
  500. MSGPTR: DW EMSG1,EMSG2,EMSG5,EMSG3,EMSG4,EMSGX
  501.         ;
  502. ;**************************************************************
  503. ;**************************************************************
  504.         ;
  505.         ;
  506.         ;Next come the hardware floating point routines themselves.
  507.         ;The multiplcation routine contains most of what the 
  508.         ;other routines use, so it is listed first.
  509.         PUBLIC  fpmul
  510. fpmul:
  511.         ;Note:  for fp multiply and divide,
  512.         ;c80 passes the first arg in the stack, the second in BD.
  513.         ;For the intrinsic multiply and divide operations, 
  514.         ;the calling program does NOT have to remove args 
  515.         ;from the stack upon return!  This is quite different from
  516.         ;the situation with user-defined functions.
  517.         ;
  518.         ;take 2nd arg from BD, convert to amd format, and pass to fpp
  519.         CALL C2AMD      ;17
  520.         ;take 1st arg from stack, convert format, and pass to fpp
  521.         CALL FLD1       ;17
  522.         ;send command, test for error, return with result in BD
  523.         MVI A,FMUL      ; 7
  524.         ;fall through to DOIT-ERRTEST-GETIT-AMD2C
  525.         ;
  526.         ;
  527.         ;DOIT-GETIT starts an FPP operation, tests for error,
  528.         ;gets the result & converts to c80 format
  529.         ;
  530.         ;send command in A to FPP
  531. DOIT:   OUT CREG        ;11--send command
  532. WAIT:   IN CREG         ;10
  533.         ORA A           ; 4
  534.         JM WAIT         ;10--until done
  535.         ;11 + n*24 t cycles = 2.75 + 6n usec (X)
  536.         ;
  537.         ;A contains error code
  538. ERRTEST:
  539.         ANI ERRBITS     ; 7--default = test all error bits
  540.         JNZ FPERR       ;10--if error found, else fall through to GETIT
  541.         ;
  542.         ;get top of fpp's stack into BD
  543. GETIT:
  544.         IN DREG         ;10
  545.         MOV B,A         ; 4
  546.         IN DREG         ;10
  547.         MOV C,A         ; 4
  548.         IN DREG         ;10
  549.         MOV D,A         ; 4
  550.         IN DREG         ;10
  551.         MOV E,A         ; 4
  552.         ;
  553.         ;Fall through to AMD2C, which converts FPP format in BD
  554.         ;to c80 float
  555.         ;AMD2C is based on suggestions by J.Shook, Electronics Lab, 
  556.         ;Dept.of Chemistry, SUNY Stony Brook
  557.         ;
  558. AMD2C:
  559.         MOV A,C         ; 4
  560.         ORA A           ; 4
  561.         JP C80ZERO      ;10--bit 7=0 implies value is 0
  562.         ;take care of mantissa sign
  563.         XRA B           ; 4--complements bit 7 of B, among other things
  564.         ANI 80H         ; 7--mask out all the garbage
  565.         XRA C           ; 4--hi bit of C was 1 in AMD format, so this
  566.         MOV C,A         ; 4--  sets the hi bit of C to mantissa sign
  567.         ;take care of exponent sign
  568.         MVI A,40H       ; 7
  569.         ANA B           ; 4--is exponent negative?
  570.         MOV A,B         ; 4
  571.         JZ POSEXP       ;10--no, set hi bit to 1 (add 128)
  572.         ANI 7FH         ; 7--  yes, mask out hi bit
  573.         MOV B,A         ; 4
  574.         RET             ;10
  575.         ;
  576. POSEXP:
  577.         ORI 80H         ;set hi bit for positive exponent
  578.         MOV B,A
  579.         RET
  580.         ;format conversion delay identical whether exponent is + or -
  581.         ;
  582. C80ZERO:
  583.         XRA A
  584.         MOV B,A
  585.         RET
  586.         ;short cut--no time calculated
  587.         ;
  588.         ;(DOIT-ERRTEST-GETIT-AMD2C takes 156 t cycles 
  589.         ;  = 39usec, + X (for operation))
  590.         ;
  591.         ;41 t cycles = 10.25usec, + 46 (C2AMD) + 72 (FLD1) + 39 
  592.         ;  + X (DOIT) = 167.25 + X usec
  593.  
  594. ;
  595. ;float sqrt(x) float x;
  596.         PUBLIC  sqrt
  597. sqrt:
  598.         CALL FLOAD1
  599.         MVI A,FSQRT
  600.         JMP DOIT
  601.  
  602. ;float sin(x) float x;
  603.         PUBLIC  sin
  604. sin:
  605.         CALL FLOAD1
  606.         MVI A,FSIN
  607.         JMP DOIT
  608.  
  609. ;float cos(x) float x;
  610.         PUBLIC  cos
  611. cos:
  612.         CALL FLOAD1
  613.         MVI A,FCOS
  614.         JMP DOIT
  615.  
  616. ;float tan(x) float x;
  617.         PUBLIC  tan
  618. tan:
  619.         CALL FLOAD1
  620.         MVI A,FTAN
  621.         JMP DOIT
  622. ;float asin(x) float x;   /* arc sin in radians */
  623.         PUBLIC  asin
  624. asin:
  625.         CALL FLOAD1
  626.         MVI A,FASIN
  627.         JMP DOIT
  628.  
  629. ;float acos(x) float x;
  630.         PUBLIC  acos
  631. acos:
  632.         CALL FLOAD1
  633.         MVI A,FACOS
  634.         JMP DOIT
  635.  
  636. ;float atan(x) float x;
  637.         PUBLIC  atan
  638. atan:
  639.         CALL FLOAD1
  640.         MVI A,FATAN
  641.         JMP DOIT
  642.  
  643. ;float log(x) float x;  /* log10 */
  644.         PUBLIC  log
  645. log:
  646.         CALL FLOAD1
  647.         MVI A,FLOG
  648.         JMP DOIT
  649.  
  650. ;float ln(x) float x;   /* log e */
  651.         PUBLIC  ln
  652. ln:
  653.         CALL FLOAD1
  654.         MVI A,FLN
  655.         JMP DOIT
  656.  
  657. ;float exp(x) float x;
  658.         PUBLIC  exp
  659. exp:
  660.         CALL FLOAD1
  661.         MVI A,FEXP
  662.         JMP DOIT
  663.  
  664. ;float pwr(x,y) float x,y;      /* x to the yth power */
  665.         PUBLIC  pwr
  666. pwr:
  667.         CALL FLOAD2
  668.         ;
  669.         MVI A,XCHF
  670.         OUT CREG        ;11--send command
  671. PWAIT:  IN CREG         ;10
  672.         ORA A           ; 4
  673.         JM PWAIT        ;10--until done
  674.         ;
  675.         MVI A,FPWR
  676.         JMP DOIT
  677. ;
  678. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  679. ;briefly back to the original source for fltlib--
  680. ;
  681. ;
  682. pophrt: POP     H
  683.         RET
  684. ;
  685. ;since div10.: is called by an external routine, I left it alone.  
  686. div10.: CALL    pushf.
  687.         LXI     B,8420H
  688.         LXI     D,0000H
  689.         CALL    movfr.
  690. fdivt:  POP     B
  691.         POP     D
  692. ;
  693. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  694. ;the fdiv: routine is replaced by fpdiv:, and muldiv: is not needed
  695.  
  696.         PUBLIC  fpdiv
  697. fpdiv:
  698.         ;take 2nd arg from BD, convert to amd format, and pass to fpp
  699.         CALL C2AMD      ;17
  700.         ;take 1st arg from stack, convert format, and pass to fpp
  701.         CALL FLD1       ;17
  702.         ;swap fpp's A and B registers
  703.         MVI A,XCHF      ; 7
  704.         OUT CREG        ;11--send command
  705. DWAIT:  IN CREG         ;10
  706.         ORA A           ; 4
  707.         JM DWAIT        ;10--until done
  708.         ;send command, test for error, return with result in BD
  709.         MVI A,FDIV      ; 7
  710.         JMP DOIT        ;10
  711.         ;takes 169.75usec + X plus delay for register swap
  712.  
  713. ;END OF MODIFICATIONS TO FLTLIB.MAC<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  714. ;back to the original code again at mul10.:
  715. mul10.: CALL    movrf.
  716.