/* Timer device support routines. * Filename: Timer.c * Author: Mark R. Rinfret * Date: 11/29/87 * */ #include ":src/lib/Timer.h" #include /* Allocate and prepare a timer request structure. * Called with: * vBlank: 1 => vertical blanking timer, microhertz timer otherwise * Returns: * pointer to timer request or NULL (failed) */ struct timerequest * CreateTimer(vBlank) BOOL vBlank; { int status = 0; struct MsgPort *timerPort = NULL; struct timerequest *timeRequest = NULL; ULONG timerType; timerType = (vBlank ? UNIT_VBLANK : UNIT_MICROHZ); if ( timerPort = CreatePort(0L, 0L) ) { if ( ! (timeRequest = (struct timerequest *) AllocMem((long) sizeof(struct timerequest), MEMF_CLEAR | MEMF_PUBLIC) ) ) { killport: DeletePort(timerPort); } else { timeRequest->tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE; timeRequest->tr_node.io_Message.mn_Node.ln_Pri = 0; timeRequest->tr_node.io_Message.mn_ReplyPort = timerPort; if (OpenDevice(TIMERNAME, timerType, timeRequest, 1L) ) { DeleteTimer(timeRequest); timeRequest = NULL; goto killport; } } } return timeRequest; } /* Delete a timer request created by CreateTimer(). * Called with: * timeRequest: pointer to timer request structure */ void DeleteTimer(timeRequest) struct timerequest *timeRequest; { struct MsgPort *msgPort; msgPort = timeRequest->tr_node.io_Message.mn_ReplyPort; if (timeRequest->tr_node.io_Device) { AbortIO(timeRequest); GetMsg(msgPort); CloseDevice(timeRequest); } FreeMem(timeRequest, (long) sizeof(timeRequest)); DeletePort(msgPort); } /* Start an asynchronous timer request. The user application detects * the expiration of the timer with Wait(timeRequest->ReplyPort->mp_SigBit) * or WaitIO(timeRequest). * Called with: * timeRequest: pointer to timer I/O request block * seconds: number of seconds in time interval * microSeconds: number of uSecs in time interval * * Caution: seconds, microSeconds are ULONG parameters! */ void StartTimer(timeRequest, seconds, microSeconds) struct timerequest *timeRequest; ULONG seconds, microSeconds; { timeRequest->tr_time.tv_secs = seconds; timeRequest->tr_time.tv_micro = microSeconds; timeRequest->tr_node.io_Command = TR_ADDREQUEST; timeRequest->tr_node.io_Flags = 0; timeRequest->tr_node.io_Error = 0; SendIO(timeRequest); /* start the timer */ } /* Stop an asynchronous timer request. * Called with: * timeRequest: pointer to timer I/O request block */ void StopTimer(timeRequest) struct timerequest *timeRequest; { AbortIO(timeRequest); WaitIO(timeRequest); } #ifdef DEBUG #define SHORTBIT (1L<tr_node.io_Message.mn_ReplyPort->mp_SigBit) #define LONGBIT (1L<tr_node.io_Message.mn_ReplyPort->mp_SigBit) main() { unsigned intervals; struct timerequest *shortTimer, *longTimer; ULONG signals; /* This simple program example sets up two timers of different * intervals and reports their expirations. */ puts("This example defines two timers. The first has an interval of"); puts("five seconds, while the second has an interval of 10 seconds."); puts("The expiration of each timer is reported to the screen until"); puts("10 intervals have been detected.\n"); if (! (shortTimer = CreateTimer(0) ) ) { puts("Failed to create short interval timer!"); exit(); } if (! (longTimer = CreateTimer(0) ) ) { puts("Failed to create long interval timer!"); DeleteTimer(shortTimer); exit(); } StartTimer(shortTimer, 5L, 0L); StartTimer(longTimer, 10L, 0L); for (intervals = 0; intervals < 10; ) { printf("Begin wait %2d ... ", intervals); signals = Wait(SHORTBIT | LONGBIT); puts("end wait."); if (signals & SHORTBIT) { GetMsg(shortTimer->tr_node.io_Message.mn_ReplyPort); ++intervals; puts(" Short interval timer expired."); StartTimer(shortTimer, 5L, 0L); } if (signals & LONGBIT) { GetMsg(longTimer->tr_node.io_Message.mn_ReplyPort); ++intervals; puts(" Long interval timer expired."); StartTimer(longTimer, 10L, 0L); } } DeleteTimer(shortTimer); DeleteTimer(longTimer); puts("\nEnd of timer demo.\n"); } #endif