CTAOS v6
This commit is contained in:
20
SysCore/drivers/clock/clock.h
Normal file
20
SysCore/drivers/clock/clock.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __PIT_H
|
||||
#define __PIT_H
|
||||
|
||||
#include <regs.h>
|
||||
#include <time.h>
|
||||
|
||||
extern void i86_PitHandler(ISR_stack_regs *r);
|
||||
extern void i86_PitInitialize(int freq);
|
||||
extern unsigned char PitIsInitialized();
|
||||
extern void PitSetFrequency(int frequency);
|
||||
extern unsigned int PitGetFrequency();
|
||||
|
||||
extern TIME ClockGetTime();
|
||||
extern unsigned int ClockSetTickCount(unsigned int i);
|
||||
extern unsigned int ClockGetTickCount();
|
||||
|
||||
extern void i86_SetRTC (const TIME* time);
|
||||
extern void i86_GetRTC(TIME* tim);
|
||||
|
||||
#endif
|
120
SysCore/drivers/clock/pit.c
Normal file
120
SysCore/drivers/clock/pit.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <system.h>
|
||||
#include <time.h>
|
||||
#include "clock.h"
|
||||
|
||||
volatile unsigned int ClockTicks = 0;
|
||||
volatile unsigned int ClockFrequency = 0;
|
||||
unsigned char PitInitialized = 0;
|
||||
volatile TIME _InternalClock;
|
||||
|
||||
|
||||
void PitSetFrequency(int frequency)
|
||||
{
|
||||
int divisor = 1193180/frequency; // Calculate the divisor
|
||||
outportb(0x43, 0x36); // Set our command byte 0x36
|
||||
outportb(0x40, divisor&0xFF); // Set low byte
|
||||
outportb(0x40, divisor>>8); // Set high byte
|
||||
ClockFrequency = frequency;
|
||||
}
|
||||
|
||||
void i86_PitHandler(ISR_stack_regs *r)
|
||||
{
|
||||
ClockTicks++; // count tick
|
||||
if (ClockTicks % ClockFrequency == 0)
|
||||
_CLOCK_INC((TIME*)&_InternalClock); // update internal clock
|
||||
}
|
||||
|
||||
unsigned int ClockSetTickCount(unsigned int i)
|
||||
{
|
||||
unsigned int r = ClockTicks;
|
||||
ClockTicks = i;
|
||||
return r;
|
||||
}
|
||||
|
||||
unsigned int ClockGetTickCount()
|
||||
{
|
||||
return ClockTicks;
|
||||
}
|
||||
unsigned int PitGetFrequency()
|
||||
{
|
||||
return ClockFrequency;
|
||||
}
|
||||
|
||||
void i86_PitInitialize(int freq)
|
||||
{
|
||||
PitSetFrequency(freq);
|
||||
ClockTicks = 0;
|
||||
|
||||
i86_GetRTC((TIME*) &_InternalClock);
|
||||
|
||||
PitInitialized = 1;
|
||||
}
|
||||
|
||||
TIME ClockGetTime()
|
||||
{
|
||||
return _InternalClock;
|
||||
}
|
||||
|
||||
unsigned char PitIsInitialized()
|
||||
{
|
||||
return PitInitialized;
|
||||
}
|
||||
|
||||
|
||||
inline unsigned char CmosRead (unsigned char address)
|
||||
{
|
||||
outportb(0x70, address); iowait();
|
||||
return inportb(0x71);
|
||||
}
|
||||
|
||||
inline void CmosWrite (unsigned char address, unsigned char val)
|
||||
{
|
||||
outportb(0x70, address); iowait();
|
||||
outportb(0x71, val);
|
||||
}
|
||||
|
||||
void i86_SetRTC (const TIME* time)
|
||||
{
|
||||
unsigned char BCD = ((CmosRead(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char ampm = ((CmosRead(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
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 (6, (BCD) ? (time->weekday%10) | (time->weekday/10*16) : time->weekday); // Weekday
|
||||
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) ? (time->year%10) | (time->year/10*16) : time->year); // Year
|
||||
CmosWrite (0x32, (BCD) ? (time->century%10) | (time->century/10*16) : time->century); // Century
|
||||
}
|
||||
|
||||
void i86_GetRTC(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->century = (BCD) ? (CmosRead(0x32)%16) + 10*(CmosRead(0x32)/16): CmosRead(0x32);
|
||||
}
|
Reference in New Issue
Block a user