home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9302 / ctrick / alarm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-04  |  5.6 KB  |  207 lines

  1. /* ****************************************************** */
  2. /*                        ALARM.C                         */
  3. /*               (c) 1993 Holger Suhr & DMV               */
  4. /* ****************************************************** */
  5. #include <stdio.h>
  6. #include "tmrprot.h"
  7. #include "alaprot.h"
  8. #include "globals.h"
  9.  
  10. #define MAXALARM    10
  11.  
  12. static int acnt = 0;
  13. static int amod[MAXALARM];
  14. static unsigned atics[MAXALARM];
  15. static unsigned otics[MAXALARM];
  16. static void (*funcvec[MAXALARM])(int id,unsigned tics);
  17. static int aloff = 0;
  18. static int alarminstalled = 0;
  19.  
  20. static inst_alarm(void);
  21. static void alarm_isr(unsigned );
  22.  
  23. /* ****************************************************** */
  24. /*  Installieren eines Alarms                             */
  25. /*  Der Funktionspointer wird nach Ablauf von tics        */
  26. /*  Timer-Ticks zu original Timer-Geschwindigkeit         */
  27. /*  ASYNCHRON aufgerufen. Nach Aufruf des Pointers wird   */
  28. /*  der Alarm automatisch inaktiv.                        */
  29. /* ****************************************************** */
  30.  
  31. alarm(void (*func)(int id,unsigned tics),unsigned tics)
  32. {
  33.   int i;
  34.  
  35.   /* Zunächst die Alarmverwaltung ausschalten */
  36.  
  37.   aloff++;
  38.  
  39.   /*  installieren, wenn noch nicht geschehen */
  40.  
  41.   if (!alarminstalled && inst_alarm()) {
  42.   retm1:;
  43.     aloff--;
  44.     return(-1);
  45.   }
  46.  
  47.   /*  freien alarm-slot finden                */
  48.  
  49.   for (i = 0; i < MAXALARM && atics[i]; i++);
  50.  
  51.   /*  alle slots belegt ?                     */
  52.  
  53.   if (i >= MAXALARM) goto retm1;
  54.  
  55.   funcvec[i] = func;
  56.   amod[i]    = 0;
  57.   otics[i]   = atics[i] = tics;
  58.   acnt++;
  59.  
  60.   /*  und alarm-verwaltung wieder einschalten */
  61.  
  62.   aloff--;
  63.  
  64.   /*  eindeutige alarm-id zurueckliefern      */
  65.  
  66.   return(i);
  67. }
  68.  
  69. /* ****************************************************** */
  70. /*  wie alarm, jedoch wird der alarm nicht deaktiviert,   */
  71. /*  sondern immer wieder nach ablauf von tics timer-ticks */
  72. /*  aufgerufen bis ein offalarm() aufruf erfolgt.         */
  73. /* ****************************************************** */
  74.  
  75. perm_alarm(void (*func)(int id,unsigned tics),unsigned tics)
  76. {
  77.   int i;
  78.  
  79.   aloff = 1;
  80.   if((i = alarm(func,tics))>=0) amod[i]=1;
  81.   aloff = 0;
  82.  
  83.   return(i);
  84. }
  85.  
  86. /* ****************************************************** */
  87. /*  Installieren der Alarm-Verwaltung                     */
  88. /* ****************************************************** */
  89.  
  90. static inst_alarm(void)
  91. {
  92.   int i;
  93.  
  94.   /*  installieren falls noch nicht geschehen    */
  95.  
  96.   if (!timerinstalled && tmr_init(0)) return(-1);
  97.  
  98.   if (!alarminstalled) {
  99.     /* wir geben uns der timerverwaltung als immer
  100.        aufzurufende funktion bekannt.
  101.        slot 0
  102.        art 1 = aufruf zu
  103.                original-geschwindigkeit (18.2/sek)   */
  104.  
  105.     tmr_intfunc(alarm_isr,0,1);
  106.   }
  107.  
  108.   acnt = 0;
  109.   for (i = 0; i < MAXALARM; i++) {
  110.      otics[i]   = atics[i] = 0;
  111.      funcvec[i] = NULL;
  112.   }
  113.  
  114.   alarminstalled = 1;
  115.  
  116.   return(0);
  117. }
  118.  
  119. /* ****************************************************** */
  120. /*  Deaktivieren des Alarm mit der id "id"                */
  121. /* ****************************************************** */
  122.  
  123. off_alarm(int id)
  124. {
  125.   aloff = 1;
  126.  
  127.   if (id < 0 || id >= MAXALARM || !otics[id])
  128.     return((aloff = 0) - 1);
  129.  
  130.   otics[id]   = atics[id] = 0;
  131.   funcvec[id] = NULL;
  132.   acnt--;
  133.  
  134.   return(aloff = 0);
  135. }
  136.  
  137. /* ****************************************************** */
  138. /*  Semi-Interrupt-Funktion wird 18.2 mal pro Sekunde     */
  139. /*  aufgerufen muss keine Interrupt-Funktion sein, da sie */
  140. /*  von der Timer-Verwaltung aufgerufen wird.             */
  141. /*                                                        */
  142. /*  (kann jedoch auch leicht direkt als Interruptfunktion */
  143. /*  ohne Timerverwaltung installiert werden)              */
  144. /* ****************************************************** */
  145.  
  146. static void alarm_isr(unsigned tics)
  147. {
  148.   register int j = acnt,i;
  149.  
  150.   /* ok, bereit zur Alarmverwaltung ? */
  151.  
  152.   if (!aloff)
  153.     for (i = 0; j && i < MAXALARM; i++) {
  154.  
  155.       /*  aktiver alarm-slot ?                    */
  156.       if (atics[i]) {
  157.  
  158.         /*  damit wir nicht laenger suchen als noetig */
  159.         j--;
  160.  
  161.         /*  dekrement und test, ob abgelaufen         */
  162.         if (!--atics[i]) {
  163.  
  164.           /*  Aufruf des Funktionspointers zum Alarm  */
  165.           (*funcvec[i])(i,tics);
  166.  
  167.           /*  wenn permanenter alarm, dann den
  168.               alarm-counter sofort wieder setzen      */
  169.  
  170.           if(amod[i]) atics[i]=otics[i];
  171.         }
  172.       }
  173.     }
  174. }
  175.  
  176. #pragma warn -par
  177.  
  178. /* ****************************************************** */
  179. /*  simple timeout-verwaltung                             */
  180. /*                                                        */
  181. /* TimeoutOn() setzt die globale variable timeout auf 0   */
  182. /* und installiert einen entsprechenden alarm.            */
  183. /* nach ablauf der zeit wird Timeoutfunc aufgerufen,      */
  184. /* wodurch timeout auf 1 gesetzt wird.                    */
  185. /*                                                        */
  186. /* ein anwendungsprogramm braucht also lediglich vor      */
  187. /* einer zeitabhaengigen phase TimeoutOn() aufzurufen und */
  188. /* anschliessend zyklisch die globale variable timeout zu */
  189. /* testen, um den ablauf eines gewuenschten timeouts      */
  190. /* festzustellen.                                         */
  191. /* ****************************************************** */
  192.  
  193. static void Timeoutfunc(int id,unsigned tics)
  194. {
  195.   timeout=1;
  196. }
  197.  
  198. TimeoutOn(int tics)
  199. {
  200.   timeout = 0;
  201.  
  202.   return(alarm(Timeoutfunc,tics));
  203. }
  204. /* ****************************************************** */
  205. /*                   Ende von ALARM.C                     */
  206.  
  207.