quinn-os/rtc.c

112 lines
2.6 KiB
C

#include "io.h"
void rtc_send_byte(unsigned char byte) {
outportb(0x70, byte);
}
unsigned char rtc_get_byte( void ) {
return inportb(0x71);
}
unsigned int rtc_get_dec_from_bcd(unsigned char in) {
unsigned int out;
out = ((in >> 4) & 0xF) * 10;
out += (in & 0xF);
return out;
}
unsigned int get_time_since_epoch(unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec) {
unsigned int new_time;
unsigned int days;
int i;
unsigned int months[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
days = day;
if (year < 70) year += 100;
year += 1900;
for (i = 1970; i<year; i++) {
if (i % 4 != 0) {
days += 365;
} else if (i % 400 == 0) {
days += 366;
} else if (i % 100 == 0) {
days += 365;
} else {
days += 366;
}
}
days += months[mon-1];
if (i % 400 == 0) {
days++;
} else {
days++;
}
new_time = days * 24;
new_time += hour;
new_time *=60;
new_time += min;
new_time *=60;
new_time += sec;
return new_time;
}
unsigned short rtc_get_fat_date(void) {
unsigned int day, mon, year;
unsigned short fatdate = 0;
rtc_send_byte(0x07);
day = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x08);
mon = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x09);
year = rtc_get_dec_from_bcd(rtc_get_byte());
if (year < 80) year += 100;
year -= 80;
fatdate = ((year & 0x7F) << 9) | ((mon & 0xF) << 5) | (day & 0x1F);
return fatdate;
}
unsigned short rtc_get_fat_time(void) {
unsigned int sec, min, hour;
unsigned short fattime = 0;
rtc_send_byte(0x00);
sec = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x02);
min = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x04);
hour = rtc_get_dec_from_bcd(rtc_get_byte());
fattime = ((hour & 0x1F) << 11) | ((min & 0x3F) << 5) | ((sec / 2) & 0x1F);
return fattime;
}
unsigned int rtc_get_time(void) {
unsigned int sec, min, hour, day, mon, year;
rtc_send_byte(0x00);
sec = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x02);
min = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x04);
hour = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x07);
day = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x08);
mon = rtc_get_dec_from_bcd(rtc_get_byte());
rtc_send_byte(0x09);
year = rtc_get_dec_from_bcd(rtc_get_byte());
return get_time_since_epoch(year, mon, day, hour, min, sec);
}