#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_POSBB_CopyMem ******************************************
*
*   NAME
*     Test_POSBB_CopyMem -- Tests speed of exec.library/POSBB_CopyMem().
*
*   SYNOPSIS
*     time = Test_CopyMem( int precision )
*
*     ULONG Test_CopyMem( int );
*
*   FUNCTION
*     Does 100,000 CopyMem() of a 1024 bytes memory block and returns the
*     time it has spent.
*
*   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.
*     BOOL freeze       if it's TRUE before starting the tests it will Forbid()
*                       (only if NOFORBID isn't defined)
*     BOOL mt           if it's TRUE it ask for a return from the user before starting
*                       and DisplayBeep()s after finishing,so the user can measure
*                       the time. It useful on UAE and emulators in general,'cause on that
*                       systems the time measured by posbb (and any other program) isn't
*                       correct.
*
*
*   RESULT
*     time - Time spent,in micorseconds.
*            TRUE if something went wrong (usually lack of memory,but is very strange
*            that the user hasn't 2048  bytes free).
*
*   EXAMPLE
*     Examine posbb.c/Perform_Tests().
*
*   BUGS
*     It has no known bugs.
*
****************************************************************************
*/
ULONG Test_CopyMem( precision, freeze,mt )
int precision;
BOOL freeze,mt;
{
   struct timeval *time1,*time2;
   int c;
   ULONG mem1,mem2,time,secs;
   char tmpstr[20];
   time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),MEMF_FAST);
   time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),MEMF_FAST);

   if (mem1=POSBB_AllocMem(1024,0))
   {
     if (mem2=POSBB_AllocMem(1024,0))
     {
#ifndef NOFORBID
	if (freeze == TRUE) Forbid(); /* This turns off multitasking */
#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<100000*precision; c++ )
	{
	  POSBB_CopyMem(mem1,mem2,1024);
	}

	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(); /* This turns on multitasking again   */
#endif
	POSBB_FreeMem(mem1,1024);
	POSBB_FreeMem(mem2,1024);
     }
     else return TRUE;   /* return true for error */
   }
   else return TRUE;

  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_CopyMem_512kb( precision, freeze,mt )
int precision;
BOOL freeze,mt;
{
   struct timeval *time1,*time2;
   int c;
   ULONG mem1,mem2,time,secs;
   char tmpstr[20];
   time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),MEMF_FAST);
   time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),MEMF_FAST);

   if (mem1=POSBB_AllocMem(512*1024,0))
   {
     if (mem2=POSBB_AllocMem(512*1024,0))
     {
#ifndef NOFORBID
	if (freeze == TRUE) Forbid(); /* This turns off multitasking */
#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<200*precision; c++ )
	{
	  POSBB_CopyMem(mem1,mem2,512*1024);
	}

	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(); /* This turns on multitasking again   */
#endif
	POSBB_FreeMem(mem1,512*1024);
	POSBB_FreeMem(mem2,512*1024);
     }
     else return TRUE;   /* return true for error */
   }
   else return TRUE;

  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_CopyMem_1Mb( precision, freeze,mt )
int precision;
BOOL freeze,mt;
{
   struct timeval *time1,*time2;
   int c;
   ULONG mem1,mem2,time,secs;
   char tmpstr[20];
   time1 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),MEMF_FAST);
   time2 = (struct timeval *) POSBB_AllocMem(sizeof(struct timeval),MEMF_FAST);

   if (mem1=POSBB_AllocMem(1024*1024,0))
   {
     if (mem2=POSBB_AllocMem(1024*1024,0))
     {
#ifndef NOFORBID
	if (freeze == TRUE) Forbid(); /* This turns off multitasking */
#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*precision; c++ )
	{
	  POSBB_CopyMem(mem1,mem2,1024*1024);
	}

	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(); /* This turns on multitasking again   */
#endif
	POSBB_FreeMem(mem1,1024*1024);
	POSBB_FreeMem(mem2,1024*1024);
     }
     else return TRUE;   /* return true for error */
   }
   else return TRUE;

  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;
}
