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

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

UBYTE *s,*x;
long xs,ts,i,ndigits,nprint;

void initinteger(UBYTE *x,long n);
void add(UBYTE *s,UBYTE *x,long xs);
void sub(UBYTE *s,UBYTE *x,long xs);
void divide(UBYTE *x,long xs,long n,UBYTE *y,long *ys);


__saveds int e(void)
{
 struct DosLibrary *DOSBase;
 struct RDArgs *rdargs;
 long ret=RETURN_FAIL;
 long opts[]={0,0};

 if(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",0))
 {
  rdargs=ReadArgs(TEMPLATE,opts,NULL);
  if(opts[0])
  {
   ndigits=(*(long *)opts[0])+10;
   nprint=ndigits+7;

   if(s=(UBYTE *)AllocVec((ndigits<<1)+2,MEMF_PUBLIC|MEMF_CLEAR))
   {
    x=s+ndigits+1;
    s[0]=x[0]=1;
    i=0;
    do
    {
     i++;
     divide(x,xs,i,x,&xs);
     add(s,x,xs);
    }
    while(xs<=ndigits);
    Printf("E=\n%ld.",s[0]);
    for(i=1;i<=ndigits-10;i++)
    {
     Printf("%ld",s[i]);
     if(i%4==0)
      Printf(" ");
     if(i%28==0)
      Printf("\n  ");
    }
    Printf("\n");
    FreeVec(s);
    ret=RETURN_OK;
   }
   else
    Printf(MEM);
   FreeArgs(rdargs);
  }
  else
   Printf(MSG);
  CloseLibrary((struct Library *)DOSBase);
 }
 return(ret);
}

void divide(UBYTE *x,long xs,long n,UBYTE *y,long *ys)
{
 long i,c;

 c=0;
 for(i=xs;i<=ndigits;i++)
 {
  c=c*10+x[i];
  y[i]=c/n;
  c%=n;
 }
 *ys=xs;
 while(*ys<=ndigits&&y[*ys]==0)
  (*ys)++;
}

void add(UBYTE *s,UBYTE *x,long xs)
{
 long i,c;

 c=0;
 for(i=ndigits;i>=xs;i--)
 {
  c+=s[i]+x[i];
  if(c>=10)
  {
   s[i]=c-10;
   c=1;
  }
  else
  {
   s[i]=c;
   c=0;
  }
 }
 i=xs;
 while(c)
 {
  i--;
  c+=s[i];
  if(c>=10)
  {
   s[i]=c-10;
   c=1;
  }
  else
  {
   s[i]=c;
   c=0;
  }
 }
}

void sub(UBYTE *s,UBYTE *x,long xs)
{
 long i,c;

 c=0;
 for(i=ndigits;i>=xs;i--)
 {
  c+=s[i]-x[i];
  if(c<0)
  {
   s[i]=c+10;
   c=-1;
  }
  else
  {
   s[i]=c;
   c=0;
  }
 }
 i=xs;
 while(c)
 {
  i--;
  c+=s[i];
  if(c<0)
  {
   s[i]=c+10;
   c=-1;
  }
  else
  {
   s[i]=c;
   c=0;
  }
 }
}
