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

  1. /***********************************************************************
  2.  
  3. FILE
  4.     alarm.c -  set hardware timer (8253 timer 0) - IBM-PC 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 milliseconds, which is the default
  16.     tick frequency used by DOS.
  17.  
  18.     To reduce overheads for very time critical applications, rsetalarm()
  19.     allows the period to be specified in clock ticks to eliminate the
  20.     millisecond to tick conversion overhead.
  21.  
  22.     If the interval argument is zero or negative, the timer is reset to
  23.     the DOS default state.
  24.  
  25. LAST UPDATE
  26.     3 May 1985
  27.         add rsetalarm().
  28.     12 January 1988
  29.         change all floats to doubles
  30.  
  31.     Copyright (c) 1985-1988  D.M. Auslander and C.H. Tham
  32.  
  33. ***********************************************************************/
  34.  
  35. /***********************************************************************
  36.                             I M P O R T S
  37. ***********************************************************************/
  38.  
  39. #include <stdio.h>
  40.  
  41. #include "envir.h"        /* environment declarations */
  42. #include "inout.h"        /* in() and out() function mapping macros */
  43. #include "alarm.h"        /* address and other declarations */
  44.  
  45. /***********************************************************************
  46.                     P R I V A T E    D A T A
  47. ***********************************************************************/
  48.  
  49. static long count = 0xFFFFL;    /* current count, init to DOS default */
  50.  
  51. /***********************************************************************
  52.                     E N T R Y    R O U T I N E S
  53. ***********************************************************************/
  54.  
  55. /*----------------------------------------------------------------------
  56. PROCEDURE
  57.     SETALARM  -  set timer interrupt period in milliseconds
  58.  
  59. SYNOPSIS
  60.     int setalarm(ms)
  61.     double ms;
  62.  
  63. PARAMETERS
  64.     ms  -  interval in milliseconds
  65.  
  66. RETURNS
  67.     0  normal return
  68.     1  error return
  69.  
  70. REMARKS
  71.     Since the max. interval for the IBM PC corresponds to a maximum
  72.     count of 65535, the maximum value of ms is limited to 54.9 ms.
  73.  
  74.     If ms is zero or negative, timer will be reset to DOS default.
  75.  
  76. LAST UPDATE
  77.     23 August 1985 by D. M. Auslander
  78.         change to float input format
  79.     12 January 1988  by  Haam
  80.         change floats to doubles
  81. ----------------------------------------------------------------------*/
  82.  
  83. int setalarm(ms)
  84. double ms;
  85. {
  86.  
  87.     if ((ms > 0.0) && (ms <= MAX_MS))    /* argument is valid */
  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 (1,193,180 Hz raw clock)
  125.  
  126. RETURNS
  127.     0  normal return
  128.     1  error return
  129.  
  130. REMARKS
  131.     This raw form is intended for time critical programs that
  132.     cannot afford the overhead of converting milliseconds to ticks.
  133.     For even more time critical applications, the range check
  134.     can be omitted.
  135.  
  136.     The clock frequency is defined in alarm.h as CLOCKFREQ.
  137.  
  138. LAST UPDATE
  139.     3 May 1985
  140. ----------------------------------------------------------------------*/
  141.  
  142. int rsetalarm(ticks)
  143. long ticks;
  144. {
  145.  
  146.     if ((ticks > 0L) && (ticks < 65536L))
  147.     {
  148.         out(TIMER_CTL, 0x36);
  149.  
  150.         out(TIMER, ticks & 0xFF);    /* send least sig. byte first */
  151.         out(TIMER, (ticks >> 8) & 0xFF);
  152.         
  153.         count = ticks;
  154.     }
  155.     else if (ticks <= 0L)            /* reset to DOS default */
  156.     {
  157.         out(TIMER_CTL, 0x36);
  158.  
  159.         out(TIMER, DOS_COUNT & 0xFF);
  160.         out(TIMER, (DOS_COUNT >> 8) & 0xFF);
  161.         
  162.         count = DOS_COUNT;
  163.     }
  164.     else
  165.         return(1);    /* error return */
  166.  
  167.     return(0);        /* normal return */
  168. }
  169.  
  170.  
  171.  
  172. /*----------------------------------------------------------------------
  173. PROCEDURE
  174.     ALARM_COUNT  -  get the current count value
  175.  
  176. SYNOPSIS
  177.     long alarm_count()
  178.  
  179. RETURNS
  180.     the current count used by the timer
  181.  
  182. LAST UPDATE
  183.     21-Aug-85 by D. M. Auslander
  184. ----------------------------------------------------------------------*/
  185.  
  186. long alarm_count()
  187. {
  188.     
  189.     return(count);
  190. }
  191.  
  192.  
  193.  
  194. /*------------------------------------------------------------------
  195. PROCEDURE
  196.     ALARM_TIME  -  get the current timer interval in millisec
  197.  
  198. SYNOPSIS
  199.     double alarm_time()
  200.  
  201. RETURNS
  202.     count * 1000 / CLOCKFREQ
  203.  
  204. LAST UPDATE
  205.     23-Aug-85 by D. M. Auslander
  206. ----------------------------------------------------------------------------*/
  207.  
  208. double alarm_time()
  209. {
  210.     
  211.     return((double)count * 1000.0 / CLOCKFREQ);
  212. }
  213.  
  214.