#include <inttypes.h>
#include "util.h"
uint8_t frombcd(uint8_t x) {
return _frombcd(x);
}
uint8_t month_length(uint8_t m, uint8_t leap) {
uint8_t knuckle = m < 8 ? (m & 1) == 1 : (m & 1) == 0;
return knuckle ? 31 : m != 2 ? 30 : leap ? 29 : 28;
}
uint8_t days_in_month_bcd(uint8_t year, uint8_t month) {
uint8_t y = frombcd(year);//(year & 7) + ((year & 070)>>3) * 10;
uint8_t m = frombcd(month);//(month & 7) + ((month & 070)>>3) * 10;
uint8_t leap = y % 4 == 0; // non y2k1-compliant, but should be correct for the next 91 years or so :)
uint8_t knuckle = m < 8 ? (m & 1) == 1 : (m & 1) == 0;
return knuckle ? 0x31 : m != 2 ? 0x30 : leap ? 0x29 : 0x28;
}
uint8_t bcd_increment(uint8_t x) {
x++;
if ((x & 0x0f) >= 0x0a)
x += 0x10 - 0x0a;
if (x >= 0xa0)
x = 0;
return x;
}
uint8_t day_of_week(uint8_t y, uint8_t m, uint8_t d) {
uint8_t leap = y % 4 == 0;
uint16_t centurydays = 6 + y * 365 + (y + 3) / 4; // year 2000 started on Saturday
for (; --m >= 1; ) {
centurydays += month_length(m, leap);
}
centurydays += d - 1;
return (centurydays % 7);
}
uint16_t tobcd16(uint16_t x) {
uint16_t y;
y = x % 10; x /= 10;
y |= (x % 10) << 4; x /= 10;
y |= (x % 100) << 8; x /= 10;
y |= 0xf000;
return y;
}