home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 316 / libsrc / alarm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  3.0 KB  |  123 lines

  1. /*
  2.  *        Cross Development System for Atari ST 
  3.  *     Copyright (c) 1988, Memorial University of Newfoundland
  4.  *
  5.  *   This routine uses the verticla blank interupt queue to get it's timing
  6.  * done.  This means that it probably depends on the resolution of the screen.
  7.  * This was written on a machine with a b&w monitor so a 70Hz clock is
  8.  * assumed - what needs to be added is some code that looks to see what
  9.  * the resolution is, and sets the alarm time accordingly.
  10.  *   If there is no room in the vbl queue then -1 is returned.  Note that
  11.  * before the program terminates, this routine must be taken out of the
  12.  * queue - to do this, _unalarm() is called from exit().  If alarm() is
  13.  * not used in the program, the _unalarm() routine is a null one.
  14.  *   This routine works by messing with the return pc (and sr) on the stack
  15.  * when it gets called from the vbl interupt routine.  Also, the routine
  16.  * checks to make sure a trap is not in progress by checking the __in_trap
  17.  * variable (which *must* be set to one before a trap is done, and cleared
  18.  * afer by the programmer - this is normally handled by the __*bios routines).
  19.  * All this weirdness is done to ensure that the os is not disturbed while
  20.  * it is doing stuff - therefor it is safe to do a longjmp() inside a signal
  21.  * handling routine.
  22.  *
  23.  * $Header: alarm.c,v 1.1 88/02/03 22:37:51 m68k Exp $
  24.  *
  25.  * $Log:    alarm.c,v $
  26.  * Revision 1.1  88/02/03  22:37:51  m68k
  27.  * Initial revision
  28.  * 
  29.  */
  30. /*
  31. #include    <xbios.h>
  32. #include    <gembios.h>
  33. */
  34. #include    <osbind.h>
  35. #include    <sysvars.h>
  36.  
  37. #define    HZ        (70)        /* how often we get called a second */
  38. #define    CLK_VEC        0x100        /* the clock vector */
  39.  
  40. extern char    _in_trap;
  41.  
  42. static int    alrm_in_vblq = 0;
  43. static int    alrm_timer();
  44. static int    set_timer();
  45.  
  46. static long    alrmtime = 0;
  47.  
  48. int
  49. alarm(n)
  50.     int    n;
  51. {
  52.     long        oldticks;
  53.     int        (*func)();
  54.  
  55.     oldticks = alrmtime ? (alrmtime + HZ - 1) / HZ : 0;
  56.     alrmtime = 0;
  57.  
  58.     if (n) {
  59.         alrmtime = n * HZ;
  60.         if (!alrm_in_vblq)
  61.             if ((short) Supexec(set_timer))
  62.                 return -1;
  63.     }
  64.     return oldticks;
  65. }
  66.  
  67. void
  68. _unalarm()
  69. {
  70.     if (alrm_in_vblq) {
  71.         alrmtime = 0;
  72.         /* don't call us any more */
  73.         (void) Supexec(set_timer);
  74.     }
  75. }
  76.  
  77. /*
  78.  * This routine should be as small as possible as it is called lots of times
  79.  * (There isn't really an argument - it's just there so we can get the
  80.  * address of the stack)
  81.  */
  82. int
  83. alrm_timer(arg)
  84.     int    arg;
  85. {
  86.     if (alrmtime && !--alrmtime)    /* rrriiinnnngggggggg! */
  87.         if (_in_trap)        /* If we are in a trap, do nothing */
  88.             alrmtime++;
  89.         else {
  90.             (void) set_timer();
  91.             _alrm_nasty(&arg);
  92.         }
  93.     return 0;
  94. }
  95.  
  96. /* This routine must be called in super mode */
  97. static    int
  98. set_timer()
  99. {
  100.     char    **func;
  101.     int    i;
  102.  
  103.     func = *_vblqueue;
  104.     i = *nvblq;
  105.     if (alrm_in_vblq)
  106.         while (i--)
  107.             if (*func == (char *) alrm_timer) {
  108.                 *func = (char *) 0;
  109.                 alrm_in_vblq = 0;
  110.                 return 0;
  111.             } else
  112.                 func++;
  113.     else
  114.         while (i--)
  115.             if (!*func) {
  116.                 *func = (char *) alrm_timer;
  117.                 alrm_in_vblq = 1;
  118.                 return 0;
  119.             } else
  120.                 func++;
  121.     return 1;
  122. }
  123.