#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/memory.h>

#define TEMPLATE "DECIMALES/N"
#define MEM "Pas assez de mémoire.\n"
#define MSG "\n \033[1mCalcPI 1.0\033[0m      Ringard' Production 95\n\n   Allenbrand Brice\n   5 rue du Manège\n   68100 Mulhouse\n\n"


int pi(void)
{
 struct DosLibrary *DOSBase;
 struct RDArgs *rdargs;
 long t,r,n,i=1,l=1,ret=RETURN_FAIL;
 long *x,*y,*z,*u,*s; 
 long k,g=0,h=0,f=0;
 long opts[]={0,0};

 if(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",0))
 {
  rdargs=ReadArgs(TEMPLATE,opts,NULL);
  if(opts[0])
  {
   n=((*(long *)(opts[0]))+11)>>2;
   if(x=(long *)AllocVec(n*sizeof(long)*5,MEMF_PUBLIC|MEMF_CLEAR))
   {
    y=x+n;
    z=y+n;
    s=z+n;
    u=s+n;
    n-=2;
    x[0]=18*48;y[0]=32*57;z[0]=-20*239;
    do
    {
     switch((g>n)+(h>n))
     {
      case 0:
       r=0;
       for(k=h;k<=n;k++)
       {
        t=r+z[k];z[k]=t/57121;
        if(z[k]<0)
         z[k]--;
        r=(t-z[k]*57121)*10000;
       }
       if(z[h]==0)
        h++;
      case 1:
       r=0;
       for(k=g;k<=n;k++)
       {
        t=r+y[k];y[k]=t/3249;r=(t-y[k]*3249)*10000;
       }
       if(y[g]==0)
        g++;
     }
     r=0;
     for(k=f;k<=n;k++)
     {
      t=r+x[k];x[k]=t/324;r=(t-x[k]*324)*10000;
     }
     r=0;
     for(k=n;k>=f;k--)
     {
      t=r+x[k]+y[k]+z[k];r=t/10000;u[k]=t-r*10000;
     }
     r=0;
     for(k=f;k<=n;k++)
     {
      t=r+u[k];u[k]=t/i;r=(t-u[k]*i)*10000;
     }
     r=0;
     for(k=n;k>=f;k--)
     {
      t=r+l*u[k]+s[k];r=t/10000;s[k]=t-r*10000;
     }
     l=-l;i+=2;
     if(x[f]==0)
      f++;
    }
    while(u[n]>0);
    for(k=n;k>=1;k--)
     if(s[k]<0)
     {
      s[k]+=10000;
      s[k-1]--;
     }
    Printf("PI=\n3.");
    for(k=1;k<=n;k++)
    {
     if(s[k]<10)
      Printf("000");
     else
      if(s[k]<100)
       Printf("00");
      else
      if(s[k]<1000)
       Printf("0");
     Printf("%ld ",s[k]);
     if(k%7==0)
      Printf("\n  ");
    }
    Printf("\n");
    ret=RETURN_OK;
    FreeVec(x);
   }
   else
    Printf(MEM);
   FreeArgs(rdargs);
  }
  else
   Printf(MSG);
  CloseLibrary((struct Library *)DOSBase);
 }
 return(ret);
}