diff options
Diffstat (limited to 'kernel/src/drivers/cmos.c')
-rw-r--r-- | kernel/src/drivers/cmos.c | 138 |
1 files changed, 0 insertions, 138 deletions
diff --git a/kernel/src/drivers/cmos.c b/kernel/src/drivers/cmos.c deleted file mode 100644 index 5ac12c3..0000000 --- a/kernel/src/drivers/cmos.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "print.h" -#include <stdint.h> -#include <sys.h> -#include <time.h> - -#define CMOS_WRITE_PORT 0x70 -#define CMOS_READ_PORT 0x71 - -#define CMOS_REG_SEC 0x00 -#define CMOS_REG_MIN 0x02 -#define CMOS_REG_HOUR 0x04 -#define CMOS_REG_WDAY 0x06 -#define CMOS_REG_MDAY 0x07 -#define CMOS_REG_MON 0x08 -#define CMOS_REG_YEAR 0x09 -#define CMOS_REG_CEN 0x32 - -static struct Time time; -static struct Time localtime; -static int cur_offset = 0; - -static uint8_t cmos_read(uint8_t reg) { - uint8_t hex, ret; - - outb(CMOS_WRITE_PORT, reg); - hex = inb(CMOS_READ_PORT); - - ret = hex & 0x0F; - ret += (hex & 0xF0) / 16 * 10; - - return ret; -} - -static int mday_offset[12] = { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 -}; - -static int month_days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -static void update_localtime(void) { - - int change, max; - - // set localtime - localtime = time; - - // do we acutally need to do anything - if (cur_offset == 0) return; - localtime.hour += cur_offset; - - // check if day rolled over - change = localtime.hour < 0 ? -1 : localtime.hour >= 24 ? 1 : 0; - if (!change) return; - - // roll over day - localtime.hour = (localtime.hour + 24) % 24; - localtime.wday = (localtime.wday + change + 7) % 7; - localtime.mday += change; - localtime.yday += change; - - // check if month rolled over - max = month_days[localtime.mon]; - if (localtime.leap && localtime.mon == 1) max++; - change = localtime.mday < 0 ? -1 : localtime.mday >= max ? 1 : 0; - if (!change) return; - - // roll over month - localtime.mon = (localtime.mon + change + 12) % 12; - - // check if year rolled over - max = localtime.leap ? 366 : 365; - change = localtime.yday < 0 ? -1 : localtime.yday >= max ? 1 : 0; - if (!change) return; - - // roll over year - localtime.yn += change; - - // check if cen rolled over - change = localtime.yn < 0 ? -1 : localtime.yn >= 100 ? 1 : 0; - if (!change) goto year; - - // roll over cen - localtime.cen += change; - - -year: - - localtime.year = localtime.yn + localtime.cen * 100; - localtime.leap = localtime.year % 4 == 0 && localtime.year % 100 != 0; - - if (localtime.leap && localtime.yday == -1) - localtime.yday = 365; - else if (localtime.yday == -1) - localtime.yday = 364; - else - localtime.yday = 0; - - localtime.year -= 1900; - -} - -void rtc_set_timezone(int offset) { - cur_offset = offset; -} - -void rtc_update(void) { - time.sec = cmos_read(CMOS_REG_SEC); - time.min = cmos_read(CMOS_REG_MIN); - time.hour = cmos_read(CMOS_REG_HOUR); - time.wday = cmos_read(CMOS_REG_WDAY) - 1; - time.mday = cmos_read(CMOS_REG_MDAY); - time.mon = cmos_read(CMOS_REG_MON) - 1; - time.yn = cmos_read(CMOS_REG_YEAR); - time.cen = 20; - - time.year = time.yn + time.cen * 100; - - time.leap = time.year % 4 == 0 && time.year % 100 != 0; - - time.yday = mday_offset[time.mon] + time.mday; - - if (time.leap && time.mon > 2) - time.yday++; - - time.year -= 1900; - - update_localtime(); -} - -struct Time *rtc_utctime(void) { - return &time; -} - -struct Time *rtc_localtime(void) { - return &localtime; -} |