home *** CD-ROM | disk | FTP | other *** search
/ ftp.whtech.com / ftp.whtech.com.7z / ftp.whtech.com / emulators / v9t9 / linux / sources / V9t9 / source / timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-10-19  |  4.0 KB  |  264 lines

  1.  
  2. /*
  3.     This module handles timer functions.
  4.  
  5. */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9.  
  10. #include "v9t9_common.h"
  11. #include "timer.h"
  12. #include "system.h"
  13.  
  14. #define _L     LOG_TIMER | LOG_INFO
  15.  
  16. static int  timer_installed;
  17.  
  18. /*************************************************************************/
  19.  
  20. static int  ticks;            /* number of ticks that have passed */
  21. static int  lasttag;        /* unique tag for timer events */
  22.  
  23. #define    TM_MAXEVENTS    32
  24.  
  25. #define    NOTAG        0
  26.  
  27. typedef void (*FUNC) (void);
  28.  
  29. struct timerrec {
  30.      u32             tag;            /* user-defined ID, 0 means unused */
  31.      u32             flags;
  32.      s32             max, counter;    /* /100 = # times per second */
  33.      volatile void *flag;            /* function or flag addr */
  34. } TM_Events[TM_MAXEVENTS];
  35.  
  36. static struct timerrec *
  37. TM_FindFreeEvent(void)
  38. {
  39.     struct timerrec *follow = TM_Events;
  40.     int         c = TM_MAXEVENTS;
  41.  
  42.     while (follow->tag != NOTAG && c) {
  43.         follow++;
  44.         c--;
  45.     }
  46.  
  47.     if (!c)
  48.         return NULL;
  49.     else
  50.         return follow;
  51. }
  52.  
  53.  
  54. static void
  55. TM_FreeEvent(struct timerrec *which)
  56. {
  57.     which->tag = NOTAG;
  58. }
  59.  
  60.  
  61. /*-----------------------------------------------------------------------*/
  62.  
  63. /*
  64.     Handle a tick event (called TM_HZ times a second), possibly
  65.     by TM_TickHandler, or by the main program.
  66. */
  67.  
  68. void
  69. TM_TickHandler(int unused)
  70. {
  71.     struct timerrec *nw;
  72.  
  73.     if (log_level(LOG_TIMER) >= 3) {
  74.         logger(_L | L_3, "tick... %d\n", ticks);
  75.         nw = TM_Events;
  76.         while (nw < TM_Events + TM_MAXEVENTS) {
  77.             if (nw->tag)
  78.                 logger(_L | L_3, "[ %d.%d ] -> ", nw->tag, nw->counter);
  79.             nw++;
  80.         }
  81.         logger(_L | L_3, " [=]\n");
  82.     }
  83.  
  84.     ticks++;                    /* update ticks */
  85.  
  86.     nw = TM_Events;
  87.  
  88.     while (nw < TM_Events + TM_MAXEVENTS) {
  89.         if (nw->tag != NOTAG) {
  90.             nw->counter += TM_HZ;    /* >tick< */
  91.             if (nw->counter >= nw->max) {    /* went off? */
  92.                 logger(_L | L_1, "executing event with id=%d\n", nw->tag);
  93.                 if (nw->flags & TM_FUNC)
  94.                     ((FUNC) nw->flag) ();    /* call rout */
  95.                 else
  96.                     *(u8 *) (nw->flag) = 1;    /* whoo hoo! */
  97.  
  98.                 /*  repeat?     */
  99.                 if (nw->flags & TM_REPEAT) {
  100.                     nw->counter -= nw->max;
  101.                 } else {
  102.                     logger(_L | L_1, "freeing event with id=%d\n\n", nw->tag);
  103.                     TM_FreeEvent(nw);
  104.                 }
  105.             }
  106.         }
  107.         nw++;
  108.     }
  109.  
  110. }
  111.  
  112. /*
  113.     Initialize the timer functions.
  114. */
  115.  
  116. int
  117. TM_Init(void)
  118. {
  119.     memset(TM_Events, 0, sizeof(TM_Events));
  120.     ticks = 0;
  121.  
  122.     system_timer_init();
  123.  
  124.     atexit(TM_Kill);
  125.  
  126.     return 1;
  127. }
  128.  
  129. /*    
  130.     Turn on the timer. 
  131. */
  132. int
  133. TM_Start(void)
  134. {
  135.     if (timer_installed)
  136.         return 0;
  137.  
  138.     system_timer_install();
  139.     timer_installed = 1;
  140.     return 1;
  141. }
  142.  
  143.  
  144. /*
  145.     Turn off the timer.
  146. */
  147.  
  148. int
  149. TM_Stop(void)
  150. {
  151.     if (!timer_installed)
  152.         return 0;
  153.  
  154.     system_timer_uninstall();
  155.     timer_installed = 0;
  156.  
  157.     return 1;
  158. }
  159.  
  160.  
  161. void
  162. TM_Kill(void)
  163. {
  164.     TM_Stop();
  165. }
  166.  
  167.  
  168.  
  169. int
  170. TM_GetTicks(void)
  171. {
  172.     return ticks;
  173. }
  174.  
  175. int
  176. TM_UniqueTag(void)
  177. {
  178.     return ++lasttag;
  179. }
  180.  
  181.  
  182. /*
  183.     Insert a event into the event chain.
  184.  
  185.     flags & TM_REPEAT --> automatically reschedule timer event
  186.     flags & TM_FUNC     --> call a function instead of setting a flag
  187. */
  188.  
  189. int
  190. TM_SetEvent(int tag, int ticks, int start, int flags, volatile void *flag)
  191. {
  192.     struct timerrec *nw;
  193.     int         restart;
  194.  
  195.     if (tag == NOTAG)
  196.         return 0;
  197.  
  198.     nw = TM_FindFreeEvent();
  199.     if (nw == NULL) {
  200.         logger(_L | LOG_FATAL, "\nTimer event list full\n");
  201.         return 0;
  202.     }
  203.  
  204.     restart = timer_installed;
  205.     TM_Stop();
  206.  
  207.     nw->flags = flags;
  208.     nw->tag = tag;
  209.     nw->flag = flag;
  210.     nw->max = ticks;
  211.     nw->counter = start;
  212.  
  213.     if (log_level(LOG_TIMER) >= 2) {
  214.         struct timerrec *step;
  215.  
  216.         logger(_L | L_2, "TM_SetEvent:\n");
  217.         step = TM_Events;
  218.         while (step < TM_Events + TM_MAXEVENTS) {
  219.             if (step->tag != NOTAG)
  220.                 logger(_L | L_2 |  0, "[ %d.%d ] -> ", step->tag,
  221.                      step->counter);
  222.             step++;
  223.         }
  224.         logger(_L | L_2, " [=]\n");
  225.     }
  226.  
  227.     if (restart)
  228.         TM_Start();
  229.  
  230.     return 1;
  231. }
  232.  
  233.  
  234.  
  235. int
  236. TM_ResetEvent(int tag)
  237. {
  238.     struct timerrec *step;
  239.     int         restart;
  240.  
  241.     restart = timer_installed;
  242.     TM_Stop();
  243.  
  244.     logger(_L | L_1, "TM_ResetEvent %d\n\n\n", tag);
  245.  
  246.     step = TM_Events;
  247.  
  248.     while (step < TM_Events + TM_MAXEVENTS && step->tag != tag) {
  249.         step++;
  250.     }
  251.  
  252.     if (step >= TM_Events + TM_MAXEVENTS) {
  253.         if (restart)
  254.             TM_Start();
  255.         return 0;
  256.     } else {
  257.         TM_FreeEvent(step);
  258.     }
  259.  
  260.     if (restart)
  261.         TM_Start();
  262.     return 1;
  263. }
  264.