Note: The following paper was presented at PTTI '92 in McLean, Virginia on December 2, 1992. The 24th Annual Precise Time and Time Interval Applications and Planning Meeting was held at the Ritz-Carlton Hotel at Tysons Corner. The major emphasis was on systems that use time, time interval and frequency and that are not generally known or thought of as timed systems. These include PTTI applications in major aerospace, military, commercial and telecommunications programs. The Meeting is sponsored each year by the U.S. Naval Observatory, and is currently chaired by Sheila C. Faulkner. RighTime tm A Real Time Clock Correcting Program For MS-DOS-Based Computer Systems G. Thomas Becker Air System Technologies, Inc. 14232 Marsh Lane, Suite 339 Dallas, Texas 75234-3899 214/402-9660 214/869-1166 Fax 214/869-2780 BBS Abstract A computer program is described which effectively eliminates the misgivings of the DOS system clock in PC/AT-class computers. RighTime is a small, sophisticated memory-resident program that automatically corrects both the DOS system clock and the hardware "CMOS" real time clock (RTC) in real time. RighTime learns what corrections are required without operator interaction beyond the occasional accurate time set. Both warm (power on) and cool (power off) errors are corrected, usually yielding better than one part per million accuracy in the typical desktop computer with no additional hardware, and RighTime increases the system clock resolution from approximately 0.0549 second to 0.01 second. Program tools are also available which allow visualization of RighTime's actions, verification of its performance, display of its history log, and which provide data for graphing of the system clock behavior. The program has found application in a wide variety of industries, including astronomy, satellite tracking, communications, broadcasting, transportation, public utilities, manufacturing, medicine and the military. Introduction Most MS-DOS, PC-DOS and DRDOS users have long ago learned to live with, and generally regard as inadequate, the system time-of- day clock that is a standard component of these operating systems. The typical DOS-based computer system clock exhibits inaccuracies that can range from a few seconds to several minutes per day, and the system can lose track of days at a time (on Friday, leave a DOS-based computer running at the office and go home for the weekend; when you return to the office Monday morning, the machine will very likely tell you it's Saturday). These errors are the result of a combination of compromises at several steps in the IBM PC design process, circa 1980. The consequences remain with users to this day. No autonomous RTC hardware was implemented in the original IBM PC announced in August, 1981. Instead, software (partially in ROM-based BIOS firmware and partially in RAM-resident DOS) counted regular interrupts which were generated by an interval timer. DOS converted the resulting "tick" count to conventional expressions of time of day when application software called for it, and, if during a request for the time DOS determined that midnight had passed, it incremented the system date. Whenever the system was booted, the date and time was initialized to 1980/01/01 00:00:00; the user was expected to set both at each boot. With the introduction of the PC/AT in August, 1984, a hardware clock system - a Motorola MC146818 CMOS RTC and some associated circuitry - was included. The part was powered by a battery when the system was not operating so it would maintain date and time continually. Released at the same time, DOS Version 3 automatically read the CMOS RTC clock date and time at system boot and set its date and tick counts to match; aside from that initialization at boot, the hardware clock was not used. When the DOS date or time was changed by the user, the change was not reflected in the CMOS RTC clock; it needed a separate setup utility program. Later DOS versions set the CMOS RTC clock at the same time the DOS clock was set, but the CMOS RTC clock time was still read, and is still today, only at boot. No other changes have been made to the time-of-day clock mechanisms of the AT-class PC-compatible computer since 1984, except as have been applied to the CMOS RTC clock hardware itself. (Dallas Semiconductor and Motorola now produce several compatible lithium-powered clock modules and Intel and other semiconductor producers have incorporated the RTC logic within large-scale integrated circuits that support the current microprocessors.) The hardware manufacturers and software publishers moved on as if whatever few difficulties that existed were solved with the advent of the PC/AT. The problems were neither solved nor few. The Problems of The DOS Clock The interval timer that DOS uses to generate the regular tick that it counts is driven by an uncalibrated, unconditioned and usually non-adjustable 1.193 Mhz source (1.193 Mhz is one quarter of the original PC system clock frequency of 4.77 Mhz, and it is also one third of the NTSC television standard color burst frequency, 3.579 Mhz). The interval timer is programmed to divide that frequency by 65,536 to produce an interrupt rate of approximately 18.206 ticks per second which determines the resolution of the standard DOS clock, approximately 54.925 milliseconds. DOS allows for the expression of time in 0.01 second increments, but it cannot internally maintain that resolution nor represent decimal times exactly due to the tick resolution. DOS depends upon the cooperation of all software that runs on the machine to allow sufficient time for each interval timer tick interrupt to be counted. This is not always possible, so some interrupts are missed and are not counted. On a computer whose interrupt system is heavily loaded, the accumulation of lost interrupts makes the DOS clock appear to run slowly. The tick interrupt is normally intercepted by a routine in the ROM BIOS which increments a 32-bit tick count in RAM and determines if a value that represents approximately 24 hours has been exceeded (the tick duration makes 24 hours indeterminable exactly). If so, the tick count is set to zero and a single bit flag, representing the passing of midnight, is set and provided to DOS when it next asks for the tick count. These DOS requests only occur when the system is in need of the current time of day. At that time, if the bit is set, DOS increments the date. If more than 24 hours have elapsed between two requests for time of day, DOS is unable to recognize that more than one midnight has passed. If the user displays the date after a system has been running, but idle for more than a day, DOS will indicate that the date is one day after the last day the machine was used. The interval timer has found itself reprogrammed by a number of applications, usually games that require dynamic video presentations. In these programs, the interrupt that the interval timer yields is used to refresh the video screen at a high rate. At the termination of the game, the DOS clock is rarely where it should be. Some of the more responsible programs make an attempt at resetting the DOS clock to compensate for the game session duration, but others leave it in disarray. If the game increased the tick rate and left the intercepting BIOS interrupt "hook" in place, the DOS clock will have advanced greatly; in the worst examples, the rate is left accelerated as well. The Problems of The CMOS RTC The CMOS RTC clock resolves only to whole seconds. When DOS reads it at boot, one second of ambiguity is set in the DOS clock even if the CMOS RTC clock is accurate. Conversely, when the DOS clock is set, DOS transfers whole seconds to the CMOS RTC clock but makes no attempt to deal with the fractional part of the seconds, nor does it synchronize the seconds transition, so even if the DOS clock is set accurately, the CMOS RTC clock won't be. The CMOS RTC clock is usually paced by a 32.768 Khz quartz crystal which is loaded by a pair of capacitors. The crystal is often an inexpensive watch-type device, characterized for operation at room temperature (typically 25 degrees C). At temperatures either above or below the characterized temperature, the crystal's resonance change will slow the clock. The loading capacitors are generally not temperature compensated and add to the detuning. Except in the case of the modern CMOS RTC modules mentioned earlier, no provision is made to allow trimming the crystal frequency. Dallas Semiconductor RTC modules are internally trimmed at the factory to +20 seconds per month at room temperature, anticipating an environment that will slow the clock; in use, the computer system internal temperature is widely varying, ranging from perhaps 10 degrees C when the system is not powered to 55 degrees C when it is. Dallas Semiconductor's data indicates that the part can be expected to run as much as 2.5 minutes per month slow at these temperatures. The CMOS RTC clock oscillator is powered by the system's +5 volt supply when the machine is powered and by a lower voltage when it is on battery backup. Typically, an additional six parts per million error can be expected when the clock is running on battery power. The CMOS RTC clock part provides an option that will automatically advance or retard the time at 0200 on the appropriate Sunday morning when Daylight Savings Time and Standard Time, respectively, start in the USA. This feature is usually not used, since no mechanism to invoke it exists in DOS. DOS does, nevertheless, include a bit in its internal time data structure that indicates whether this automatic time change feature is enabled or not (many documents incorrectly state that the bit indicates that the time is Daylight Savings Time). The rule was changed in 1986 and many computers - even current models - contain parts that still adopt the pre-1986 rule. Even if the feature is enabled, many machines will change on the wrong Sunday morning in April (the last rather than the first). Dallas Semiconductor's DS1287 RTC module was introduced with the currently correct rule. Motorola corrected its part with the announcement of the MCCS146818B1M RTC module in 1991. The Solution to the Problems RighTime approaches the solution to these problems by making best use of the better qualities of each of the two clocks. Two foremost qualities of the CMOS RTC are its relative stability and its autonomy. The DOS clock has a high resolution interval timer available to it, although its availability is conditional, subject to loss of power and to software that commandeers it. With these resources, RighTime does four fundamental things: 1- RighTime slaves the DOS clock to the CMOS RTC, frequently referring the DOS date, tick count and interval timer count to the CMOS RTC date and time; 2- RighTime operates the interval timer in a disciplined mode that allows deriving a higher resolution than standard while maintaining the standard tick rate and count for compatibility; 3- RighTime maintains accuracy by regularly calculating and applying corrections to the DOS clock and adjustments to the CMOS RTC; and 4- RighTime intercepts and monitors time set commands to learn and refine the CMOS RTC correction rate. RighTime is loaded each time DOS is booted, makes itself resident in system memory, and hooks a number of system interrupts. (A hook is a logical tap in the execution chain of some specific event or class of events.) For its time-keeping tasks, RighTime hooks an interrupt from the CMOS RTC, one from the interval timer, and several that convey the time set and read commands from an application program or the user to DOS. Other interrupts are intercepted to disallow functions that could otherwise change resources that RighTime must exclusively control. Since DOS is not ordinarily a multitasking operating system, several other interrupts are hooked to determine when system activities are momentarily idle. These logical pauses are often very brief, but occur frequently and allow RighTime to do its manipulations as a transparent background function without noticeably affecting work that is ongoing in the foreground. The CMOS RTC is programmed to produce an interrupt once per second, immediately after its internal seconds update. Every four seconds, RighTime reads the CMOS RTC date and time, calculates the equivalent DOS clock values, and sets the tick count and interval timer count and mode accordingly. This regular update prevents the DOS clock from wandering far from the CMOS RTC time and corrects whatever ills might come from a game or other application that reprograms the interval timer. Between these periodic updates, the DOS tick count is incremented by the BIOS interval timer interrupt handler - just as it is without RighTime - and is available to those programs that use the tick count directly. RighTime augments the routines that handle the conversions of tick count to time-of-day and time-of-day to tick count with its own routines. These routines process the Get DOS Time and Set DOS Time functions, respectively, and provide resolution that far exceeds the 0.01 second resolution of the DOS clock data structure. Any program that gets the time via the DOS calls will benefit from the additional resolution that RighTime provides. Although the CMOS RTC is relatively stable, its rate is rarely highly accurate. Since, under RighTime, the DOS clock mimics the CMOS RTC, the DOS clock would exhibit the same rate error unless corrected. RighTime handles this by incorporating a calculated correcting offset in each of the DOS clock updates. The result is a deliberately increasing divergence of the two clocks. Assuming that the corrected DOS clock rate is accurate, the CMOS RTC must be occasionally adjusted to match the DOS clock. The CMOS RTC is advanced or retarded when the difference between the two clocks has reached one second; the DOS clock offset is adjusted accordingly. If the DOS clock is set to the correct time, and the CMOS RTC rate correction is proper, the result is a DOS clock whose expression is within 0.01 second of the correct time and a CMOS RTC that is within one second of the correct time. Actually, the calculated DOS clock offset is bipolar, so the CMOS RTC is never more than +/-0.5 second from the correct time. Since the CMOS RTC rate can vary with changes in temperature and voltage, the theoretically perfect correcting algorithm would account for both in appropriate complex terms. In practice, two rates are maintained by RighTime, and suffice; one represents the system power-off state and the other represents power-on. We refer to them as "cool" and "warm", though, since most users seem intuitively familiar with temperature effects. RighTime applies a single calculated adjustment when it is loaded at system boot that corrects for CMOS RTC error that accumulated while the system was in the power-off state; if the program has not been running for more than 30 minutes, the cool correction rate is employed, otherwise the warm correction rate is applied. With that exception, the warm correction rate is used in each DOS clock update. The CMOS RTC rate correction values are learned. RighTime assumes that whenever the DOS clock is set, it is set accurately. At the moment of set, then, the existing DOS clock error is a function of the CMOS RTC rate error, the current cool and warm correction rates, the time elapsed since the last accurate time set, and the ratio of warm and cool operation in that period. The correction rates are refined with each time set, yielding decreasing error as they close on the "ideal" values. These values, and others that are necessary for the process, are stored in a suitable place within the machine hardware or in a small dedicated file. For those users who want one less clock to change twice each year, RighTime offers support for the American Daylight/Standard time change feature of the CMOS RTC. Since the change itself is handled by the hardware, the program does not need to be running when the change needs to occur. The user is cautioned, though, that the change might not occur on the prescribed day in April due to an outdated hardware component. Although RighTime can usually be used effectively with the defaults, the program accepts a wealth of options and user- provided parameters that can detail the function to a specific machine environment, and a logical interface is included that allows the time setting functions to be automated. A system can be easily designed that will continually adjust itself to a slowly changing operational environment as might be encountered with seasonal temperature changes at a remote data acquisition site. Conclusion RighTime is an effective software solution to the poor time- keeping performance of the PC/AT-compatible, DOS-based computer system. The cesium beam and hydrogen maser clock industries will remain unchallenged by your computer, but it should be easy to achieve error rates of 0.5 second per week or better. We regularly hear reports of one tenth of that error rate from stable systems, but these represent the best that can be expected in the current form of the program. The current version (v2.5) requires only 6.5K of RAM, and the program can be loaded into high memory. RighTime is a commercial software product that is currently distributed via shareware. An evaluation copy is available electronically on the Air System Technologies BBS, 214/869-2780 (1200-14400 bps, 8N1), free of charge. The evaluation program is fully functional and may be used for up to 30 days. Usage beyond that period requires payment of a registration fee. Development of the RighTime process is ongoing. We anticipate reliable accuracies on most hardware to exceed 0.001 second, allowing DOS clock time to be expressed to the millisecond in a future revision. An OS/2 version is in planning, with a summer 1993 anticipated delivery.