68 lines
2.3 KiB
C
68 lines
2.3 KiB
C
#include <kernel/cmos.h>
|
|
|
|
int _check_update_in_progress(void) {
|
|
unsigned char ret_val = 0;
|
|
__asm__ volatile("mov $0x0A, %%al\n\t" "outb %%al, $0x70\n\t" "inb $0x71, %%al\n\t" "mov %%al, %0":"=b" (ret_val)::"%al");
|
|
return ret_val;
|
|
}
|
|
|
|
unsigned char _get_rtc_reg(unsigned char reg) {
|
|
unsigned char ret_val = 0;
|
|
__asm__ volatile("mov %1, %%al\n\t" "outb %%al, $0x70\n\t" "inb $0x71, %%al\n\t" "mov %%al, %0":"=b" (ret_val):"c" (reg):"%al");
|
|
return ret_val;
|
|
}
|
|
|
|
unsigned long int read_rtc() {
|
|
unsigned char regb;
|
|
unsigned long int ret_val;
|
|
|
|
/* I might need to add this check back in, but it's fine for now. */
|
|
/* while(_check_update_in_progress()); */
|
|
|
|
cur_time.second = _get_rtc_reg(0x00);
|
|
cur_time.minute = _get_rtc_reg(0x02);
|
|
cur_time.hour = _get_rtc_reg(0x04);
|
|
cur_time.day = _get_rtc_reg(0x07);
|
|
cur_time.month = _get_rtc_reg(0x08);
|
|
cur_time.year = _get_rtc_reg(0x09);
|
|
|
|
regb = _get_rtc_reg(0x0B);
|
|
|
|
/* Convert bcd to binary if needed */
|
|
if(!(regb & 0x04)) {
|
|
cur_time.second = (cur_time.second & 0x0F) + ((cur_time.second / 16) * 10);
|
|
cur_time.minute = (cur_time.minute & 0x0F) + ((cur_time.minute / 16) * 10);
|
|
cur_time.hour = ((cur_time.hour & 0x0F) + (((cur_time.hour & 0x70) / 16) * 10)) | (cur_time.hour & 0x80);
|
|
cur_time.day = (cur_time.day & 0x0F) + ((cur_time.day / 16) * 10);
|
|
cur_time.month = (cur_time.month & 0x0F) + ((cur_time.month / 16) * 10);
|
|
cur_time.year = (cur_time.year & 0x0F) + ((cur_time.year / 16) * 10);
|
|
}
|
|
|
|
/* Convert to 24H time if needed */
|
|
if(!(regb & 0x02) && (cur_time.hour & 0x80)) {
|
|
cur_time.hour = ((cur_time.hour & 0x7F) + 12) % 24;
|
|
}
|
|
|
|
/* Get year. TODO: Use century register for this. */
|
|
cur_time.year += (RELEASE_YEAR / 100) * 100; /* Add century of release year */
|
|
if(cur_time.year < RELEASE_YEAR) cur_time.year += 100;
|
|
|
|
ret_val = cur_time.second;
|
|
ret_val += cur_time.minute * 60;
|
|
ret_val += cur_time.hour * 3600;
|
|
unsigned int tot_days = cur_time.day;
|
|
unsigned char month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
|
for(unsigned int i = 1970; i < cur_time.year; i++) {
|
|
if(i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) {
|
|
tot_days += 366;
|
|
}
|
|
else {
|
|
tot_days += 365;
|
|
}
|
|
}
|
|
for(int i = 0; i < (cur_time.month - 1); i++) {
|
|
tot_days += month_days[i];
|
|
}
|
|
ret_val += tot_days * 86400;
|
|
return ret_val;
|
|
}
|