xref: /reactos/boot/armllb/hw/time.c (revision 84344399)
1 /*
2  * PROJECT:         ReactOS Boot Loader
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * FILE:            boot/armllb/hw/time.c
5  * PURPOSE:         LLB Time Routines
6  * PROGRAMMERS:     ReactOS Portable Systems Group
7  */
8 
9 #include "precomp.h"
10 
11 #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
12 
13 UCHAR LlbDaysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
14 
15 #ifndef _ZOOM2_
16 TIMEINFO LlbTime;
17 #else
18 extern TIMEINFO LlbTime;
19 #endif
20 
21 BOOLEAN
22 NTAPI
23 LlbIsLeapYear(IN ULONG Year)
24 {
25     /* Every 4, 100, or 400 years */
26     return (!(Year % 4) && (Year % 100)) || !(Year % 400);
27 }
28 
29 ULONG
30 NTAPI
31 LlbDayOfMonth(IN ULONG Month,
32               IN ULONG Year)
33 {
34     /* Check how many days a month has, accounting for leap yearS */
35     return LlbDaysInMonth[Month] + (LlbIsLeapYear(Year) && Month == 1);
36 }
37 
38 VOID
39 NTAPI
40 LlbConvertRtcTime(IN ULONG RtcTime,
41                   OUT TIMEINFO* TimeInfo)
42 {
43     ULONG Month, Year, Days, DaysLeft;
44 
45     /* Count the days, keep the minutes */
46     Days = RtcTime / 86400;
47     RtcTime -= Days * 86400;
48 
49     /* Get the year, based on days since 1970 */
50     Year = 1970 + Days / 365;
51 
52     /* Account for leap years which changed the number of days/year */
53     Days -= (Year - 1970) * 365 + LEAPS_THRU_END_OF(Year - 1) - LEAPS_THRU_END_OF(1970 - 1);
54     if (Days < 0)
55     {
56         /* We hit a leap year, so fixup the math */
57         Year--;
58         Days += 365 + LlbIsLeapYear(Year);
59     }
60 
61     /* Count months */
62     for (Month = 0; Month < 11; Month++)
63     {
64         /* How many days in this month? */
65         DaysLeft = Days - LlbDayOfMonth(Month, Year);
66         if (DaysLeft < 0) break;
67 
68         /* How many days left total? */
69         Days = DaysLeft;
70     }
71 
72     /* Write the structure */
73     TimeInfo->Year = Year;
74     TimeInfo->Day = Days + 1;
75     TimeInfo->Month = Month + 1;
76     TimeInfo->Hour = RtcTime / 3600;
77     RtcTime -= TimeInfo->Hour * 3600;
78     TimeInfo->Minute = RtcTime / 60;
79     TimeInfo->Second = RtcTime - TimeInfo->Minute * 60;
80 }
81 
82 TIMEINFO*
83 NTAPI
84 LlbGetTime(VOID)
85 {
86     ULONG RtcTime;
87 
88     /* Read RTC time */
89     RtcTime = LlbHwRtcRead();
90 #ifndef _ZOOM2_
91     /* Convert it */
92     LlbConvertRtcTime(RtcTime, &LlbTime);
93 #endif
94     return &LlbTime;
95 }
96 
97 /* EOF */
98