#include <stdio.h>
#include <stdlib.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/timer.h>
#include <math.h>
#include "compiler.h"

/****** posbb_tests.c/Test_IMath ********************************************
*
*   NAME
*     Test_IMath -- Tests the speed of some int Math operations.
*
*   SYNOPSIS
*     time = Test_IMath( int precision )
*     ULONG Test_IMath( int );
*
*   FUNCTION
*     Does 1 million of additions,differences,multiplications and divisions
*     and returns the time it took.
*
*   INPUT
*     int precision     the precision of the results. Can be any of
*                       POSBB_PREECISION#?. The higher is the precision wanted,
*                       the higher the time taken. precision is useful on faster
*                       machines,on wich the times will be too low.
*
*   RESULT
*     time - Time spent in seconds. No error can be returned.
*
*   EXAMPLE
*     See posbb.c/Perform_Tests()
*
*   BUGS
*
*     Like some other function it uses if (freeze == TRUE) Forbid()/if (freeze == TRUE) Permit(),wich probably will
*     not work under a future Amiga OS.
*     It doesn't check if memory allocations fail. In that case it will
*     probably crash. I'll fix it in future versions.
*
****************************************************************************
*/
ULONG Test_IMath( precision,freeze,mt )
int precision;
BOOL freeze,mt;
{
  int c,i=0,time;
  ULONG *a=0,*b=0,*d=0,secs;
  struct timeval *time1,*time2;
  char tmpstr[20];
  time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);

  a = calloc(sizeof(ULONG),100*precision);
  b = calloc(sizeof(ULONG),100*precision);
  d = calloc(sizeof(ULONG),100*precision);
  /* Initializing b and d table with random values */
  for(i =0;i<(100*precision);i++)
  {
    b[i] = rand();
    d[i] = rand();
  }
#ifndef NOFORBID
  if (freeze == TRUE) Forbid();
#endif
  if (mt)
  {
    printf("Press RETURN to start");
    getchar();
  }
  else  GetSysTime(time1);   /* This gets the system time using timer.device. It is opened by posbb.c */

  for (c = 0;c<10000;c++)
  {
    for ( i = 0; i<(100 * precision)-3; i+=3 )
    {
      a[i] /= b[i] + d[i];
      a[i+1] *= b[i+1] - d[i+1];
      a[i+2] += b[i+2] * d[i+2];
      a[i+3] -= b[i+3] / d[i+3];
    }
  }
if (mt)
	{
	  DisplayBeep();
	  printf("Test finished. Type in the number of seconds taken:");
	  secs = atoi(gets(tmpstr));
	}
	else GetSysTime(time2);
#ifndef NOFORBID
  if (freeze == TRUE) Permit();
#endif
  free(a);
  free(b);
  free(d);
  if (mt) time = secs * 1000;
  else
  {
    SubTime(time2,time1);
    time = (time2->tv_secs)*1000+(time2->tv_micro)/1000;
  }
  POSBB_FreeMem(time1,sizeof(struct timeval));
  POSBB_FreeMem(time2,sizeof(struct timeval));
  return time;
}
/****** posbb_tests.c/Test_FPMath ********************************************
*
*   NAME
*     Test_FPMath -- Tests the speed of some floating point Math operations.
*
*   SYNOPSIS
*     time = Test_FPMath( int precision )
*     ULONG Test_FPMath( int );
*
*   FUNCTION
*     Does 1 million of additions,differences,multiplications and divisions
*     and returns the time it took.
*
*   INPUT
*     int precision     the precision of the results. Can be any of
*                       POSBB_PREECISION#?. The higher is the precision wanted,
*                       the higher the time taken. precision is useful on faster
*                       machines,on wich the times will be too low.
*
*   RESULT
*     time - Time spent in seconds. At the moment no error can be returned.
*
*   EXAMPLE
*     See posbb.c/Perform_Tests()
*
*   NOTES
*     To obtain code for FPU use the right option of your compiler.
*
*   BUGS
*     Like some other functions it uses if (freeze == TRUE) Forbid()/if (freeze == TRUE) Permit(),wich probably will
*     not work under a future Amiga OS.
*     Until now it doesn't check if memory allocations needed for variuos
*     tables used in the test has failed. In that case it will probably
*     crash. I'll fix it in new versions.
*
****************************************************************************
*/
ULONG Test_FPMath( precision ,freeze,mt)
int precision;
BOOL freeze,mt;
{
  int c,i=0;
  ULONG secs,time;
  double *a=0,*b,*d;
  struct timeval *time1,*time2;
  char tmpstr[20];
  time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);

  a = calloc(sizeof(double),100*precision);
  b = calloc(sizeof(double),100*precision);
  d = calloc(sizeof(double),100*precision);
  /* Initializing b and d table with random values; */
  for(c =0;c<(100*precision);c++) {
    b[c] = (double) rand();
    d[c] = (double) rand();
  }
#ifndef NOFORBID
  if (freeze == TRUE) Forbid();
#endif
  if (mt)
  {
    printf("Press RETURN to start");
    getchar();
  }
  else  GetSysTime(time1);   /* This gets the system time using timer.device. It is opened by posbb.c */

  for (c = 0;c<10000;c++)
  {
    for ( i = 0; i<(100 * precision)-3; i+=3 )
    {
      a[i] /= b[i] + d[i];
      a[i+1] *= b[i+1] - d[i+1];
      a[i+2] += b[i+2] * d[i+2];
      a[i+3] -= b[i+3] / d[i+3];
    }
  }
#ifndef NOFORBID
  if (freeze == TRUE) Permit();
#endif
if (mt)
	{
	  DisplayBeep();
	  printf("Test finished. Type in the number of seconds taken:");
	  secs = atoi(gets(tmpstr));
	}
	else GetSysTime(time2);
  free(a);
  free(b);
  free(d);
  if (mt) time = secs * 1000;
  else
  {
    SubTime(time2,time1);
    time = (time2->tv_secs)*1000+(time2->tv_micro)/1000;
  }
  POSBB_FreeMem(time1,sizeof(struct timeval));
  POSBB_FreeMem(time2,sizeof(struct timeval));

  return time;

}
ULONG Test_TMath(precision,freeze,mt)
int precision;
BOOL freeze,mt;
{
  struct timeval *time1,*time2;
  int c;
  char tmpstr[20];
  ULONG time,secs;
  double *cosine=0,*sine=0,*tangent=0,angle = 0;
  time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),0);
  cosine = calloc(sizeof(double),360*precision);
  sine = calloc(sizeof(double),360*precision);
  tangent = calloc(sizeof(double),360*precision);
#ifndef NOFORBID
  if (freeze == TRUE) Forbid();
#endif
  if (mt)
  {
    printf("Press RETURN to start");
    getchar();
  }
  else  GetSysTime(time1);   /* This gets the system time using timer.device. It is opened by posbb.c */
  for(c=0;c<100;c++){
    for(angle=0;angle<360*precision;angle++)
    {
      sine[(int)angle] = sin(angle);
      cosine[(int)angle] = cos(angle);
      tangent[(int)angle] = tan(angle);
    }
  }
 if (mt)
	{
	  DisplayBeep();
	  printf("Test finished. Type in the number of seconds taken:");
	  secs = atoi(gets(tmpstr));
	}
	else GetSysTime(time2);
#ifndef NOFORBID
  if (freeze == TRUE) Permit();
#endif
  free(sine);
  free(cosine);
  free(tangent);
  if (mt) time = secs * 1000;
  else
  {
    SubTime(time2,time1);
    time = (time2->tv_secs)*1000+(time2->tv_micro)/1000;
  }
  POSBB_FreeMem(time1,sizeof(struct timeval));
  POSBB_FreeMem(time2,sizeof(struct timeval));
  return (time);
}




