#include <exec/memory.h>
#include <proto/timer.h>
#include <proto/exec.h>
#include <stdio.h>
#include "time.h"

struct TimerObject
{
	struct Library		*TimerBase;
	struct MsgPort		*MsgPort;
	struct timerequest	*IO;
	struct EClockVal	MyOldEClockVal;
	struct EClockVal	MyEClockVal;
	ULONG			ticks;
};

extern struct Library	*SysBase;

#define	TimerBase	MyTimerObject->TimerBase

void*	__regargs	TimerCreateObject(void)
{
struct TimerObject	*MyTimerObject;

  if (MyTimerObject=(struct TimerObject*) AllocVec(sizeof(struct TimerObject),MEMF_ANY))
  {
    if ((MyTimerObject->MsgPort=CreatePort(NULL, 0)) != NULL)
    {
      if ((MyTimerObject->IO=(struct timerequest*) CreateStdIO(MyTimerObject->MsgPort)) != NULL)
      {
        if (OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)MyTimerObject->IO, 0) == 0L)
        {
          TimerBase	=(struct Library*) MyTimerObject->IO->tr_node.io_Device;
          return((void*) MyTimerObject);
        }
        DeleteStdIO((struct IOStdReq*) MyTimerObject->IO);
      }
      DeletePort(MyTimerObject->MsgPort);
    }
    FreeVec(MyTimerObject);
  }
  return(NULL);
}

void	__regargs	TimerDeleteObject(struct TimerObject	*MyTimerObject)
{
  if (MyTimerObject)
  {
    CloseDevice((struct IORequest*) MyTimerObject->IO);
    DeleteStdIO((struct IOStdReq*) MyTimerObject->IO);
    DeletePort(MyTimerObject->MsgPort);
    FreeVec(MyTimerObject);
  }
}

void	__regargs	TimerShow(struct TimerObject	*MyTimerObject)
{
ULONG			allticks,secs,mics;
double			micros;

  if (MyTimerObject->MyEClockVal.ev_hi <= MyTimerObject->MyOldEClockVal.ev_hi)
  {
    allticks	=	MyTimerObject->MyEClockVal.ev_lo - MyTimerObject->MyOldEClockVal.ev_lo;
  }
  else
  {
    if (MyTimerObject->MyEClockVal.ev_lo <= MyTimerObject->MyOldEClockVal.ev_lo)
    {
      allticks	=	MyTimerObject->MyEClockVal.ev_lo - MyTimerObject->MyOldEClockVal.ev_lo;
    }
    else
    {
      allticks	=	MyTimerObject->MyOldEClockVal.ev_lo - MyTimerObject->MyEClockVal.ev_lo;
    }
    allticks	+=	(MyTimerObject->MyEClockVal.ev_hi - MyTimerObject->MyOldEClockVal.ev_hi)<<16;
  }

  secs		=	allticks / MyTimerObject->ticks;
  micros	=	((double) 1 / ((double) MyTimerObject->ticks/ (double) ((allticks-(secs*MyTimerObject->ticks)))))*1000000;
  mics		=	micros;

  printf("%ld.%06ld secs\n",secs,mics);
}

BOOL	__regargs	TimerSetAttr(struct TimerObject	*MyTimerObject,
                                     ULONG		Attr)
{
  if (Attr==TIMERTAG_START)
  {
    MyTimerObject->ticks		=	ReadEClock(&MyTimerObject->MyOldEClockVal);
  }
  else if (Attr==TIMERTAG_STOP)
  {
    MyTimerObject->ticks		=	ReadEClock(&MyTimerObject->MyEClockVal);
  }

  return(TRUE);
}

