mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-28 08:16:31 +00:00
7c6a2037d8
Changed DVD Resolution in DoDistro to 1024x768. Kernel files reformatted: Display.CC, EdLite.CC, FunSeg.CC, Job.CC, KConfig.CC, KDataTypes.CC, KDate.CC, KDebug.CC, KDefine.CC, KExcept.CC, KExterns.CC, KGlobals.CC, KHashA.CC, KHashB.CC, KInterrupts.CC, KLoad.CC, KMain.CC, KStart16.CC, KStart32.CC.
240 lines
5.3 KiB
HolyC
Executable file
240 lines
5.3 KiB
HolyC
Executable file
//See $LK,"::/Doc/TimeDate.DD"$
|
|
|
|
U16 month_start_days[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
|
U16 month_start_days_leap[12] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
|
|
|
|
I64 YearStartDate(I64 year)
|
|
{//32-bit day since AD 0, given year number.
|
|
I64 y1 = year - 1, yd4000 = y1 / 4000, yd400 = y1 / 400, yd100 = y1 / 100, yd4 = y1 / 4;
|
|
|
|
return year * 365 + yd4 - yd100 + yd400 - yd4000;
|
|
}
|
|
|
|
CDate Struct2Date(CDateStruct *_ds)
|
|
{//Convert CDateStruct to CDate.
|
|
CDate cdt;
|
|
I64 i1, i2;
|
|
|
|
i1 = YearStartDate(_ds->year);
|
|
i2 = YearStartDate(_ds->year + 1);
|
|
if (i2 - i1 == 365)
|
|
i1 += month_start_days[_ds->mon - 1];
|
|
else
|
|
i1 += month_start_days_leap[_ds->mon - 1];
|
|
cdt.date = i1 + _ds->day_of_mon - 1;
|
|
cdt.time = (_ds->sec10000 + 100 * (_ds->sec100 + 100 * (_ds->sec + 60 * (_ds->min + 60 * _ds->hour))))
|
|
<< 21 / (15 * 15 * 3 * 625);
|
|
return cdt;
|
|
}
|
|
|
|
I64 DayOfWeek(I64 i)
|
|
{//Day of week, given 32-bit day since AD 0.
|
|
i += CDATE_BASE_DAY_OF_WEEK;
|
|
if (i >= 0)
|
|
return i % 7;
|
|
else
|
|
return 6 - (6 - i) % 7;
|
|
}
|
|
|
|
U0 Date2Struct(CDateStruct *_ds, CDate cdt)
|
|
{//Convert CDate to CDateStruct.
|
|
I64 i, k, date = cdt.date;
|
|
|
|
_ds->day_of_week = DayOfWeek(date);
|
|
_ds->year = (date + 1) * 100000 / CDATE_YEAR_DAYS_INT;
|
|
i = YearStartDate(_ds->year);
|
|
|
|
while (i > date)
|
|
{
|
|
_ds->year--;
|
|
i = YearStartDate(_ds->year);
|
|
}
|
|
date -= i;
|
|
if (YearStartDate(_ds->year + 1) - i == 365)
|
|
{
|
|
k = 0;
|
|
while (date >= month_start_days[k + 1] && k < 11)
|
|
k++;
|
|
date -= month_start_days[k];
|
|
}
|
|
else
|
|
{
|
|
k = 0;
|
|
while (date >= month_start_days_leap[k + 1] && k < 11)
|
|
k++;
|
|
date -= month_start_days_leap[k];
|
|
}
|
|
_ds->mon = k + 1;
|
|
_ds->day_of_mon = date + 1;
|
|
k = (625 * 15 * 15 * 3 * cdt.time) >> 21 + 1;
|
|
_ds->sec10000 = ModU64(&k, 100);
|
|
_ds->sec100 = ModU64(&k, 100);
|
|
_ds->sec = ModU64(&k, 60);
|
|
_ds->min = ModU64(&k, 60);
|
|
_ds->hour = k;
|
|
}
|
|
|
|
I64 FirstDayOfMon(I64 i)
|
|
{//First day of month, given 32-bit day since AD 0.
|
|
CDateStruct ds;
|
|
CDate cdt = 0;
|
|
|
|
cdt.date = i;
|
|
Date2Struct(&ds, cdt);
|
|
ds.day_of_mon = 1;
|
|
cdt = Struct2Date(&ds);
|
|
return cdt.date;
|
|
}
|
|
|
|
I64 LastDayOfMon(I64 i)
|
|
{//Last day of month, given 32-bit day since AD 0.
|
|
CDateStruct ds;
|
|
CDate cdt = 0;
|
|
|
|
cdt.date = i;
|
|
Date2Struct(&ds, cdt);
|
|
ds.mon++;
|
|
if (ds.mon == 13)
|
|
{
|
|
ds.mon = 0;
|
|
ds.year++;
|
|
}
|
|
ds.day_of_mon = 1;
|
|
cdt = Struct2Date(&ds);
|
|
return cdt.date - 1;
|
|
}
|
|
|
|
I64 FirstDayOfYear(I64 i)
|
|
{//First day of year, given 32-bit day since AD 0.
|
|
CDateStruct ds;
|
|
CDate cdt = 0;
|
|
|
|
cdt.date = i;
|
|
Date2Struct(&ds, cdt);
|
|
ds.day_of_mon = 1;
|
|
ds.mon = 1;
|
|
cdt = Struct2Date(&ds);
|
|
return cdt.date;
|
|
}
|
|
|
|
I64 LastDayOfYear(I64 i)
|
|
{//Last day of year, given 32-bit day since AD 0.
|
|
CDateStruct ds;
|
|
CDate cdt = 0;
|
|
|
|
cdt.date = i;
|
|
Date2Struct(&ds, cdt);
|
|
ds.day_of_mon = 1;
|
|
ds.mon = 1;
|
|
ds.year++;
|
|
cdt = Struct2Date(&ds);
|
|
return cdt.date - 1;
|
|
}
|
|
|
|
U8 CMOSRegRead(I64 register)
|
|
{//Read val from CMOS register. See $LK,"CMOS Registers",A="MN:CMOSR_SEC"$.
|
|
OutU8(CMOS_SEL, register);
|
|
return InU8(CMOS_DATA);
|
|
}
|
|
|
|
U0 CMOSRegWrite(I64 register, I64 val)
|
|
{//Write val to CMOS register. See $LK,"CMOS Registers",A="MN:CMOSR_SEC"$.
|
|
OutU8(CMOS_SEL, register);
|
|
OutU8(CMOS_DATA, val);
|
|
}
|
|
|
|
Bool CMOSIsBcd()
|
|
{//Check of CMOS is in binary-coded decimal mode.
|
|
// Ex: 15:32:44 == 0x15:0x32:0x44 (not good). We use $LK,"Bcd2Binary",A="MN:Bcd2Binary"$() to convert.
|
|
return !(CMOSRegRead(CMOSR_STATUS_B) & CMOSF_BINARY);
|
|
}
|
|
|
|
I64 Bcd2Binary(U64 b)
|
|
{
|
|
I64 i, res = 0;
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
res = res * 10 + b >> 60;
|
|
b <<= 4;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
U0 NowDateTimeStruct(CDateStruct *_ds)
|
|
{
|
|
I64 i;
|
|
U8 *b = _ds;
|
|
|
|
MemSet(_ds, 0, sizeof(CDateStruct));
|
|
PUSHFD
|
|
CLI
|
|
while (LBts(&sys_semas[SEMA_SYS_DATE], 0))
|
|
PAUSE
|
|
|
|
do
|
|
{
|
|
while (CMOSRegRead(CMOSR_STATUS_A) & CMOSF_UPDATING)
|
|
PAUSE
|
|
|
|
b[2] = CMOSRegRead(CMOSR_SEC);
|
|
b[3] = CMOSRegRead(CMOSR_MIN);
|
|
b[4] = CMOSRegRead(CMOSR_HOUR);
|
|
b[5] = CMOSRegRead(CMOSR_DAY_OF_WEEK);
|
|
b[6] = CMOSRegRead(CMOSR_DAY_OF_MONTH);
|
|
b[7] = CMOSRegRead(CMOSR_MONTH);
|
|
b[8] = CMOSRegRead(CMOSR_YEAR);
|
|
|
|
}
|
|
while (CMOSRegRead(CMOSR_STATUS_A) & CMOSF_UPDATING);
|
|
|
|
LBtr(&sys_semas[SEMA_SYS_DATE], 0);
|
|
POPFD
|
|
if (CMOSIsBcd)
|
|
for (i = 2; i < 9; i++)
|
|
b[i] = Bcd2Binary(b[i]);
|
|
|
|
if (_ds->year > 255) _ds->year = 255;
|
|
_ds->year += 2000;
|
|
|
|
if (_ds->mon > 12) _ds->mon = 12;
|
|
if (_ds->day_of_mon > 31) _ds->day_of_mon = 31;
|
|
if (_ds->day_of_week > 6) _ds->day_of_week = 6;
|
|
if (_ds->hour > 23) _ds->hour = 23;
|
|
if (_ds->min > 59) _ds->min = 59;
|
|
if (_ds->sec > 59) _ds->sec = 59;
|
|
}
|
|
|
|
CDate Now()
|
|
{//Current datetime.
|
|
CDateStruct ds;
|
|
|
|
NowDateTimeStruct(&ds);
|
|
return Struct2Date(&ds)-local_time_offset;
|
|
}
|
|
|
|
U0 TimeSet(CDateStruct *ds)
|
|
{//Set CMOS time from user crafted $LK,"CDateStruct",A="MN:CDateStruct"$.
|
|
//$BK,1$Make sure to use hex as decimals if BCD mode.$BK,0$ Check using $LK,"CMOSIsBcd",A="MN:CMOSIsBcd"$().
|
|
//Ex: if bcd mode and we want 12/30, 10:45:15 -- 0x12/0x30, 0x10:0x45:0x15.
|
|
//Pass year as double digit number (obviously 20XX is too big for a U8).
|
|
U8 *b = ds;
|
|
|
|
PUSHFD
|
|
CLI
|
|
while (LBts(&sys_semas[SEMA_SYS_DATE], 0))
|
|
PAUSE
|
|
|
|
while (CMOSRegRead(CMOSR_STATUS_A) & CMOSF_UPDATING)
|
|
PAUSE
|
|
|
|
CMOSRegWrite(CMOSR_SEC, b[2]);
|
|
CMOSRegWrite(CMOSR_MIN, b[3]);
|
|
CMOSRegWrite(CMOSR_HOUR, b[4]);
|
|
CMOSRegWrite(CMOSR_DAY_OF_WEEK, b[5]);
|
|
CMOSRegWrite(CMOSR_DAY_OF_MONTH, b[6]);
|
|
CMOSRegWrite(CMOSR_MONTH, b[7]);
|
|
CMOSRegWrite(CMOSR_YEAR, b[8]);
|
|
|
|
LBtr(&sys_semas[SEMA_SYS_DATE], 0);
|
|
POPFD
|
|
}
|