luxos/Kernel/drivers/cmos/cmos.c

64 lines
2.7 KiB
C

#include <time.h>
#include <stdio.h>
#include "cmos.h"
uint8 CmosRead (uint8 address)
{
outportb(0x70, address); iowait();
return inportb(0x71);
}
void CmosWrite (uint8 address, uint8 val)
{
outportb(0x70, address); iowait();
outportb(0x71, val);
}
void CmosSetRTC (const Time* time)
{
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
unsigned char ampm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
uint8 year = time->Year % 100;
uint8 century = time->Year / 100;
CmosWrite (0, (BCD) ? (time->Second%10) | (time->Second/10*16) : time->Second); // Seconds
CmosWrite (2, (BCD) ? (time->Minute%10) | (time->Minute/10*16) : time->Minute); // Minutes
if (ampm && time->Hour > 12) // Hours
CmosWrite (4, (BCD) ? (((time->Hour - 12) % 10) | ((time->Hour - 12)/10*16) | 0x80) : (time->Hour | 0x80) );
else if (ampm && time->Hour == 0) // Midnight convention: 12 PM = 00:00
CmosWrite (4, (BCD) ? 0x92 : 0x8C);
else CmosWrite (4, (BCD) ? (time->Hour%10) | (time->Hour/10*16) : time->Hour); // 24h / AM
CmosWrite (7, (BCD) ? (time->Day%10) | (time->Day/10*16) : time->Day); // Day
CmosWrite (8, (BCD) ? (time->Month%10) | (time->Month/10*16) : time->Month); // Month
CmosWrite (9, (BCD) ? (year%10) | (year/10*16) : year); // Year
CmosWrite (0x32, (BCD) ? (century%10) | (century/10*16) : century); // Century
}
void CmosGetRTC(Time* tim)
{
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
unsigned char am_pm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
tim->Second = (BCD) ? (CmosRead(0x00)%16) + 10*(CmosRead(0x00)/16): CmosRead(0x00);
tim->Minute = (BCD) ? (CmosRead(0x02)%16) + 10*(CmosRead(0x02)/16): CmosRead(0x02);
// Time is PM
if (am_pm && (CmosRead(0x04)&80)) {
tim->Hour = (BCD) ? ((CmosRead(0x04)-0x80)%16) + 10*((CmosRead(0x04)-0x80)/16): CmosRead(0x04)-0x80;
tim->Hour += 12;
}
// 24Hour format, or AM
else tim->Hour = (BCD) ? (CmosRead(0x04)%16) + 10*(CmosRead(0x04)/16): CmosRead(0x04);
tim->WeekDay = (BCD) ? (CmosRead(0x06)%16) + 10*(CmosRead(0x06)/16): CmosRead(0x06);
tim->Day = (BCD) ? (CmosRead(0x07)%16) + 10*(CmosRead(0x07)/16): CmosRead(0x07);
tim->Month = (BCD) ? (CmosRead(0x08)%16) + 10*(CmosRead(0x08)/16): CmosRead(0x08);
tim->Year = (BCD) ? (CmosRead(0x09)%16) + 10*(CmosRead(0x09)/16): CmosRead(0x09);
tim->Year += 100 * ((BCD) ? (CmosRead(0x32)%16) + 10*(CmosRead(0x32)/16): CmosRead(0x32));
}