[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

/* Simple_Timer.c
 *
 * A simple example of using the timer device.
 *
 * Compile with SAS C 5.10: LC -b1 -cfistq -v -y -L
 *
 * Run from CLI only
 */

#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/timer.h>

#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>

#include <stdio.h>

#ifdef LATTICE
int CXBRK(void) { return(0); }     /* Disable SAS CTRL/C handling */
int chkabort(void) { return(0); }  /* really */
#endif

/* Our timer sub-routines */
void delete_timer  (struct timerequest *);
LONG get_sys_time  (struct timeval *);
LONG set_new_time  (LONG);
void wait_for_timer(struct timerequest *, struct timeval *);
LONG time_delay    ( struct timeval *, LONG );
struct timerequest *create_timer( ULONG );
void show_time     (ULONG);

struct Library *TimerBase;      /* to get at the time comparison functions */

/* manifest constants -- "will never change" */
#define   SECSPERMIN   (60)
#define   SECSPERHOUR  (60*60)
#define   SECSPERDAY   (60*60*24)

void main(int argc,char **argv)
{
LONG seconds;
struct timerequest *tr;      /* IO block for timer commands */
struct timeval oldtimeval;   /* timevals to store times     */
struct timeval mytimeval;
struct timeval currentval;

printf("\nTimer test\n");

/* sleep for two seconds */
currentval.tv_secs = 2;
currentval.tv_micro = 0;
time_delay( &currentval, UNIT_VBLANK );
printf( "After 2 seconds delay\n" );

/* sleep for four seconds */
currentval.tv_secs = 4;
currentval.tv_micro = 0;
time_delay( &currentval, UNIT_VBLANK );
printf( "After 4 seconds delay\n" );

/* sleep for 500,000 micro-seconds = 1/2 second */
currentval.tv_secs = 0;
currentval.tv_micro = 500000;
time_delay( &currentval, UNIT_MICROHZ );
printf( "After 1/2 second delay\n" );

printf( "DOS Date command shows: " );
(void) Execute( "date", 0, 0 );

/* save what system thinks is the time....we'll advance it temporarily */
get_sys_time( &oldtimeval );
printf("Original system time is:\n");
show_time(oldtimeval.tv_secs );

printf("Setting a new system time\n");

seconds = 1000 * SECSPERDAY + oldtimeval.tv_secs;

set_new_time( seconds );

/* (if user executes the AmigaDOS DATE command now, he will*/
/* see that the time has advanced something over 1000 days */
printf( "DOS Date command now shows: " );
(void) Execute( "date", 0, 0 );

get_sys_time( &mytimeval );
printf( "Current system time is:\n");
show_time(mytimeval.tv_secs);

/* Added the microseconds part to show that time keeps */
/* increasing even though you ask many times in a row  */
printf("Now do three TR_GETSYSTIMEs in a row (notice how the microseconds increase)\n\n");
get_sys_time( &mytimeval );
printf("First TR_GETSYSTIME \t%ld.%ld\n",mytimeval.tv_secs, mytimeval.tv_micro);
get_sys_time( &mytimeval );
printf("Second TR_GETSYSTIME \t%ld.%ld\n",mytimeval.tv_secs, mytimeval.tv_micro);
get_sys_time( &mytimeval );
printf("Third TR_GETSYSTIME \t%ld.%ld\n",mytimeval.tv_secs, mytimeval.tv_micro);

printf( "\nResetting to former time\n" );
set_new_time( oldtimeval.tv_secs );

get_sys_time( &mytimeval );
printf( "Current system time is:\n");
show_time(mytimeval.tv_secs);

/* just shows how to set up for using the timer functions, does not */
/* demonstrate the functions themselves.  (TimerBase must have a    */
/* legal value before AddTime, SubTime or CmpTime are performed.    */
tr = create_timer( UNIT_MICROHZ );
TimerBase = (struct Library *)tr->tr_node.io_Device;

/* and how to clean up afterwards */
TimerBase = (struct Library *)(-1);
delete_timer( tr );
}


struct timerequest *create_timer( ULONG unit )
{
/* return a pointer to a timer request.  If any problem, return NULL */
LONG error;
struct MsgPort *timerport;
struct timerequest *TimerIO;

timerport = CreatePort( 0, 0 );
if (timerport == NULL )
    return( NULL );

TimerIO = (struct timerequest *)
    CreateExtIO( timerport, sizeof( struct timerequest ) );
if (TimerIO == NULL )
    {
    DeletePort(timerport);   /* Delete message port */
    return( NULL );
    }

error = OpenDevice( TIMERNAME, unit,(struct IORequest *) TimerIO, 0L );
if (error != 0 )
    {
    delete_timer( TimerIO );
    return( NULL );
    }
return( TimerIO );
}


/* more precise timer than AmigaDOS Delay() */
LONG time_delay( struct timeval *tv, LONG unit )
{
struct timerequest *tr;
/* get a pointer to an initialized timer request block */
tr = create_timer( unit );

/* any nonzero return says timedelay routine didn't work. */
if (tr == NULL )
    return( -1L );

wait_for_timer( tr, tv );

/* deallocate temporary structures */
delete_timer( tr );
return( 0L );
}


void wait_for_timer(struct timerequest *tr, struct timeval *tv )
{

tr->tr_node.io_Command = TR_ADDREQUEST; /* add a new timer request */

/* structure assignment */
tr->tr_time = *tv;

/* post request to the timer -- will go to sleep till done */
DoIO((struct IORequest *) tr );
}


LONG set_new_time(LONG secs)
{
struct timerequest *tr;
tr = create_timer( UNIT_MICROHZ );

/* non zero return says error */
if (tr == 0 )
    return( -1 );

tr->tr_time.tv_secs = secs;
tr->tr_time.tv_micro = 0;
tr->tr_node.io_Command = TR_SETSYSTIME;
DoIO((struct IORequest *) tr );

delete_timer(tr);
return(0);
}


LONG get_sys_time(struct timeval *tv)
{
struct timerequest *tr;
tr = create_timer( UNIT_MICROHZ );

/* non zero return says error */
if (tr == 0 )
    return( -1 );

tr->tr_node.io_Command = TR_GETSYSTIME;
DoIO((struct IORequest *) tr );

/* structure assignment */
*tv = tr->tr_time;

delete_timer( tr );
return( 0 );
}


void delete_timer(struct timerequest *tr )
{
struct MsgPort *tp;

if (tr != 0 )
    {
    tp = tr->tr_node.io_Message.mn_ReplyPort;

    if (tp != 0)
        DeletePort(tp);

    CloseDevice( (struct IORequest *) tr );
    DeleteExtIO( (struct IORequest *) tr );
    }
}


void show_time(ULONG secs)
{
ULONG days,hrs,mins;

/* Compute days, hours, etc. */
mins=secs/60;
hrs=mins/60;
days=hrs/24;
secs=secs%60;
mins=mins%60;
hrs=hrs%24;

/* Display the time */
printf("*   Hour Minute Second  (Days since Jan.1,1978)\n");
printf("*%5ld:%5ld:%5ld      (%6ld )\n\n",hrs,mins,secs,days);
}      /* end of main */