home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s300 / 1.ddi / CHAP2 / ALARM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-02  |  5.7 KB  |  216 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. /***********************************************************************
  47.                     P R I V A T E    D A T A
  48. ***********************************************************************/
  49.  
  50. static long count = 0xFFFFL;    /* current count, init to DOS default */
  51.  
  52.  
  53. /***********************************************************************
  54.                     E N T R Y    R O U T I N E S
  55. ***********************************************************************/
  56.  
  57. /*----------------------------------------------------------------------
  58. PROCEDURE
  59.     SETALARM  -  set timer interrupt period in milliseconds
  60.  
  61. SYNOPSIS
  62.     int setalarm(ms)
  63.     double ms;
  64.  
  65. PARAMETERS
  66.     ms  -  interval in milliseconds
  67.  
  68. RETURNS
  69.     0  normal return
  70.     1  error return
  71.  
  72. REMARKS
  73.     Since the max. interval for the IBM PC corresponds to a maximum
  74.     count of 65535, the maximum value of ms is limited to 54.9 ms.
  75.  
  76.     If ms is zero or negative, timer will be reset to DOS default.
  77.  
  78. LAST UPDATE
  79.     23 August 1985 by D. M. Auslander
  80.         change to float input format
  81.     12 January 1988  by  Haam
  82.         change floats to doubles
  83. ----------------------------------------------------------------------*/
  84.  
  85. int setalarm(ms)
  86. double ms;
  87. {
  88.  
  89.     if ((ms > 0.0) && (ms <= MAX_MS))   /* argument is valid */
  90.     {
  91.         count = (CLOCKFREQ * ms) / 1000.0 + 0.5;
  92.  
  93.         out(TIMER_CTL, 0x36);       /* mode 3, 16-bit binary count */
  94.  
  95.         out(TIMER, count & 0xFF);   /* send least sig. byte first */
  96.         out(TIMER, (count >> 8) & 0xFF);
  97.     }
  98.     else if (ms <= 0.0)             /* reset to DOS clock rate */
  99.     {
  100.         out(TIMER_CTL, 0x36);
  101.  
  102.         out(TIMER, DOS_COUNT & 0xFF);
  103.         out(TIMER, (DOS_COUNT >> 8) & 0xFF);
  104.         
  105.         count = DOS_COUNT;
  106.     }
  107.     else    /* bad input - do nothing */
  108.     {
  109.         return(1);      /* error return */
  110.     }
  111.  
  112.     return(0);          /* normal return */
  113. }
  114.  
  115.  
  116.  
  117. /*----------------------------------------------------------------------
  118. PROCEDURE
  119.     RSETALARM  -  raw form of setalarm using clock ticks instead of ms.
  120.  
  121. SYNOPSIS
  122.     rsetalarm(ticks)
  123.     long ticks;
  124.  
  125. PARAMETERS
  126.     ticks  -  interval in clock ticks (1,193,180 Hz raw clock)
  127.  
  128. RETURNS
  129.     0  normal return
  130.     1  error return
  131.  
  132. REMARKS
  133.     This raw form is intended for time critical programs that
  134.     cannot afford the overhead of converting milliseconds to ticks.
  135.     For even more time critical applications, the range check
  136.     can be omitted.
  137.  
  138.     The clock frequency is defined in alarm.h as CLOCKFREQ.
  139.  
  140. LAST UPDATE
  141.     3 May 1985
  142. ----------------------------------------------------------------------*/
  143.  
  144. int rsetalarm(ticks)
  145. long ticks;
  146. {
  147.  
  148.     if ((ticks > 0L) && (ticks < 65536L))
  149.     {
  150.         out(TIMER_CTL, 0x36);
  151.  
  152.         out(TIMER, ticks & 0xFF);   /* send least sig. byte first */
  153.         out(TIMER, (ticks >> 8) & 0xFF);
  154.         
  155.         count = ticks;
  156.     }
  157.     else if (ticks <= 0L)           /* reset to DOS default */
  158.     {
  159.         out(TIMER_CTL, 0x36);
  160.  
  161.         out(TIMER, DOS_COUNT & 0xFF);
  162.         out(TIMER, (DOS_COUNT >> 8) & 0xFF);
  163.         
  164.         count = DOS_COUNT;
  165.     }
  166.     else
  167.         return(1);  /* error return */
  168.  
  169.     return(0);      /* normal return */
  170. }
  171.  
  172.  
  173.  
  174. /*----------------------------------------------------------------------
  175. PROCEDURE
  176.     ALARM_COUNT  -  get the current count value
  177.  
  178. SYNOPSIS
  179.     long alarm_count()
  180.  
  181. RETURNS
  182.     the current count used by the timer
  183.  
  184. LAST UPDATE
  185.     21-Aug-85 by D. M. Auslander
  186. ----------------------------------------------------------------------*/
  187.  
  188. long alarm_count()
  189. {
  190.     
  191.     return(count);
  192. }
  193.  
  194.  
  195.  
  196. /*------------------------------------------------------------------
  197. PROCEDURE
  198.     ALARM_TIME  -  get the current timer interval in millisec
  199.  
  200. SYNOPSIS
  201.     double alarm_time()
  202.  
  203. RETURNS
  204.     count * 1000 / CLOCKFREQ
  205.  
  206. LAST UPDATE
  207.     23-Aug-85 by D. M. Auslander
  208. ----------------------------------------------------------------------------*/
  209.  
  210. double alarm_time()
  211. {
  212.     
  213.     return((double)count * 1000.0 / CLOCKFREQ);
  214. }
  215.  
  216.