[comp.sys.mac.programmer] MPW and Think

jess@gn.ecn.purdue.edu (Jess M Holle) (06/23/91)

I have seen posts regarding the relative efficiency of MPW and Think
compilers several times recently, and it's gotten me curious. I know
that Think is a faster compiler, but I am VERY curious about the code
it produces as compared to MPW.

Does anyone have any actual test code stats?  From those of you who
have used both, what is your opinion of the code production? Are there
any particular areas where each compiler shines? If MPW's code is
generally slower (that seems to be what I've heard), then why are the
compiles so slow and is Apple working to make their code more optimized?

Jess Holle

P.S.  I use and own MPW.

guido@cwi.nl (Guido van Rossum) (06/25/91)

jess@gn.ecn.purdue.edu (Jess M Holle) writes:

>I have seen posts regarding the relative efficiency of MPW and Think
>compilers several times recently, and it's gotten me curious. I know
>that Think is a faster compiler, but I am VERY curious about the code
>it produces as compared to MPW.
>
>Does anyone have any actual test code stats?

I have one data point.  I developed my Python programming language
interpreter largely on my humble MacPlus with 1 Meg of memory using
various versions of Think C (currently 4.0).  Just to test the
portability of the stuff I decided to compile with MPW 2.0 (the only
version we have).  Surprise, the resulting Python interpreter was
actually SLOWER than the one compiled by Think C.  I can't remember by
how much but believe it was by about 10 or 20 percent.  And MPW also
compiled ten times slower, and wasn't able to compile one particularly
large function (a switch with ~100 cases) in the given memory.  And
then the messy hacks needed to add segmentation to the code :-(

I haven't tried to understand why MPW generated slower code; I suspect
however that 4 byte integers (versus 2 byte ints in Think C) have
something to do with it.

I don't know if later versions of MPW are any better.

--Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>
"Pablo Picasso was never called an asshole"

dorner@pequod.cso.uiuc.edu (Steve Dorner) (06/25/91)

In article <3764@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes:
>then the messy hacks needed to add segmentation to the code :-(

Messy hacks?  I dunno what's messy about:

#pragma segment MySegName

In fact, MPW's segmentation scheme is one of the things that I really like
about MPW compared to THINK, since it allows you to put functions from more
than one segment in a single source file.  I don't always WANT my functions
grouped by segment; sometimes, even often, other arrangements make more sense.

Perhaps this is one of the things that has changed since Guido bought his
copy of MPW.
--
Steve Dorner, U of Illinois Computing Services Office
Internet: s-dorner@uiuc.edu  UUCP: uunet!uiucuxc!uiuc.edu!s-dorner

jess@gn.ecn.purdue.edu (Jess M Holle) (06/26/91)

Thanks to everyone who replied to my question (any further opinions
appreciated as well).

The general consensus of the replies is that Think Pascal code is much
better than anything else, that MPW C was somewhat smaller and faster
than Think C (though someone provided a nice counterexample).

It was also noted that Think is rumored to be planning much greater code
optimizations for their next version.

After reading this, I have a pleading request for the MPW people at Apple:
PLEASE EMPHASIZE CODE OPTIMIZATION IN FUTURE VERSIONS! If I knew that this
was never going to happen, I'd probably switch to Think C right now. I know
that 3.2 is done, but how about working on it for 3.3.

Jess Holle

anders@verity.com (Anders Wallgren) (06/26/91)

In article <3764@charon.cwi.nl>, guido@cwi (Guido van Rossum) writes:
>I have one data point.  I developed my Python programming language
>interpreter largely on my humble MacPlus with 1 Meg of memory using
>various versions of Think C (currently 4.0).  Just to test the
>portability of the stuff I decided to compile with MPW 2.0 (the only
>version we have).  Surprise, the resulting Python interpreter was
>actually SLOWER than the one compiled by Think C.  I can't remember by
>how much but believe it was by about 10 or 20 percent.  And MPW also
>compiled ten times slower, and wasn't able to compile one particularly
>large function (a switch with ~100 cases) in the given memory.  And
>then the messy hacks needed to add segmentation to the code :-(
>

I wish I could give you a more concrete counter-example, rather than
just the following: the MPW 2.0 and MPW 3.0 C compilers are not the
same compiler, so this test isn't really accurate.

anders

ml27192@uxa.cso.uiuc.edu (Mark Lanett) (06/26/91)

jess@gn.ecn.purdue.edu (Jess M Holle) writes:

>After reading this, I have a pleading request for the MPW people at Apple:
>PLEASE EMPHASIZE CODE OPTIMIZATION IN FUTURE VERSIONS! If I knew that this
>was never going to happen, I'd probably switch to Think C right now. I know
>that 3.2 is done, but how about working on it for 3.3.

Gack! No Code Optimizations! That's what breaks always breaks! The version 3 C
compiler just can't deal properly with heavy register usage. And you know that
once a new bug gets introduced into MPW it's going to be there for a looooong
time.

>Jess Holle
--
//-----------------------------------------------------------------------------
Mark Lanett						mlanett@uiuc.edu
Software Tools Group, NCSA

d88-jwa@byse.nada.kth.se (Jon W{tte) (06/26/91)

> ml27192@uxa.cso.uiuc.edu (Mark Lanett) writes:

   >After reading this, I have a pleading request for the MPW people at Apple:
   >PLEASE EMPHASIZE CODE OPTIMIZATION IN FUTURE VERSIONS! If I knew that this

   Gack! No Code Optimizations! That's what breaks always breaks! The version
   3 C compiler just can't deal properly with heavy register usage. And you

I'll probably never get a job at ai.prep.mit.edu for saying this, but...

You know, there is a gcc for MPW (was ?)

--
						Jon W{tte
						h+@nada.kth.se
						- Speed !

ksand@apple.com (Kent Sandvik) (06/28/91)

In article <1991Jun25.161605.16017@ux1.cso.uiuc.edu>, dorner@pequod.cso.uiuc.edu (Steve Dorner) writes:
> 
> In article <3764@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes:
> >then the messy hacks needed to add segmentation to the code :-(
> 
> Messy hacks?  I dunno what's messy about:
> 
> #pragma segment MySegName
> 
> In fact, MPW's segmentation scheme is one of the things that I really like
> about MPW compared to THINK, since it allows you to put functions from more
> than one segment in a single source file.  I don't always WANT my functions
> grouped by segment; sometimes, even often, other arrangements make more sense.
> 
> Perhaps this is one of the things that has changed since Guido bought his
> copy of MPW.

Nih!, it has not changed. Actually clever segmentation tries to group functions/methods
calling each other into the same segment (in order to avoid segment loader table entries
and segment loading), so either one has to move code between files (as in Think C),
or then to just specify pragma statements (as in MPW C). Someone please correct me if 
there's a neat hack in Think C in order to avoid file structure changes just for the sake of
segmentation.

Kent Sandvik

ksand@apple.com (Kent Sandvik) (06/28/91)

In article <1991Jun25.215324.2791@ux1.cso.uiuc.edu>, ml27192@uxa.cso.uiuc.edu (Mark Lanett) writes:
> Gack! No Code Optimizations! That's what breaks always breaks! The version 3 C
> compiler just can't deal properly with heavy register usage. And you know that
> once a new bug gets introduced into MPW it's going to be there for a looooong
> time.

Well... If bugs are not reported they certainly will stay in the code. Today when
Zortech has released a C/C++ compiler for the MPW environment there's always
the possibility to switch to that compiler and see if the code produced is better,
same with the MPW GNU gcc (if someone dares to produce commercial binaries using
that compiler).

Otherwise one could always hand-code in assembler those parts that are time-critical.
I guess most professional application development projects end up doing this anyway.

Sorry if I eventually offended anyone, I just wanted to point out that even if 
critical developers find MPW C not producing the most perfect code (seems like
System 7 binaries work efficiently using MPW compilers), it does not mean a dead end.
Programmers used the AT&T UNIX pcc for a long time, and it does not exactly produce
any optimized code, but there are many operating systems and tools running out
there that have been compiled using pcc.

Kent Sandvik
60517

Loaner copies will be distributed by a number of people.  E-mail to
the person closest to you to get on the list.  Don't be too surprised
if there's a little delay; this seems to be very popular.

    barney@usc.edu -- Barney Lum -- Southern California
    geoff@apple.com -- Geoff Peck -- Northern California
    jle@hpfcla.fc.hp.com -- Jer/ Eberhard -- Colorado
    ericth@i88.isc.com -- Eric Thiele -- Illinois
    mahler@usl.edu -- Steve Mahler --Louisiana
    james@nueng.coe.northeastern.edu -- James Jones, Jr -- Massachusetts
    rjg@umnstat.stat.umn.edu -- Robert Granvin -- Minnesota
    gerry@n5jxs.jsc.nasa.gov -- Gerry Creager -- Texas
    gjh@galen.med.virginia.edu -- Galen Hekhuis -- Virginia 

A transcript has been made by Robert Dorsett (rdd@cactus.org) and is
available by anonymous ftp on rascal.ics.utexas.edu.  It's located in
the directory ~ftp/misc/av/safety-folder/SUX.  A Macintosh Microsoft
Word- formatted file is in that directory, as well as a text-readable
version.  The transcript has also been posted to sci.aeronautics, in
two parts.

Australian readers will be able to borrow a copy from Mark Ferraretto
(mferrare@physics.adelaide.edu.au).  There is some delay here, as I'm
trying to get it converted to PAL and it's taking some time.

If the demand is very heavy, I'll ask for a couple more volunteers and
get more copies circulating.

--
Mary Shafer  shafer@skipper.dfrf.nasa.gov  ames!skipper.dfrf.nasa.gov!shafer
           NASA Ames Dryden Flight Research Facility, Edwards, CA
                     Of course I don't speak for NASA
            "Turn to kill, not to engage."  CDR Willie Driscoll

knoll@well.sf.ca.us (John Knoll) (06/28/91)

Well, my experience with the relative speed difference between MPW and Think
was this:

About two years ago, I wrote some code that did a lot of integer number
crunching.  I wrote it in MPW C 2.0. Recently, I ported it to Think C, since
that is the environment I have come to prefer.  The exact same code in
Think C runs at 90% the speed of the MPW code. (I had MPW's optimizers on)

Your milage may vary, but my experience is that MPW C generates faster code.

dvorak@extro.ucc.su.OZ.AU (Darko Volaric) (06/29/91)

Mr Sandwich sez:
>same with the MPW GNU gcc (if someone dares to produce commercial binaries using
>that compiler).
Mmm...didn't Mr Jobs, Perot, et al, dare a few million by compiling the Next OS
with the GNU compiler?

I think you may be being a wee bit paranoid, and giving the wrong impression.
Using the GNU compiler goes not mean that you have to give away the source to
your program. IF you modify THE COMPILER and distribute it, your must also
freely distribute your modifications.

>Kent Sandvik
>60517

Hope you're enjoying sunny California,
Darko Volaric

peirce@outpost.UUCP (Michael Peirce) (06/29/91)

In article <1991Jun29.075457.28418@metro.ucc.su.OZ.AU>, dvorak@extro.ucc.su.OZ.AU (Darko Volaric) writes:
> Mr Sandwich sez:
> >same with the MPW GNU gcc (if someone dares to produce commercial binaries using
> >that compiler).
> Mmm...didn't Mr Jobs, Perot, et al, dare a few million by compiling the Next OS
> with the GNU compiler?
> 
> I think you may be being a wee bit paranoid, and giving the wrong impression.
> Using the GNU compiler goes not mean that you have to give away the source to
> your program. IF you modify THE COMPILER and distribute it, your must also
> freely distribute your modifications.

I believe the libraries that come with gcc are covered by the FSF
CopyLeft.

Remember, the Free Software Foundation is *actively* discouraging
for-profit use of their sofitware.

--  Michael Peirce         --   outpost!peirce@claris.com
--  Peirce Software        --   Suite 301, 719 Hibiscus Place
--  Macintosh Programming  --   San Jose, California 95117
--           & Consulting  --   (408) 244-6554, AppleLink: PEIRCE

peterc@Sugar.NeoSoft.com (Peter Creath) (06/29/91)

OK, folks, how the HELL do I calculate a sine from Think C?  I have tried
using FracSin, but Think C doesn't seem to know how to handle Fract's and
Fixed's.  I can declare them just fine, but when I try something like
defining a Fixed=0.05*(x^2+y^2); and I should be getting 9.25 (I checked
on my calculator), Think C puts what it thinks is 9 into the Fixed.  Upon
examining the exact hex data, Think C isn't converting it to a Fixed.
It's converting it to a long.  So, when I go to FracSin and Think C tries
to put .471.... into a Fract, my debugger says it's 85-thousand something.
Of course, when sines should be from -1 to 1, that does sorta screw up
any calculations you were doing...
 
So is there any way to tell Think C how to handle Fract's and Fixed's?
Or is there an easier way to calculate a sine?  (I've got an SE/30, so
I've got the 68881)
 
PLEASE respond in E-mail.  My news system doesn't allow threading...
--
peterc@sugar.neosoft.com           "Listen, there's a hell of a good
peterc@sugar.hackercorp.com         universe next door.  Let's go!"
(take your pick)                                      -e e cummings


-- 

peterc@Sugar.NeoSoft.com (Peter Creath) (06/30/91)

Well, I figured out a way to do sines & cosines (I think):
 
I multiply floats (small ones) by 30000, convert that to long, that to
Fixed, that to Frac.  Convert a 30000 long to Fixed to Frac.  Do a FracDiv
of the multiplied original number by the Frac'd 30000 to get the original
number.  The perform the operation on that.
(FracSin, that is)
 
Of course, now there's another problem.
 
This system won't work with anything over about 1.1.  So to solve that I'm
trying to take the reciprocal and take the square root of that (FracSqrt)
and then take the reciprocal of THAT.  Horribly inefficient.
 
I intensely dislike having to do it this way.  Especially with square
roots.  Is Apple really that short-sighted to put in a square root
function that only works with values from -2 to 1.999999999?
 
Or is there some call other than FracSqrt for square roots?


-- 

dvorak@extro.ucc.su.OZ.AU (Darko Volaric) (06/30/91)

In article <D2150035.jd2uo2@outpost.UUCP> peirce@outpost.UUCP (Michael Peirce) writes:
>
>In article <1991Jun29.075457.28418@metro.ucc.su.OZ.AU>, dvorak@extro.ucc.su.OZ.AU (Darko Volaric) writes:
>> Mr Sandwich sez:
>> >same with the MPW GNU gcc (if someone dares to produce commercial binaries using
>> >that compiler).
>> Mmm...didn't Mr Jobs, Perot, et al, dare a few million by compiling the Next OS
>> with the GNU compiler?
>> 
>> I think you may be being a wee bit paranoid, and giving the wrong impression.
>> Using the GNU compiler goes not mean that you have to give away the source to
>> your program. IF you modify THE COMPILER and distribute it, your must also
>> freely distribute your modifications.
>
>I believe the libraries that come with gcc are covered by the FSF
>CopyLeft.
You're not required to use the GNU libraries. MPW GCC uses MPW libraries, for
instance.

>
>Remember, the Free Software Foundation is *actively* discouraging
>for-profit use of their sofitware.
I'm not so sure about that. They may be discouraging unscrupulous use of their
software, but on whole I think their main concern is the freedom of source code
and that lots of people use it. If they didn't want people to make money out of
their software, they wouldn't let hardware vendors sell machines with their
software on it.

I'm not the FSF. One should mail them (at gnu@prep.ai.mit.edu, I think) if one
wants to get definitive answers...

Darko Volaric

guido@cwi.nl (Guido van Rossum) (07/01/91)

ksand@apple.com (Kent Sandvik) writes:

>In article <1991Jun25.161605.16017@ux1.cso.uiuc.edu>, dorner@pequod.cso.uiuc.edu (Steve Dorner) writes:
>> 
>> In article <3764@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes:
>> >then the messy hacks needed to add segmentation to the code :-(
>> 
>> Messy hacks?  I dunno what's messy about:
>> 
>> #pragma segment MySegName
>> 
>> In fact, MPW's segmentation scheme is one of the things that I really like
>> about MPW compared to THINK, since it allows you to put functions from more
>> than one segment in a single source file.  I don't always WANT my functions
>> grouped by segment; sometimes, even often, other arrangements make more sense.
>> 
>> Perhaps this is one of the things that has changed since Guido bought his
>> copy of MPW.
>
>Nih!, it has not changed. Actually clever segmentation tries to group functions/methods
>calling each other into the same segment (in order to avoid segment loader table entries
>and segment loading), so either one has to move code between files (as in Think C),
>or then to just specify pragma statements (as in MPW C). Someone please correct me if 
>there's a neat hack in Think C in order to avoid file structure changes just for the sake of
>segmentation.

Actually it has changed since I last used MPW: I had to write
something like

	#define __SEGMENT__ MySegName

but I used "messy hacks" in relation to hat you have to do if you
don't want to edit your source files: split the program in libraries
containing one segment each and rename the segment name when combining
the libraries.

My complaint against the #pragma approach is that (again this may have
changed) if I don't care about segmentation I still have to edit my
source, or write an incredibly complicated Makefile.  In Think C I
can just drag around the files between segments until they fit.

I probably should point out (and this is not an apology, just a
clarification!) that my view of Mac programming is somewhat unusual
for the Mac crowd inhabitating this newsgroup -- I like to write
portable C code and be able to use it both on UNIX and on my Mac.
Anything on the Mac that gets in my way gets a bad score, especially
if it's something that the compiler could do for me just as easily.
(My favorite gripe against Think C is that there still is no full
equivalent of the UNIX -I and -D compiler options.)

--Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>
"It's a bit runny, sir"

peterc@Sugar.NeoSoft.com (Peter Creath) (07/01/91)

Well, I've got more problems.  I'm not sure if it's math, or what,
but here's the errors I've been getting:
 
for GraphIt():
     Bus Error at 0034956E (I hit "G" to continue, and then)
     Spurious Interrupt or Uninitialized Interrupt Vector at 00349572
         (I hit "G" once again, and these errors repeat a few times.
          Then the program locks up)
 
for GraphIt2():
     "Unimplemented Instruction at 0001A208
      Unimplemented Instruction at 0001A208
      *** MacsBug caused the exception ***" and then it locks up...
 
Now, I don't know what the hell is wrong with this program.  I'm sure
it's some small detail I'm overlooking.  (It's probably a big detail,
actually...)  Anyway, here's the source code.  If you can figure out
what's wrong, PLEASE mail me.
 
#define NIL     0L
 
EventRecord     gTheEvent;
 
main()
{
ToolBoxInit();
WindowShow();
ExitToShell();
}
 
ToolBoxInit()
{
InitGraf(&thePort);
InitFonts();
FlushEvents(everyEvent,0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(NIL);
InitCursor();
}
 
WindowShow()
{
WindowPtr       theWindow;
GrafPtr         savedPort;
int c=0;
 
theWindow=NewWindow(NIL,&(screenBits.bounds),"\p",TRUE,
        plainDBox,-1L,FALSE,0L);
GetPort(&savedPort);
SetPort(theWindow);
SetOrigin(-100,-100);
BackPat(black);
PenPat(white);
HideCursor();
FillRect(&(theWindow->portRect),black);
GraphIt();                         /* GraphIt() or GraphIt2() */
SetPort(savedPort);
while (!Button());
ShowCursor();
DisposeWindow(theWindow);
}
 
GraphIt(void)
{
short g[44],p[28][18];
short i,j,jc,x,y,z;
float zz;
 
for (i=1;i<=43;i++) {
     g[i]=159-(6*(i-27))*(i>27);
     }
y=-8;
for (i=127;i>=31;i-=6) {
     x=-13;
     for (j=128-i;j<=(284-i);j+=6) {
          jc=(j+5)/6;
          zz=(x*x+y*y);
          zz=10*sin(zz/20);
          z=zz;
          if ((z+i)<0) z=-i;
          if ((z+i)>g[jc]) {
               if (j==(128-i)) MoveTo(j,g[jc]);
               else LineTo(j,g[jc]);
               }
          else {
               g[jc]=z+i;
               if (j==(128-i)) MoveTo(j,(z+i));
               else LineTo(j,(z+i));
               }
          p[(x+14)][(y+9)]=g[jc];
          x++;
          }
     y++;
     }
for (x=1;x<=27;x++) {
     MoveTo((6*x-5),p[x][1]);
     for (y=2;y<=17;y++) {
          LineTo((6*(x+y)-11),p[x][y]);
          }
     }
for (x=1;x<=27;x++) {
     MoveTo((6*x-5),p[x][1]);
     LineTo((6*x-5),159);
     }
for (y=2;y<=17;y++) {
     MoveTo((6*y+151),p[27][y]);
     LineTo((6*y+151),165-y*6);
     }
MoveTo(1,159);
LineTo(157,159);
LineTo(253,63);
}
 
/*================================================*/
GraphIt2()
{
/* CONSTANTS = A,B,C,D,E,F,G        (81,58) should be 1st point
FOR-NEXT VARIABLES = H,BB
DEPENDENT ON H = AA,BB
DEPENDENT ON H AND BB = CC, D1,DD
PLOTTING VARIABLES = X,X1,Y,Y1
DEPENDENT ON BB AND H = X,X1
DEPENDENT ON DD AND H = Y,Y1 */
 
float n1,n2,p;
float a=144,c,e=160,f,g=199;
float bb,cc,d1,dd;
float x,y,fTemp;
float b=2.25,h;
short x1,y1,aa;
Fract frc,frc2;
 
n1=20; /* -40 to 40  - vscale */
n2=90; /* -50 to 150 - vpos */
 
c=n1;f=n2;
 
for (h=-a;h<=a;h+=b) {
     p=a*a-h*h;
     p=sqrt(p);
     p+=.5;
     aa=p;                       /* aa=int(.5+sqr(a^2-h^2)); */
     for (bb=-aa;bb<=aa;bb++) {
          fTemp=sqrt(bb*bb+h*h)*0.0327; /* q=sqrt(bb*bb+h*h)*0.0327 */
          d1=cos(b);
          d1+=cos(2*b);
          d1+=cos(5*b);                 /* cos(q)+cos(2*q)+cos(5*q) */
          dd=d1*c;
          x=bb+(h/b)+e;
          y=dd-(h/b)+f;
          x=x*0.85;y=0.9*(g-y);
          x1=x;
          y1=y;
          if (y1>=0 && y1<191) {
               MoveTo(x1,y1);
               LineTo(x1,y1);
               PenPat(black);
               MoveTo(x1,(y1+1));
               LineTo(x1,190);
               PenPat(white);
               }
          }
     }
}
 
And here's the AppleSoft BASIC program I took GraphIt2() from:
 
 1000  REM  ------------------------------
 1010 :
 1020  REM       ***********************
 1030  REM       *                     *
 1040  REM       * THREE-DIMENSIONAL PLOT 
 1050  REM       *                     *
 1060  REM       ***********************
 1070 :
 1080  HOME 
 1090  PRINT : PRINT 
 1100  PRINT "TO EXPAND OR COMPRESS THE PLOT
 1110  PRINT "VERTICALLY, ENTER A NUMBER
 1120  INPUT "FROM -40 TO 40 (20 IS TYPICAL).";N1
 1130  PRINT : PRINT 
 1140  PRINT " TO MOVE THE PLOT UP OR DOWN
 1150  PRINT " ON THE SCREEN, ENTER A NUMBER
 1160  INPUT " FROM -50 TO 150 (90 IS TYPICAL).";N2
 1170 :
 1180  REM  ------------------------------
 1190 :
 1200  REM  CONSTANTS = A,B,C,D,E,F,G
 1210  REM  FOR-NEXT VARIABLES = H,BB
 1220  REM  DEPENDENT ON H = AA,BB
 1230  REM  DEPENDENT ON H AND BB = CC, D1,DD
 1240  REM  PLOTTING VARIABLES = X,X1,Y,Y1
 1250  REM  DEPENDENT ON BB AND H = X,X1
 1260  REM  DEPENDENT ON DD AND H = Y,Y1
 1270 :
 1280 A = 144
 1290 B = 2.25
 1300 C = N1
 1310 D = .0327
 1320 E = 160
 1330 F = N2
 1340 G = 199
 1350 :
 1360  REM  ------------------------------
 1370 :
 1380  HGR : POKE  - 16302,0
 1390  HCOLOR= 3
 1400 :
 1410  FOR H =  - A TO A STEP B
 1420 AA =  INT (.5 +  SQR (A ^ 2 - H ^ 2))
 1430  FOR BB =  - AA TO AA
 1440 CC =  SQR (BB ^ 2 + H ^ 2) * D
 1450 D1 =  FN R(CC)
 1460 DD = D1 * C
 1470  GOSUB 1520
 1480  NEXT BB
 1490  NEXT H
 1500 :
 1510  STOP 
 1520 :
 1530  REM  ------------------------------
 1540 :
 1550 X = BB + (H / B) + E
 1560 Y = DD - (H / B) + F
 1570 X1 =  INT (.85 * X)
 1580 Y1 =  INT (.9 * (G - Y))
 1590  IF Y1 < 0 OR Y1 > 190 THEN  RETURN 
 1600  HPLOT X1,Y1
 1610 :
 1620  REM  ERASE BACKGROUND
 1630  HCOLOR= 0: REM  BLACK
 1640  HPLOT X1,(Y1 + 1) TO X1,190
 1650  HCOLOR= 3: REM  WHITE AGAIN
 1660 :
 1670  RETURN 
 
 
PLEASE send all responses in E-mail.  My news system doesn't allow
threading...
--
peterc@sugar.neosoft.com           "Listen, there's a hell of a good
peterc@sugar.hackercorp.com         universe next door.  Let's go!"
(take your pick)                                      -e e cummings
 
p.s. I'm using Think C 4.0.4 including MacHeaders and ANSI-881
p.p.s  On the BASIC source, I forgot:
       "10  DEF FN R(Q) = COS(Q) + COS (2 * Q) + COS (5 * Q)"


--