home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s300 / 1.ddi / CHAP3 / ALARM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-02  |  5.7 KB  |  213 lines

  1. /***********************************************************************
  2.  
  3. FILE
  4.     alarm.c -  set hardware timer (8253, timer 0 version)
  5.  
  6. ROUTINES
  7.     setalarm    -  set hardware timer alarm in milliseconds (double).
  8.     rsetalarm   -  a "raw" form of setalarm(), using ticks
  9.     alarm_count - returns the current count (long).
  10.     alarm_time  - returns the current time in millisec (double).
  11.  
  12. REMARKS
  13.     These procedures are obviously hardware dependent. The 8253 timer 0
  14.     is set to mode 3, 16-bit binary count.  The maximum period on the
  15.     IBM PC is limited to about 54.9 ms.  This is the default period used
  16.     by DOS.
  17.  
  18.     A time granularity of 1 ms is quite adequate for most applications.
  19.     Thus specifying the interval in ms is very convenient.  However,
  20.     there will be applications (such as pulse width modulation control)
  21.     where it may be necessary to change the interval very frequently.
  22.     To reduce overheads for such time critical applications, rsetalarm
  23.     specifies the interval in clock ticks, eliminating the millisecond
  24.     to tick conversion overhead.
  25.  
  26.     If the interval argument is zero or negative, the timer is reset to
  27.     the DOS default state.
  28.  
  29. LAST UPDATE
  30.     3 May 1985
  31.         add rsetalarm().
  32.  
  33.     Copyright (c) 1985  D.M. Auslander and C.H. Tham
  34.  
  35. ***********************************************************************/
  36.  
  37. /***********************************************************************
  38.                             I M P O R T S
  39. ***********************************************************************/
  40.  
  41. #include <stdio.h>
  42.  
  43. #include "envir.h"      /* environment declarations */
  44. #include "inout.h"      /* in() and out() function mapping macros */
  45. #include "alarm.h"      /* address and other declarations */
  46.  
  47.  
  48. /***********************************************************************
  49.                     P R I V A T E    D A T A
  50. ***********************************************************************/
  51.  
  52. static long count;      /* current count */
  53.  
  54.  
  55. /***********************************************************************
  56.                     E N T R Y    R O U T I N E S
  57. ***********************************************************************/
  58.  
  59. /*----------------------------------------------------------------------
  60. PROCEDURE
  61.     SETALARM  -  set interrupt interval in milliseconds
  62.  
  63. SYNOPSIS
  64.     int setalarm(ms)
  65.     double ms;
  66.  
  67. PARAMETERS
  68.     ms  -  interval in milliseconds
  69.  
  70. RETURNS
  71.     0  normal return
  72.     1  error return
  73.  
  74. REMARKS
  75.     Since the max. interval for the IBM PC corresponds to a maximum
  76.     count of 65535, the maximum value of ms is limited to 54.9 ms.
  77.  
  78. LAST UPDATE
  79.     23 August 1985 by D. M. Auslander
  80.         change to float input format
  81. ----------------------------------------------------------------------*/
  82.  
  83. int setalarm(ms)
  84. double ms;
  85. {
  86.  
  87.     if ((ms > 0.0) && (ms <= MAX_MS))
  88.     {
  89.         count = (CLOCKFREQ * ms) / 1000.0 + 0.5;
  90.  
  91.         out(TIMER_CTL, 0x36);       /* mode 3, 16-bit binary count */
  92.  
  93.         out(TIMER, count & 0xff);   /* send least sig. byte first */
  94.         out(TIMER, (count >> 8) & 0xff);
  95.     }
  96.     else if (ms <= 0.0)             /* reset to DOS clock rate */
  97.     {
  98.         out(TIMER_CTL, 0x36);
  99.  
  100.         out(TIMER, DOS_COUNT & 0xff);
  101.         out(TIMER, (DOS_COUNT >> 8) & 0xff);
  102.         
  103.         count = DOS_COUNT;
  104.     }
  105.     else    /* bad input - do nothing */
  106.     {
  107.         return(1);      /* Error return */
  108.     }
  109.  
  110.     return(0);          /* Normal return */
  111. }
  112.  
  113.  
  114.  
  115. /*----------------------------------------------------------------------
  116. PROCEDURE
  117.     RSETALARM  -  raw form of setalarm using clock ticks instead of ms.
  118.  
  119. SYNOPSIS
  120.     rsetalarm(ticks)
  121.     long ticks;
  122.  
  123. PARAMETERS
  124.     ticks  -  interval in clock ticks
  125.  
  126. RETURNS
  127.     ERROR (1 for error return, 0 for normal return)
  128.  
  129. REMARKS
  130.     This raw form is intended for extremely time critical programs that
  131.     cannot afford the overhead of converting milliseconds to ticks  or
  132.     programs that require precision better than 1 millisecond.
  133.  
  134.     In the interest of speed, we shall assume that the timer is in the
  135.     correct mode (mode 3) and not reprogram the mode.
  136.  
  137.     The clock frequency is defined in alarm.h as CLOCKFREQ.
  138.  
  139. LAST UPDATE
  140.     3 May 1985
  141. ----------------------------------------------------------------------*/
  142.  
  143. int rsetalarm(ticks)
  144. long ticks;
  145. {
  146.  
  147.     if ((ticks > 0L) && (ticks < 65536L))
  148.     {
  149.         out(TIMER, ticks & 0xff);   /* send least sig. byte first */
  150.         out(TIMER, (ticks >> 8) & 0xff);
  151.         
  152.         count = ticks;
  153.     }
  154.     else if (ticks < 0L)            /* reset to DOS default */
  155.     {
  156.         out(TIMER_CTL, 0x36);
  157.  
  158.         out(TIMER, DOS_COUNT & 0xff);
  159.         out(TIMER, (DOS_COUNT >> 8) & 0xff);
  160.         
  161.         count = DOS_COUNT;
  162.     }
  163.     else
  164.         return(1);  /* error return */
  165.  
  166.     return(0);      /* normal return */
  167. }
  168.  
  169.  
  170.  
  171. /*----------------------------------------------------------------------
  172. PROCEDURE
  173.     ALARM_COUNT  -  get the current count value
  174.  
  175. SYNOPSIS
  176.     long alarm_count()
  177.  
  178. RETURNS
  179.     the current count used by the timer
  180.  
  181. LAST UPDATE
  182.     21-Aug-85 by D. M. Auslander
  183. ----------------------------------------------------------------------*/
  184.  
  185. long alarm_count()
  186. {
  187.     
  188.     return(count);
  189. }
  190.  
  191.  
  192.  
  193. /*------------------------------------------------------------------
  194. PROCEDURE
  195.     ALARM_TIME  -  get the current timer interval in millisec
  196.  
  197. SYNOPSIS
  198.     double alarm_time()
  199.  
  200. RETURNS
  201.     count * 1000 / CLOCKFREQ
  202.  
  203. LAST UPDATE
  204.     23-Aug-85 by D. M. Auslander
  205. ----------------------------------------------------------------------------*/
  206.  
  207. double alarm_time()
  208. {
  209.     
  210.     return((double)count * 1000.0 / CLOCKFREQ);
  211. }
  212.  
  213.