Page 1 of 1
RTC and century
Posted: Sat Nov 21, 2009 4:41 pm
by psnix
hi
i have some problems with calculatin year , for getting date i use RTC:
Code: Select all
unsigned char y,m,d,c;
SDate t;
short int RTCaddress = 0x70;
short int RTCdata = 0x71;
#if ARAX_HAL_COMPILER == ARAX_HAL_COMPILER_MSVC
_asm
{
l1: mov al,10
out 0x70,al
in al,0x71
test al,0x80
jne l1
mov al,0x07
out 0x70,al
in al,0x71
mov byte ptr[d],al
mov al,0x08
out 0x70,al
in al,0x71
mov byte ptr[m],al
mov al,0x09
out 0x70,al
in al,0x71
mov byte ptr[y],al
mov al,20
out 0x70,al
in al,0x71
mov byte ptr[c],al
}
#endif
t.year = ((BCDtoBinary(c)-1) * 1000) + BCDtoBinary(y);
t.month = BCDtoBinary(m);
t.day =BCDtoBinary(d);
but this is'nt work correclty always for example in the vmware its work but not in bochs.
how can i get current century and calculate current date??
Re: RTC and century
Posted: Sun Nov 22, 2009 3:48 am
by Creature
I believe the century and year are relative to the epoch (or something similar), so you have to add that to the counter. Sadly, I'm not really sure what epoch that is. It could be the Unix epoch as well as other epochs. Perhaps someone else is able to shed some light on it.
Re: RTC and century
Posted: Sun Nov 22, 2009 5:00 am
by Brendan
Hi,
Originally the CMOS didn't keep track of the century at all, and an OS had to guess. For example, an OS written in 1978 might do "if (year >= 78) then { year += 1900 } else { year += 2000 }". This means an OS should work fine for 99 years after it's written/released (but, see below).
Later on (probably about 15 years ago now) some chipsets added "century" to the RTC. This wasn't part of the original RTC (it's a non-standard extension), which means that different chipsets use different CMOS locations for the century. The only way I know of to determine if the RTC supports "century" and to determine which CMOS location it uses is to parse the ACPI "FADT" table. At offset 108 in this table there's a byte that contains the CMOS location for the RTC's century (if it's nonzero). If this byte is zero then the RTC doesn't support "century" and you need to use the "works for 99 years" method above.
I should also point out that some old computers are borked - the BIOS/RTC only supports 1900 to 1999. This causes 2 problems. The first problem is that if you use the BIOS to set the correct date then the BIOS will mis-calculate the "day of the week" field, but no sane OS uses the RTC "day of the week field" anyway. The other problem is leap years, but if you set the RTC date to 1909 (instead of 2009) then you shouldn't have a problem until the year 2100.
Cheers,
Brendan
Re: RTC and century
Posted: Sun Nov 22, 2009 6:04 am
by Owen
Perhaps the OS should also store the century elsewhere; it's unlikely it's not going to be booted for 100 years (And if it is, the clock battery's probably long dead!), and at least that way it's reliable.
Possibly best to store the year, rather than the century actually; that way, you can do something like
if(cmos_year < stored_year_without_century) {
/* We have probably been off during a century switchover - add one to the century and append the RTC date to it */
} else {
/* Take the year from the RTC and append it to the century we stored */
}
Re: RTC and century
Posted: Sun Nov 22, 2009 8:06 am
by Creature
I guess the best way to have time would be to not use the RTC at all, but use an internet server for synchronization. The PIT can then be used for timing events. The only thing the RTC (IMO) is useful for is determining the date/time when there is no internet connection, which most people definately have. If they don't, I guess they're stuck with a wrong time (use a clock?).
I'm not sure how accurate the time in the RTC is anyways. I'm guessing it will run behind/forward after a while because of its accuracy (which is probably why they switched to time synchronization servers in the first place).
Re: RTC and century
Posted: Sun Nov 22, 2009 8:17 am
by Owen
The RTC is clocked by a crystal orders of magnitude better than the PIT. The PIT will drift by seconds every hour; the RTC is seconds per year.