home *** CD-ROM | disk | FTP | other *** search
- /* ****************************************************** */
- /* ALARM.C */
- /* (c) 1993 Holger Suhr & DMV */
- /* ****************************************************** */
- #include <stdio.h>
- #include "tmrprot.h"
- #include "alaprot.h"
- #include "globals.h"
-
- #define MAXALARM 10
-
- static int acnt = 0;
- static int amod[MAXALARM];
- static unsigned atics[MAXALARM];
- static unsigned otics[MAXALARM];
- static void (*funcvec[MAXALARM])(int id,unsigned tics);
- static int aloff = 0;
- static int alarminstalled = 0;
-
- static inst_alarm(void);
- static void alarm_isr(unsigned );
-
- /* ****************************************************** */
- /* Installieren eines Alarms */
- /* Der Funktionspointer wird nach Ablauf von tics */
- /* Timer-Ticks zu original Timer-Geschwindigkeit */
- /* ASYNCHRON aufgerufen. Nach Aufruf des Pointers wird */
- /* der Alarm automatisch inaktiv. */
- /* ****************************************************** */
-
- alarm(void (*func)(int id,unsigned tics),unsigned tics)
- {
- int i;
-
- /* Zunächst die Alarmverwaltung ausschalten */
-
- aloff++;
-
- /* installieren, wenn noch nicht geschehen */
-
- if (!alarminstalled && inst_alarm()) {
- retm1:;
- aloff--;
- return(-1);
- }
-
- /* freien alarm-slot finden */
-
- for (i = 0; i < MAXALARM && atics[i]; i++);
-
- /* alle slots belegt ? */
-
- if (i >= MAXALARM) goto retm1;
-
- funcvec[i] = func;
- amod[i] = 0;
- otics[i] = atics[i] = tics;
- acnt++;
-
- /* und alarm-verwaltung wieder einschalten */
-
- aloff--;
-
- /* eindeutige alarm-id zurueckliefern */
-
- return(i);
- }
-
- /* ****************************************************** */
- /* wie alarm, jedoch wird der alarm nicht deaktiviert, */
- /* sondern immer wieder nach ablauf von tics timer-ticks */
- /* aufgerufen bis ein offalarm() aufruf erfolgt. */
- /* ****************************************************** */
-
- perm_alarm(void (*func)(int id,unsigned tics),unsigned tics)
- {
- int i;
-
- aloff = 1;
- if((i = alarm(func,tics))>=0) amod[i]=1;
- aloff = 0;
-
- return(i);
- }
-
- /* ****************************************************** */
- /* Installieren der Alarm-Verwaltung */
- /* ****************************************************** */
-
- static inst_alarm(void)
- {
- int i;
-
- /* installieren falls noch nicht geschehen */
-
- if (!timerinstalled && tmr_init(0)) return(-1);
-
- if (!alarminstalled) {
- /* wir geben uns der timerverwaltung als immer
- aufzurufende funktion bekannt.
- slot 0
- art 1 = aufruf zu
- original-geschwindigkeit (18.2/sek) */
-
- tmr_intfunc(alarm_isr,0,1);
- }
-
- acnt = 0;
- for (i = 0; i < MAXALARM; i++) {
- otics[i] = atics[i] = 0;
- funcvec[i] = NULL;
- }
-
- alarminstalled = 1;
-
- return(0);
- }
-
- /* ****************************************************** */
- /* Deaktivieren des Alarm mit der id "id" */
- /* ****************************************************** */
-
- off_alarm(int id)
- {
- aloff = 1;
-
- if (id < 0 || id >= MAXALARM || !otics[id])
- return((aloff = 0) - 1);
-
- otics[id] = atics[id] = 0;
- funcvec[id] = NULL;
- acnt--;
-
- return(aloff = 0);
- }
-
- /* ****************************************************** */
- /* Semi-Interrupt-Funktion wird 18.2 mal pro Sekunde */
- /* aufgerufen muss keine Interrupt-Funktion sein, da sie */
- /* von der Timer-Verwaltung aufgerufen wird. */
- /* */
- /* (kann jedoch auch leicht direkt als Interruptfunktion */
- /* ohne Timerverwaltung installiert werden) */
- /* ****************************************************** */
-
- static void alarm_isr(unsigned tics)
- {
- register int j = acnt,i;
-
- /* ok, bereit zur Alarmverwaltung ? */
-
- if (!aloff)
- for (i = 0; j && i < MAXALARM; i++) {
-
- /* aktiver alarm-slot ? */
- if (atics[i]) {
-
- /* damit wir nicht laenger suchen als noetig */
- j--;
-
- /* dekrement und test, ob abgelaufen */
- if (!--atics[i]) {
-
- /* Aufruf des Funktionspointers zum Alarm */
- (*funcvec[i])(i,tics);
-
- /* wenn permanenter alarm, dann den
- alarm-counter sofort wieder setzen */
-
- if(amod[i]) atics[i]=otics[i];
- }
- }
- }
- }
-
- #pragma warn -par
-
- /* ****************************************************** */
- /* simple timeout-verwaltung */
- /* */
- /* TimeoutOn() setzt die globale variable timeout auf 0 */
- /* und installiert einen entsprechenden alarm. */
- /* nach ablauf der zeit wird Timeoutfunc aufgerufen, */
- /* wodurch timeout auf 1 gesetzt wird. */
- /* */
- /* ein anwendungsprogramm braucht also lediglich vor */
- /* einer zeitabhaengigen phase TimeoutOn() aufzurufen und */
- /* anschliessend zyklisch die globale variable timeout zu */
- /* testen, um den ablauf eines gewuenschten timeouts */
- /* festzustellen. */
- /* ****************************************************** */
-
- static void Timeoutfunc(int id,unsigned tics)
- {
- timeout=1;
- }
-
- TimeoutOn(int tics)
- {
- timeout = 0;
-
- return(alarm(Timeoutfunc,tics));
- }
- /* ****************************************************** */
- /* Ende von ALARM.C */
-
-