home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / datetime / navytime / timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-08-02  |  3.3 KB  |  108 lines

  1. /* timer -- real time interval timer for Turbo C                            */
  2. /* copyright 1987  Michael M Rubenstein                                     */
  3.  
  4. /* The technique for chaining to the old interrupt routine is due to        */
  5. /* Don Corbitt                                                              */
  6.  
  7. #include <dos.h>
  8. #include "atfinish.h"
  9. #include "timer.h"
  10.  
  11. #define INT_REGS        unsigned bp, unsigned di, unsigned si, unsigned ds, \
  12.                         unsigned es, unsigned dx, unsigned cx, unsigned bx, \
  13.                         unsigned ax, unsigned ip, unsigned cs, unsigned flags
  14.  
  15. volatile static long    count;
  16. static int              timed_out;
  17. static void             (*timer_func)(void);
  18. static void interrupt   (*old_ticker)(void) = (void interrupt (*) ()) 0;
  19.  
  20. void                    clear_timer_routine(void), set_timer_routine(void);
  21. void interrupt          new_ticker(INT_REGS);
  22.  
  23. extern unsigned         _psp;
  24.  
  25. /* set timer                                                                */
  26. void set_timer(int seconds, void (*func)())
  27. {
  28.   if (seconds == 0)
  29.     clear_timer_routine();
  30.   else
  31.   {
  32.     timer_func = func;
  33.     set_timer_routine();
  34.     disable();
  35.     count = (long) (seconds * 182l);
  36.     count /= 10l;
  37.     timed_out = 0;
  38.     enable();
  39.   }
  40. }
  41.  
  42. /* reset ticker to previous routine                                         */
  43. static void clear_timer_routine(void)
  44. {
  45.   if (old_ticker != (void interrupt (*) ()) 0)
  46.     setvect(0x1c, old_ticker);
  47. }
  48.  
  49. /* set ticker to timer routine.  also set exit address to make sure it gets */
  50. /* reset if program exits.  can't use "atexit" since that is bypassed on    */
  51. /* various types of abnormal termination                                    */
  52. static void set_timer_routine(void)
  53. {
  54.   void interrupt        (*ticker)(void) = (void interrupt (*) ()) 0;
  55.  
  56.  
  57.   /* set timer routine */
  58.   if (old_ticker == (void interrupt (*)()) 0)
  59.   {
  60.     ticker = getvect(0x1c);
  61.     atfinish(clear_timer_routine);
  62.   }
  63.  
  64.   disable();
  65.   old_ticker = ticker;
  66.   enable();
  67.   setvect(0x1c, new_ticker);
  68. }
  69.  
  70. #pragma warn -par
  71. /* ticker routine.  count down and set timed_out when zero is reached       */
  72. static void interrupt new_ticker(INT_REGS)
  73. {
  74.   volatile unsigned     temp[6];
  75.  
  76.   if (--count == 0)
  77.     timed_out = 1;
  78.  
  79.   /* chain to next routine */
  80.   temp[0] = bp;                         /* Save top 3 values */
  81.   temp[1] = di;
  82.   temp[2] = si;
  83.   bp = ds;                              /* Move all others up by 3 */
  84.   di = es;
  85.   si = dx;
  86.   ds = cx;
  87.   es = bx;
  88.   dx = ax;
  89.   cx = FP_OFF(old_ticker);              /* and put a new ip/cs/flags */
  90.   bx = FP_SEG(old_ticker);              /* on the stack */
  91.   ax = flags & ~0x200;
  92.   _BP -= 6;                             /* Modify BP by three words        */
  93.                                         /* NOTE: after changing _BP, don't */
  94.                                         /* plan on using an local variables, */
  95.                                         /* other than those here.           */
  96.   bp = temp[3];                         /* Restore top 3 values             */
  97.   di = temp[4];
  98.   si = temp[5];
  99. }
  100. #pragma warn .par
  101.  
  102. /* check if timer expired and execute timer function if so                  */
  103. void chk_timer(void)
  104. {
  105.   if (timed_out)
  106.     (*timer_func)();
  107. }
  108.