PRODUCT : Borland C++ NUMBER : 1703 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 1/3 TITLE : Possible conflicts with DOS time and date functions Every IBM compatible PC is capable of keeping track of the current date and time. Your PC can keep the current time even when it is turned off, because of a clock that is built in to the CMOS. However, this CMOS clock is only used once, when your computer is turned on. From this point on the date/time is maintained by both BIOS and DOS working together. Because of some quirks in the way BIOS and DOS work, some problems can occur if you are not careful in your program. To understand these problems and how to avoid them, we first need to see how BIOS and DOS stores the time. The BIOS keeps two variables in memory at the following locations: 0x0040:0x006C - # of ticks since midnight (double word) 0x0040:0x0070 - midnight flag (byte) These values are updated 18.2 times a second, by the system timer. This timer does nothing but increment the tick count, and check to see if midnight has passed. If midnight passes, the tick count is reset to 0, and the midnight flag is set to 1. It is important to note the midnight flag is a Boolean, not a count. That is, it doesn't count the number of times midnight has passed, it only indicates that midnight has passed "at least once". It is also important to note that the BIOS doesn't update the actual clock time or date. It only updates the timer tick count and midnight flag. DOS maintains the time and date, but only when you ask it to retrieve these values. There are several ways to find the current date and time. Listed below are BIOS/DOS interrupts, and their corresponding functions from the Borland C++ run-time library: BIOS int 0x1A,0x00 - read system time (biostime) BIOS int 0x1A,0x01 - DOS system time (biostime) DOS int 0x21,0x2A - get DOS date (getdate, _dos_getdate) DOS int 0x21,0x2B - set DOS date (setdate, _dos_setdate) DOS int 0x21,0x2C - get DOS time (gettime, _dos_gettime) DOS int 0x21,0x2D - set DOS time (settime, _dos_settime) The DOS functions operate by first calling the BIOS function to get the timer tick count and midnight flag, and then PRODUCT : Borland C++ NUMBER : 1703 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 2/3 TITLE : Possible conflicts with DOS time and date functions calculating the appropriate values. The date is only updated when you call one of the DOS date functions. The first problem that can occur is due to the fact that the midnight flag is Boolean. DOS only updates the date when you call a DOS date function, and the midnight flag is reset at this time. Consider the following scenario: actual DOS date date/time | F | event | after event ------------+---+-----------------------------+--------------- 12/01 12:00 | | turn on computer | 12/01 12/02 00:00 | X | midnight flag is set | 12/01 12/02 15:45 | | call DOS getdate function | 12/02 12/03 00:01 | X | midnight flag set | 12/02 12/04 00:00 | X | midnight flag set (again) | 12/02 12/04 11:30 | | call DOS getdate function | 12/03 If an entire day passes with no call to a date function, the internal DOS date never gets updated, causing a day to be missed. The second problem comes in because of how BIOS int 0x1A operates. Whenever you call this function to retrieve the system time (the current timer tick value) it also returns the current midnight flag and RESETS THE FLAG. But since the BIOS function doesn't update the DOS date, the next time you ask for the date, it will not be updated correctly. DOS is aware of the behavior, so when you call any DOS function, the midnight flag is maintained correctly. If you call BIOS int 0x1A yourself, you MUST check the midnight flag value and turn it back on if it was set. The following function is a safe replacement for the biostime() function. It properly restores the midnight flag, avoiding the problem described above: long safebiostime(int cmd, long newtime) { long temptime; asm { mov ax,cmd mov dx,word ptr newtime mov cx,word ptr newtime+2 int 0x1a PRODUCT : Borland C++ NUMBER : 1703 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 3/3 TITLE : Possible conflicts with DOS time and date functions mov word ptr temptime,dx mov word ptr temptime+2,cx or al,al jz not_midnight mov ax,0x40 mov es,ax mov bx,0x70 mov byte ptr es:[bx],1 } not_midnight: return temptime; } DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.