CTAOS v5
This commit is contained in:
@ -1,92 +1,81 @@
|
||||
/***** cmos.c ********************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. Glory To God *
|
||||
* *
|
||||
* CMOS I/O Routines *
|
||||
* ================= *
|
||||
* *
|
||||
* ! IMPORTANT NOTE ! Close interrupts before any CMOS operation *
|
||||
************************************************************ cta os */
|
||||
|
||||
#include <system.h>
|
||||
#include <time.h>
|
||||
#include "cmos.h"
|
||||
|
||||
volatile byte i86_cmos_data[128];
|
||||
|
||||
void i86_cmos_write ()
|
||||
/*****************************************************************
|
||||
* !!!!!!!!!! IMPORTANT NOTE !!!!!!!!!! *
|
||||
* You should close interrupts before any CMOS operation. *
|
||||
*****************************************************************/
|
||||
inline unsigned char i86_cmos_read (unsigned char address)
|
||||
{
|
||||
byte i;
|
||||
for (i = 0; i < 128; i++) {
|
||||
//asm volatile ("cli");
|
||||
outportb(0x70, i);
|
||||
iowait();
|
||||
outportb(0x71, i86_cmos_data[i]);
|
||||
//asm volatile ("sti");
|
||||
}
|
||||
outportb(0x70, address); iowait();
|
||||
return inportb(0x71);
|
||||
}
|
||||
|
||||
void i86_cmos_read ()
|
||||
inline void i86_cmos_write (unsigned char address, unsigned char val)
|
||||
{
|
||||
byte i;
|
||||
for (i = 0; i < 128; i++) {
|
||||
//asm volatile ("cli");
|
||||
outportb(0x70, i);
|
||||
iowait();
|
||||
i86_cmos_data[i] = inportb(0x71);
|
||||
//asm volatile ("sti");
|
||||
}
|
||||
outportb(0x70, address); iowait();
|
||||
outportb(0x71, val);
|
||||
}
|
||||
|
||||
void i86_cmos_write_clock (const TIME* time)
|
||||
{
|
||||
unsigned char BCD = ((i86_cmos_read(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char ampm = ((i86_cmos_read(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
i86_cmos_write (0, (BCD) ? (time->second%10) | (time->second/10*16) : time->second); // Seconds
|
||||
i86_cmos_write (2, (BCD) ? (time->minute%10) | (time->minute/10*16) : time->minute); // Minutes
|
||||
|
||||
if (ampm && time->hour > 12) // Hours
|
||||
i86_cmos_write (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
|
||||
i86_cmos_write (4, (BCD) ? 0x92 : 0x8C);
|
||||
|
||||
else i86_cmos_write (4, (BCD) ? (time->hour%10) | (time->hour/10*16) : time->hour); // 24h / AM
|
||||
|
||||
i86_cmos_write (6, (BCD) ? (time->weekday%10) | (time->weekday/10*16) : time->weekday); // Weekday
|
||||
i86_cmos_write (7, (BCD) ? (time->day%10) | (time->day/10*16) : time->day); // Day
|
||||
i86_cmos_write (8, (BCD) ? (time->month%10) | (time->month/10*16) : time->month); // Month
|
||||
i86_cmos_write (9, (BCD) ? (time->year%10) | (time->year/10*16) : time->year); // Year
|
||||
i86_cmos_write (0x32, (BCD) ? (time->century%10) | (time->century/10*16) : time->century); // Century
|
||||
}
|
||||
|
||||
void i86_cmos_read_clock(TIME* tim)
|
||||
{
|
||||
i86_cmos_read();
|
||||
unsigned char BCD = ((i86_cmos_read(0x0b)&4)==0) ? 1 : 0;
|
||||
unsigned char am_pm = ((i86_cmos_read(0x0b)&2)==0) ? 1 : 0;
|
||||
|
||||
if ((i86_cmos_data[0x0b]&4)==0) // BCD = true;
|
||||
{
|
||||
tim->seconds = (i86_cmos_data[0x00]%16) + 10*(i86_cmos_data[0x00]/16);
|
||||
tim->minutes = (i86_cmos_data[0x02]%16) + 10*(i86_cmos_data[0x02]/16);
|
||||
if ((i86_cmos_data[0x0b]&2)==0) { // AM/PM
|
||||
if (i86_cmos_data[0x04]&80) { // pm
|
||||
tim->hours = ((i86_cmos_data[0x04]-0x80)%16) + 10*((i86_cmos_data[0x04]-0x80)/16);
|
||||
tim->am_pm = 1;
|
||||
}
|
||||
else { // am
|
||||
tim->hours = (i86_cmos_data[0x04]%16) + 10*(i86_cmos_data[0x04]/16);
|
||||
tim->am_pm = 0;
|
||||
}
|
||||
}
|
||||
else { // 24 hours
|
||||
tim->hours = (i86_cmos_data[0x04]%16) + 10*(i86_cmos_data[0x04]/16);
|
||||
if (tim->hours > 12) {
|
||||
tim->am_pm = 1;
|
||||
tim->hours -= 12;
|
||||
}
|
||||
else tim->am_pm = 0;
|
||||
}
|
||||
tim->second = (BCD) ? (i86_cmos_read(0x00)%16) + 10*(i86_cmos_read(0x00)/16): i86_cmos_read(0x00);
|
||||
tim->minute = (BCD) ? (i86_cmos_read(0x02)%16) + 10*(i86_cmos_read(0x02)/16): i86_cmos_read(0x02);
|
||||
|
||||
tim->weekday = (i86_cmos_data[0x06]%16) + 10*(i86_cmos_data[0x06]/16);
|
||||
tim->day = (i86_cmos_data[0x07]%16) + 10*(i86_cmos_data[0x07]/16);
|
||||
tim->month = (i86_cmos_data[0x08]%16) + 10*(i86_cmos_data[0x08]/16);
|
||||
tim->year = (i86_cmos_data[0x09]%16) + 10*(i86_cmos_data[0x09]/16);
|
||||
tim->century = (i86_cmos_data[0x32]%16) + 10*(i86_cmos_data[0x32]/16);
|
||||
}
|
||||
|
||||
else {//BCD = false;
|
||||
tim->seconds = i86_cmos_data[0x00];
|
||||
tim->minutes = i86_cmos_data[0x02];
|
||||
if ((i86_cmos_data[0x0b]&2)==0) { // AM/PM
|
||||
if (i86_cmos_data[0x04]&80) { // pm
|
||||
tim->hours = i86_cmos_data[0x04]-0x80;
|
||||
tim->am_pm = 1;
|
||||
}
|
||||
else { // am
|
||||
tim->hours = i86_cmos_data[0x04];
|
||||
tim->am_pm = 0;
|
||||
}
|
||||
}
|
||||
else { // 24 hours
|
||||
tim->hours = i86_cmos_data[0x02];
|
||||
if (tim->hours > 12) {
|
||||
tim->am_pm = 1;
|
||||
tim->hours -= 12;
|
||||
}
|
||||
else tim->am_pm = 0;
|
||||
}
|
||||
tim->weekday = i86_cmos_data[0x06];
|
||||
tim->day = i86_cmos_data[0x07];
|
||||
tim->month = i86_cmos_data[0x08];
|
||||
tim->year = i86_cmos_data[0x09];
|
||||
tim->century = i86_cmos_data[0x32];
|
||||
// Time is PM
|
||||
if (am_pm && i86_cmos_read(0x04)&80) {
|
||||
tim->hour = (BCD) ? ((i86_cmos_read(0x04)-0x80)%16) + 10*((i86_cmos_read(0x04)-0x80)/16): i86_cmos_read(0x04)-0x80;
|
||||
tim->hour += 12;
|
||||
}
|
||||
// 24Hour format, or AM
|
||||
else tim->hour = (BCD) ? (i86_cmos_read(0x04)%16) + 10*(i86_cmos_read(0x04)/16): i86_cmos_read(0x04);
|
||||
|
||||
tim->weekday = (BCD) ? (i86_cmos_read(0x06)%16) + 10*(i86_cmos_read(0x06)/16): i86_cmos_read(0x06);
|
||||
tim->day = (BCD) ? (i86_cmos_read(0x07)%16) + 10*(i86_cmos_read(0x07)/16): i86_cmos_read(0x07);
|
||||
tim->month = (BCD) ? (i86_cmos_read(0x08)%16) + 10*(i86_cmos_read(0x08)/16): i86_cmos_read(0x08);
|
||||
tim->year = (BCD) ? (i86_cmos_read(0x09)%16) + 10*(i86_cmos_read(0x09)/16): i86_cmos_read(0x09);
|
||||
tim->century = (BCD) ? (i86_cmos_read(0x32)%16) + 10*(i86_cmos_read(0x32)/16): i86_cmos_read(0x32);
|
||||
}
|
||||
|
||||
|
||||
unsigned char i86_cmos_read_floppy_drives ()
|
||||
{
|
||||
outportb (0x70, 0x10);
|
||||
return inportb(0x71);
|
||||
}
|
@ -1,10 +1,17 @@
|
||||
/***** cmos.h ********************************************************
|
||||
* (c) 2010 CTA Systems Inc. All rights reserved. *
|
||||
* *
|
||||
* CMOS I/O Routines *
|
||||
* ================= *
|
||||
* *
|
||||
* ! IMPORTANT NOTE ! Close interrupts before any CMOS operation *
|
||||
************************************************************ cta os */
|
||||
|
||||
#ifndef __CMOS_H
|
||||
#define __CMOS_H
|
||||
|
||||
extern volatile byte i86_cmos_data[128];
|
||||
|
||||
extern void i86_cmos_write ();
|
||||
extern void i86_cmos_read ();
|
||||
extern void i86_cmos_write_clock (const TIME* time);
|
||||
extern void i86_cmos_read_clock (TIME *tim);
|
||||
extern unsigned char i86_cmos_read_floppy_drives ();
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user