/*  
 *  Timer.c: Functions to invoke the Amiga timer:
 *  
 *  External Functions:
 *
 *  OpenTimer, CloseTimer, StartTimer, TimerExpired, GetTimerSigBit
 * 
 *  Maintenance Notes:
 *   05Jul86  - Created by Jeff Lydiatt, Vancouver, Canada.
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/tasks.h>
#include <exec/io.h>
#include <devices/timer.h>
#include <functions.h>

static struct timerequest TimerIO;
static struct MsgPort    *TimerPort = NULL;
static BOOL timerON;
static BOOL timerExpired;

/*-------------------------------------------------------------*/
/*	OpenTimer: return TRUE if timer opened OK	       */
/*-------------------------------------------------------------*/

BOOL OpenTimer()
{
   register struct timerequest *t = &TimerIO;
   register struct MsgPort *port;

   timerON = FALSE;
   timerExpired = TRUE;
   if ( TimerPort != NULL )
      return TRUE;

   if ( (port = CreatePort("Timer Port", 0L)) == NULL )
      return FALSE;
   else
      TimerPort = port;

   if (OpenDevice(TIMERNAME, UNIT_VBLANK, t, 0L) != 0)
     {
	DeletePort( port );
	TimerPort = NULL;
	return FALSE;
     }

   return TRUE;
}

/*-------------------------------------------------------------*/
/*	CloseTimer: All Done with the timer.		       */
/*-------------------------------------------------------------*/

void CloseTimer()
{
   register struct timerequest *t = &TimerIO;

   if ( timerON )
      AbortIO( t );

   CloseDevice( t );
   DeletePort( TimerPort );
   TimerPort = NULL;
}

/*-------------------------------------------------------------*/
/*	GetTimerSigBit: return Timer signal bit		       */
/*-------------------------------------------------------------*/

int GetTimerSigBit()
{
   return TimerPort->mp_SigBit;
}

/*-------------------------------------------------------------*/
/*	StartTimer: launch the timer.			       */
/*-------------------------------------------------------------*/

void StartTimer(seconds, micros)
ULONG seconds, micros;
{
   register struct timerequest *t = &TimerIO;

   if ( timerON )
     {
	AbortIO( t );
	(void) GetMsg( TimerPort );
	timerON = FALSE;
        timerExpired = TRUE;
     }

   t->tr_time.tv_secs = seconds;
   t->tr_time.tv_micro = micros;
   t->tr_node.io_Command = TR_ADDREQUEST;
   t->tr_node.io_Flags = IOF_QUICK;
   t->tr_node.io_Error = 0;
   t->tr_node.io_Message.mn_ReplyPort = TimerPort;
   SendIO( t );
   timerExpired = FALSE;
   timerON = TRUE;
}

/*-------------------------------------------------------------*/
/*	TimerExpired: returns TRUE if timer expired.	       */
/*-------------------------------------------------------------*/

BOOL TimerExpired()
{
   if ( timerON && ( CheckIO( &TimerIO.tr_node ) == NULL) )
      return FALSE;

   (void)GetMsg( TimerPort );
   timerExpired = TRUE;
   timerON = FALSE;

   return timerExpired;
}

