home *** CD-ROM | disk | FTP | other *** search
- /* timer.c */
-
- /* Copyright (c) 1988 David J. Arendash, Inc. */
-
- /* This file contains general purpose routines for the handling of the
- timer device. As the ROM Kernal Manual examples are buggy, I based these
- on those in the Programmer's Guide to the Amiga by Robert A. Peck.
- They use standard IO requests rather than timerrequests. On the other
- hand, they work.
-
- You may want to break this file up to library-ize these routines.
-
- Feel free to do anything you want with this stuff. I only ask that
- 1. Don't delete these comments
- 2. Follow this indentation and punctuation, as it is the least
- annoying and easiest to follow, all pinheads aside.
- */
-
- #include "exec/types.h"
- #include "exec/nodes.h"
- #include "exec/lists.h"
- #include "exec/memory.h"
- #include "exec/interrupts.h"
- #include "exec/ports.h"
- #include "exec/libraries.h"
- #include "exec/tasks.h"
- #include "exec/io.h"
- #include "exec/devices.h"
- #include "devices/timer.h"
- #include <stdio.h> /* used in debugging */
-
- #define SECS io_Actual
- #define MICROS io_Length
-
- APTR TimerBase;
-
- extern struct MsgPort *CreatePort();
- extern struct IOStdReq *CreateStdIO();
-
-
- /* set up the Timer Device (just once) */
- long InitTimerDevice (tr, unit)
- struct IOStdReq *tr;
- long unit;
- {
- long error;
-
- error = OpenDevice (TIMERNAME, unit, tr, 0L);
- if (error)
- return (NULL);
-
- TimerBase = tr->io_Device;
- return (1L);
- }
-
- /* Duplicate a timer. Useful for generating multiple requests */
- DupTimer (orginal, duplicate)
- struct IOStdReq *orginal, *duplicate;
- {
- duplicate->io_Device = orginal->io_Device;
- duplicate->io_Unit = orginal->io_Unit;
- }
-
- /* create a new timer request. does not start the timer */
- struct IOStdReq *CreateTimer ()
- {
- long error;
-
- struct MsgPort *timerport;
- struct IOStdReq *timermsg;
-
- timerport = CreatePort (0L, 0L);
-
- if (timerport == NULL)
- return (NULL);
-
- timermsg = CreateStdIO (timerport);
- return (timermsg);
- }
-
- /* everything needed to do a time delay (like Wait)
- unit is UNIT_MICROHZ or UNIT_VBLANK
- secs is seconds
- micros is microseconds
- */
- TimeDelay (unit, secs, micros)
- long unit, secs, micros;
- {
- long precise;
- struct IOStdReq *tr;
-
- /* choose best unit (?) (from the book) */
- if (secs < 0 || unit == UNIT_MICROHZ)
- unit = UNIT_MICROHZ;
- else
- unit = UNIT_VBLANK;
-
- tr = CreateTimer ();
- if (tr == NULL)
- return (-1);
-
- if (!InitTimerDevice (tr, unit))
- return (-1);
-
- tr->SECS = secs;
- tr->MICROS = micros;
- tr->io_Command = TR_ADDREQUEST;
- /* wait for timer to timeout */
- DoIO (tr);
-
- CloseDevice (tr);
- DeleteTimer (tr);
- return (0);
- }
-
- /* Queue (start) a timer using seconds and microseconds
- tr is the thing returned from CreateTimer() */
- QTimer_sm (tr,secs,micros)
- struct IOStdReq *tr;
- {
- tr->SECS = secs;
- tr->MICROS = micros;
- tr->io_Command = TR_ADDREQUEST;
- SendIO (tr);
- /* returns immediately, use CheckTimer to find out when it's done */
- }
-
- /* Queue (start) a timer using a timeval structure.
- tr is the thing returned from CreateTimer() */
- QTimer_tv (tr,tv)
- struct IOStdReq *tr;
- struct timeval *tv;
- {
- tr->SECS = tv->tv_secs;
- tr->MICROS = tv->tv_micro;
- tr->io_Command = TR_ADDREQUEST;
- SendIO (tr);
- /* returns immediately, use CheckTimer to find out when it's done */
- }
-
- /* Check to see if a timer is done. Returns 1 if done, 0 if not done */
- CheckTimer (tr)
- struct IOStdReq *tr;
- {
- long result;
-
- /* see if timed out; if so, reply to it */
- result = (int) CheckIO (tr);
- if (result)
- GetMsg (tr->io_Message.mn_ReplyPort);
- return (result);
- }
-
- /* stop a timer whether it is done or not
- best do this to all timers before CloseDevice() */
- AbortTimer (tr)
- struct IOStdReq *tr;
- {
- AbortIO (tr);
- }
-
- /* set new system time in seconds since 12:00 AM, 1/1/78 */
- SetNewTime (secs)
- LONG secs;
- {
- struct IOStdReq *tr;
-
- tr = CreateTimer (UNIT_MICROHZ);
- if (tr == 0)
- return (-1);
-
- tr->io_Command = TR_SETSYSTIME;
- tr->SECS = secs;
- tr->MICROS = 0;
- DoIO (tr);
-
- CloseDevice (tr);
- DeleteTimer (tr);
- return (0);
- }
-
- /* fill a timeval structure with system time in seconds and microseconds
- since 12:00 AM, 1/1/78 */
- GetSysTime (tv)
- struct timeval *tv;
- {
- struct IOStdReq *tr;
-
- tr = CreateTimer (UNIT_MICROHZ);
- if (tr == 0)
- return (-1);
-
- tr->io_Command = TR_GETSYSTIME;
- DoIO (tr);
-
- CloseDevice (tr);
- DeleteTimer (tr);
- return (0);
- }
-
- /* remove a timer from existance */
- DeleteTimer (tr)
- struct IOStdReq *tr;
- {
- struct MsgPort *tp;
-
- if (tr)
- {
- tp = tr->mn_ReplyPort;
- if (tp)
- DeletePort (tp);
- DeleteStdIO (tr);
- }
- }
-