home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / animutil / cycle / timer.c < prev   
Encoding:
C/C++ Source or Header  |  1988-09-24  |  4.6 KB  |  215 lines

  1. /* timer.c */
  2.  
  3. /* Copyright (c) 1988 David J. Arendash, Inc. */
  4.  
  5. /* This file contains general purpose routines for the handling of the
  6.    timer device.  As the ROM Kernal Manual examples are buggy, I based these
  7.    on those in the Programmer's Guide to the Amiga by Robert A. Peck.
  8.    They use standard IO requests rather than timerrequests.  On the other
  9.    hand, they work.
  10.  
  11.    You may want to break this file up to library-ize these routines.
  12.  
  13.    Feel free to do anything you want with this stuff.  I only ask that
  14.     1.  Don't delete these comments
  15.     2.  Follow this indentation and punctuation, as it is the least
  16.         annoying and easiest to follow, all pinheads aside.
  17. */
  18.  
  19. #include "exec/types.h"
  20. #include "exec/nodes.h"
  21. #include "exec/lists.h"
  22. #include "exec/memory.h"
  23. #include "exec/interrupts.h"
  24. #include "exec/ports.h"
  25. #include "exec/libraries.h"
  26. #include "exec/tasks.h"
  27. #include "exec/io.h"
  28. #include "exec/devices.h"
  29. #include "devices/timer.h"
  30. #include <stdio.h>    /* used in debugging */
  31.  
  32. #define SECS io_Actual
  33. #define MICROS io_Length
  34.  
  35. APTR TimerBase;
  36.  
  37. extern struct MsgPort  *CreatePort();
  38. extern struct IOStdReq *CreateStdIO();
  39.  
  40.  
  41. /* set up the Timer Device (just once) */
  42. long InitTimerDevice (tr, unit)
  43. struct IOStdReq *tr;
  44. long            unit;
  45. {
  46.    long error;
  47.  
  48.    error = OpenDevice (TIMERNAME, unit, tr, 0L);
  49.    if (error)
  50.       return (NULL);
  51.  
  52.    TimerBase = tr->io_Device;
  53.    return (1L);
  54. }
  55.  
  56. /* Duplicate a timer.  Useful for generating multiple requests */
  57. DupTimer (orginal, duplicate)
  58. struct IOStdReq *orginal, *duplicate;
  59. {
  60.    duplicate->io_Device = orginal->io_Device;
  61.    duplicate->io_Unit = orginal->io_Unit;
  62. }
  63.  
  64. /* create a new timer request. does not start the timer */
  65. struct IOStdReq *CreateTimer ()
  66. {
  67.    long error;
  68.  
  69.    struct MsgPort *timerport;
  70.    struct IOStdReq *timermsg;
  71.  
  72.    timerport = CreatePort (0L, 0L);
  73.  
  74.    if (timerport == NULL)
  75.       return (NULL);
  76.  
  77.    timermsg = CreateStdIO (timerport);
  78.    return (timermsg);
  79. }
  80.  
  81. /* everything needed to do a time delay (like Wait)
  82.    unit is UNIT_MICROHZ or UNIT_VBLANK
  83.    secs is seconds
  84.    micros is microseconds
  85. */
  86. TimeDelay (unit, secs, micros)
  87. long unit, secs, micros;
  88. {
  89.    long precise;
  90.    struct IOStdReq *tr;
  91.  
  92.    /* choose best unit (?)  (from the book) */
  93.    if (secs < 0 || unit == UNIT_MICROHZ)
  94.       unit = UNIT_MICROHZ;
  95.    else
  96.       unit = UNIT_VBLANK;
  97.  
  98.    tr = CreateTimer ();
  99.    if (tr == NULL)
  100.       return (-1);
  101.  
  102.    if (!InitTimerDevice (tr, unit))
  103.       return (-1);
  104.  
  105.    tr->SECS = secs;
  106.    tr->MICROS = micros;
  107.    tr->io_Command = TR_ADDREQUEST;
  108.    /* wait for timer to timeout */
  109.    DoIO (tr);
  110.  
  111.    CloseDevice (tr);
  112.    DeleteTimer (tr);
  113.    return (0);
  114. }
  115.  
  116. /* Queue (start) a timer using seconds and microseconds
  117.    tr is the thing returned from CreateTimer() */
  118. QTimer_sm (tr,secs,micros)
  119. struct IOStdReq *tr;
  120. {
  121.    tr->SECS = secs;
  122.    tr->MICROS = micros;
  123.    tr->io_Command = TR_ADDREQUEST;
  124.    SendIO (tr);
  125.    /* returns immediately, use CheckTimer to find out when it's done */
  126. }
  127.  
  128. /* Queue (start) a timer using a timeval structure.
  129.    tr is the thing returned from CreateTimer() */
  130. QTimer_tv (tr,tv)
  131. struct IOStdReq *tr;
  132. struct timeval *tv;
  133. {
  134.    tr->SECS = tv->tv_secs;
  135.    tr->MICROS = tv->tv_micro;
  136.    tr->io_Command = TR_ADDREQUEST;
  137.    SendIO (tr);
  138.    /* returns immediately, use CheckTimer to find out when it's done */
  139. }
  140.  
  141. /* Check to see if a timer is done. Returns 1 if done, 0 if not done */
  142. CheckTimer (tr)
  143. struct IOStdReq *tr;
  144. {
  145.    long result;
  146.  
  147.    /* see if timed out; if so, reply to it */
  148.    result = (int) CheckIO (tr);
  149.    if (result)
  150.       GetMsg (tr->io_Message.mn_ReplyPort);
  151.    return (result);
  152. }
  153.  
  154. /* stop a timer whether it is done or not
  155.    best do this to all timers before CloseDevice() */
  156. AbortTimer (tr)
  157. struct IOStdReq *tr;
  158. {
  159.    AbortIO (tr);
  160. }
  161.  
  162. /* set new system time in seconds since 12:00 AM, 1/1/78 */
  163. SetNewTime (secs)
  164. LONG secs;
  165. {
  166.    struct IOStdReq *tr;
  167.  
  168.    tr = CreateTimer (UNIT_MICROHZ);
  169.    if (tr == 0)
  170.       return (-1);
  171.  
  172.    tr->io_Command = TR_SETSYSTIME;
  173.    tr->SECS = secs;
  174.    tr->MICROS = 0;
  175.    DoIO (tr);
  176.  
  177.    CloseDevice (tr);
  178.    DeleteTimer (tr);
  179.    return (0);
  180. }
  181.  
  182. /* fill a timeval structure with system time in seconds and microseconds
  183.    since 12:00 AM, 1/1/78 */ 
  184. GetSysTime (tv)
  185. struct timeval *tv;
  186. {
  187.    struct IOStdReq *tr;
  188.  
  189.    tr = CreateTimer (UNIT_MICROHZ);
  190.    if (tr == 0)
  191.       return (-1);
  192.  
  193.    tr->io_Command = TR_GETSYSTIME;
  194.    DoIO (tr);
  195.  
  196.    CloseDevice (tr);
  197.    DeleteTimer (tr);
  198.    return (0);
  199. }
  200.  
  201. /* remove a timer from existance */
  202. DeleteTimer (tr)
  203. struct IOStdReq *tr;
  204. {
  205.    struct MsgPort *tp;
  206.  
  207.    if (tr)
  208.    {
  209.       tp = tr->mn_ReplyPort;
  210.       if (tp)
  211.          DeletePort (tp);
  212.       DeleteStdIO (tr);
  213.    }
  214. }
  215.