home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
-
- FILE
- alarm.c - set hardware timer (8253 timer 0) - IBM-PC version
-
- ROUTINES
- setalarm - set hardware timer alarm in milliseconds (double).
- rsetalarm - a "raw" form of setalarm(), using ticks
- alarm_count - returns the current count (long).
- alarm_time - returns the current time in millisec (double).
-
- REMARKS
- These procedures are obviously hardware dependent. The 8253 timer 0
- is set to mode 3, 16-bit binary count. The maximum period on the
- IBM PC is limited to about 54.9 milliseconds, which is the default
- tick frequency used by DOS.
-
- To reduce overheads for very time critical applications, rsetalarm()
- allows the period to be specified in clock ticks to eliminate the
- millisecond to tick conversion overhead.
-
- If the interval argument is zero or negative, the timer is reset to
- the DOS default state.
-
- LAST UPDATE
- 3 May 1985
- add rsetalarm().
- 12 January 1988
- change all floats to doubles
-
- Copyright (c) 1985-1988 D.M. Auslander and C.H. Tham
-
- ***********************************************************************/
-
- /***********************************************************************
- I M P O R T S
- ***********************************************************************/
-
- #include <stdio.h>
-
- #include "envir.h" /* environment declarations */
- #include "inout.h" /* in() and out() function mapping macros */
- #include "alarm.h" /* address and other declarations */
-
- /***********************************************************************
- P R I V A T E D A T A
- ***********************************************************************/
-
- static long count = 0xFFFFL; /* current count, init to DOS default */
-
- /***********************************************************************
- E N T R Y R O U T I N E S
- ***********************************************************************/
-
- /*----------------------------------------------------------------------
- PROCEDURE
- SETALARM - set timer interrupt period in milliseconds
-
- SYNOPSIS
- int setalarm(ms)
- double ms;
-
- PARAMETERS
- ms - interval in milliseconds
-
- RETURNS
- 0 normal return
- 1 error return
-
- REMARKS
- Since the max. interval for the IBM PC corresponds to a maximum
- count of 65535, the maximum value of ms is limited to 54.9 ms.
-
- If ms is zero or negative, timer will be reset to DOS default.
-
- LAST UPDATE
- 23 August 1985 by D. M. Auslander
- change to float input format
- 12 January 1988 by Haam
- change floats to doubles
- ----------------------------------------------------------------------*/
-
- int setalarm(ms)
- double ms;
- {
-
- if ((ms > 0.0) && (ms <= MAX_MS)) /* argument is valid */
- {
- count = (CLOCKFREQ * ms) / 1000.0 + 0.5;
-
- out(TIMER_CTL, 0x36); /* mode 3, 16-bit binary count */
-
- out(TIMER, count & 0xFF); /* send least sig. byte first */
- out(TIMER, (count >> 8) & 0xFF);
- }
- else if (ms <= 0.0) /* reset to DOS clock rate */
- {
- out(TIMER_CTL, 0x36);
-
- out(TIMER, DOS_COUNT & 0xFF);
- out(TIMER, (DOS_COUNT >> 8) & 0xFF);
-
- count = DOS_COUNT;
- }
- else /* bad input - do nothing */
- {
- return(1); /* error return */
- }
-
- return(0); /* normal return */
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- RSETALARM - raw form of setalarm using clock ticks instead of ms.
-
- SYNOPSIS
- rsetalarm(ticks)
- long ticks;
-
- PARAMETERS
- ticks - interval in clock ticks (1,193,180 Hz raw clock)
-
- RETURNS
- 0 normal return
- 1 error return
-
- REMARKS
- This raw form is intended for time critical programs that
- cannot afford the overhead of converting milliseconds to ticks.
- For even more time critical applications, the range check
- can be omitted.
-
- The clock frequency is defined in alarm.h as CLOCKFREQ.
-
- LAST UPDATE
- 3 May 1985
- ----------------------------------------------------------------------*/
-
- int rsetalarm(ticks)
- long ticks;
- {
-
- if ((ticks > 0L) && (ticks < 65536L))
- {
- out(TIMER_CTL, 0x36);
-
- out(TIMER, ticks & 0xFF); /* send least sig. byte first */
- out(TIMER, (ticks >> 8) & 0xFF);
-
- count = ticks;
- }
- else if (ticks <= 0L) /* reset to DOS default */
- {
- out(TIMER_CTL, 0x36);
-
- out(TIMER, DOS_COUNT & 0xFF);
- out(TIMER, (DOS_COUNT >> 8) & 0xFF);
-
- count = DOS_COUNT;
- }
- else
- return(1); /* error return */
-
- return(0); /* normal return */
- }
-
-
-
- /*----------------------------------------------------------------------
- PROCEDURE
- ALARM_COUNT - get the current count value
-
- SYNOPSIS
- long alarm_count()
-
- RETURNS
- the current count used by the timer
-
- LAST UPDATE
- 21-Aug-85 by D. M. Auslander
- ----------------------------------------------------------------------*/
-
- long alarm_count()
- {
-
- return(count);
- }
-
-
-
- /*------------------------------------------------------------------
- PROCEDURE
- ALARM_TIME - get the current timer interval in millisec
-
- SYNOPSIS
- double alarm_time()
-
- RETURNS
- count * 1000 / CLOCKFREQ
-
- LAST UPDATE
- 23-Aug-85 by D. M. Auslander
- ----------------------------------------------------------------------------*/
-
- double alarm_time()
- {
-
- return((double)count * 1000.0 / CLOCKFREQ);
- }
-