8#ifndef PEDIGREE_KERNEL_MACHINE_MACH_PC_RTCCALENDAR_H
9#define PEDIGREE_KERNEL_MACHINE_MACH_PC_RTCCALENDAR_H
11#include "RtcTimeAccounting.h"
13namespace RtcCalendar {
14inline bool validCenturyIndex(uint8_t index) {
15 return index == 0 || (index >= 0x0e && index <= 0x7f);
18inline bool decode(uint8_t raw,
bool binary, uint8_t& value) {
19 if (!binary && ((raw & 15) > 9 || (raw >> 4) > 9)) {
22 value = binary ? raw : (raw >> 4) * 10 + (raw & 15);
26inline uint8_t encode(uint8_t value,
bool binary) {
27 return binary ? value : ((value / 10) << 4) | (value % 10);
31 return time.year >= 1970 && time.year <= 9999 && time.month >= 1 && time.month <= 12 &&
32 time.day >= 1 && time.day <= RtcTimeAccounting::daysInMonth(time.year, time.month) &&
33 time.hour < 24 && time.minute < 60 && time.second < 60;
37template <
typename Read>
39 if (!validCenturyIndex(centuryIndex) || !(readRegister(0x0d) & 0x80)) {
42 const uint8_t status = readRegister(0x0b);
43 const bool binary = status & 4;
44 const bool hours24 = status & 2;
45 const uint8_t rawHour = readRegister(4);
46 uint8_t year = 0, century = 0;
48 if (!decode(readRegister(0), binary, time.second) ||
49 !decode(readRegister(2), binary, time.minute) ||
50 !decode(hours24 ? rawHour : (rawHour & 0x7f), binary, time.hour) ||
51 !decode(readRegister(7), binary, time.day) || !decode(readRegister(8), binary, time.month) ||
52 !decode(readRegister(9), binary, year) || year > 99) {
56 if (time.hour < 1 || time.hour > 12) {
59 time.hour = (time.hour % 12) + ((rawHour & 0x80) ? 12 : 0);
62 if (!decode(readRegister(centuryIndex), binary, century) || century > 99) {
65 time.year = century * 100 + year;
69 time.year = (year >= 70 ? 1900 : 2000) + year;
78template <
typename Read,
typename Write>
79bool write(Read readRegister, Write writeRegister, uint8_t centuryIndex,
81 if (!validCenturyIndex(centuryIndex) || !valid(time) || (!centuryIndex && time.year > 2069)) {
84 const uint8_t status = readRegister(0x0b);
85 const bool binary = status & 4;
86 const bool hours24 = status & 2;
87 uint8_t hour = time.hour;
89 hour = time.hour % 12;
94 const uint8_t rawHour = encode(hour, binary) | ((!hours24 && time.hour >= 12) ? 0x80 : 0);
95 writeRegister(0, encode(time.second, binary));
96 writeRegister(2, encode(time.minute, binary));
97 writeRegister(4, rawHour);
98 writeRegister(7, encode(time.day, binary));
99 writeRegister(8, encode(time.month, binary));
100 writeRegister(9, encode(time.year % 100, binary));
102 writeRegister(centuryIndex, encode(time.year / 100, binary));