1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** FileX Component */ 16 /** */ 17 /** System */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define FX_SOURCE_CODE 23 24 25 /* Include necessary system files. */ 26 27 #include "fx_api.h" 28 #include "fx_system.h" 29 30 31 /**************************************************************************/ 32 /* */ 33 /* FUNCTION RELEASE */ 34 /* */ 35 /* _fx_system_timer_entry PORTABLE C */ 36 /* 6.1 */ 37 /* AUTHOR */ 38 /* */ 39 /* William E. Lamie, Microsoft Corporation */ 40 /* */ 41 /* DESCRIPTION */ 42 /* */ 43 /* This function is FileX system timer function. It is called at the */ 44 /* rate specified by FX_UPDATE_RATE_IN_SECONDS and is responsible for */ 45 /* maintaining both the system date and time. */ 46 /* */ 47 /* INPUT */ 48 /* */ 49 /* id Not used */ 50 /* */ 51 /* OUTPUT */ 52 /* */ 53 /* None */ 54 /* */ 55 /* CALLS */ 56 /* */ 57 /* None */ 58 /* */ 59 /* CALLED BY */ 60 /* */ 61 /* Application Initialization */ 62 /* */ 63 /* RELEASE HISTORY */ 64 /* */ 65 /* DATE NAME DESCRIPTION */ 66 /* */ 67 /* 05-19-2020 William E. Lamie Initial Version 6.0 */ 68 /* 09-30-2020 William E. Lamie Modified comment(s), */ 69 /* resulting in version 6.1 */ 70 /* */ 71 /**************************************************************************/ _fx_system_timer_entry(ULONG id)72VOID _fx_system_timer_entry(ULONG id) 73 { 74 75 UINT second; 76 UINT minute; 77 UINT hour; 78 UINT day; 79 UINT month; 80 UINT year; 81 82 83 /* Determine if the ID is valid. */ 84 if (id == FX_TIMER_ID) 85 { 86 87 /* Break the current date time into separate fields for easier work! */ 88 second = (_fx_system_time & FX_SECOND_MASK) * 2; 89 minute = (_fx_system_time >> FX_MINUTE_SHIFT) & FX_MINUTE_MASK; 90 hour = (_fx_system_time >> FX_HOUR_SHIFT) & FX_HOUR_MASK; 91 day = _fx_system_date & FX_DAY_MASK; 92 month = (_fx_system_date >> FX_MONTH_SHIFT) & FX_MONTH_MASK; 93 year = ((_fx_system_date >> FX_YEAR_SHIFT) & FX_YEAR_MASK) + FX_BASE_YEAR; 94 95 /* Now apply the "second" update. */ 96 second = second + FX_UPDATE_RATE_IN_SECONDS; 97 98 /* Determine if we need to adjust the minute field. */ 99 if (second > FX_MAXIMUM_SECOND) 100 { 101 102 /* Yes, we need to adjust the minute field. */ 103 minute = minute + second / 60; 104 second = second % 60; 105 106 /* Determine if we need to adjust the hour field. */ 107 if (minute > FX_MAXIMUM_MINUTE) 108 { 109 110 /* Yes, we need to adjust the hour field. */ 111 hour = hour + minute / 60; 112 minute = minute % 60; 113 114 /* Determine if we need to adjust the day field. */ 115 if (hour > FX_MAXIMUM_HOUR) 116 { 117 118 /* Yes, we need to adjust the day field. */ 119 hour = 0; 120 day++; 121 122 /* Determine if we need to adjust the month field. */ 123 switch (month) 124 { 125 126 case 1: /* January */ 127 { 128 129 /* Check for end of the month. */ 130 if (day > 31) 131 { 132 133 /* Move to next month. */ 134 day = 1; 135 month++; 136 } 137 break; 138 } 139 140 case 2: /* February */ 141 { 142 143 /* Check for leap year. We don't need to check for leap 144 century her (century years divisible by 400) since 2000 145 is and this FAT format only supports years to 2107. */ 146 if ((year % 4) == 0) 147 { 148 149 /* Leap year in February... check for 29 days 150 instead of 28. */ 151 if (day > 29) 152 { 153 154 /* Adjust the month. */ 155 day = 1; 156 month++; 157 } 158 } 159 else 160 { 161 162 if (day > 28) 163 { 164 165 /* Adjust the month. */ 166 day = 1; 167 month++; 168 } 169 } 170 break; 171 } 172 173 case 3: /* March */ 174 { 175 176 /* Check for end of the month. */ 177 if (day > 31) 178 { 179 180 /* Move to next month. */ 181 day = 1; 182 month++; 183 } 184 break; 185 } 186 187 case 4: /* April */ 188 { 189 190 /* Check for end of the month. */ 191 if (day > 30) 192 { 193 194 /* Move to next month. */ 195 day = 1; 196 month++; 197 } 198 break; 199 } 200 201 case 5: /* May */ 202 { 203 204 /* Check for end of the month. */ 205 if (day > 31) 206 { 207 208 /* Move to next month. */ 209 day = 1; 210 month++; 211 } 212 break; 213 } 214 215 case 6: /* June */ 216 { 217 218 /* Check for end of the month. */ 219 if (day > 30) 220 { 221 222 /* Move to next month. */ 223 day = 1; 224 month++; 225 } 226 break; 227 } 228 229 case 7: /* July */ 230 { 231 232 /* Check for end of the month. */ 233 if (day > 31) 234 { 235 236 /* Move to next month. */ 237 day = 1; 238 month++; 239 } 240 break; 241 } 242 243 case 8: /* August */ 244 { 245 246 /* Check for end of the month. */ 247 if (day > 31) 248 { 249 250 /* Move to next month. */ 251 day = 1; 252 month++; 253 } 254 break; 255 } 256 257 case 9: /* September */ 258 { 259 260 /* Check for end of the month. */ 261 if (day > 30) 262 { 263 264 /* Move to next month. */ 265 day = 1; 266 month++; 267 } 268 break; 269 } 270 271 case 10: /* October */ 272 { 273 274 /* Check for end of the month. */ 275 if (day > 31) 276 { 277 278 /* Move to next month. */ 279 day = 1; 280 month++; 281 } 282 break; 283 } 284 285 case 11: /* November */ 286 { 287 288 /* Check for end of the month. */ 289 if (day > 30) 290 { 291 292 /* Move to next month. */ 293 day = 1; 294 month++; 295 } 296 break; 297 } 298 299 case 12: /* December */ 300 { 301 302 /* Check for end of the month. */ 303 if (day > 31) 304 { 305 306 /* Move to next month. */ 307 day = 1; 308 month = 1; 309 310 /* Also move to next year. */ 311 year++; 312 313 /* Check for a year that exceeds the representation 314 in this format. */ 315 if (year > FX_MAXIMUM_YEAR) 316 { 317 return; 318 } 319 } 320 break; 321 } 322 323 default: /* Invalid month! */ 324 325 return; /* Skip updating date/time! */ 326 } 327 } 328 } 329 } 330 331 /* Now apply the new setting to the internal representation. */ 332 333 /* Set the system date. */ 334 _fx_system_date = ((year - FX_BASE_YEAR) << FX_YEAR_SHIFT) | 335 (month << FX_MONTH_SHIFT) | day; 336 337 /* Set the new system time. */ 338 _fx_system_time = (hour << FX_HOUR_SHIFT) | 339 (minute << FX_MINUTE_SHIFT) | (second / 2); 340 } 341 } 342 343