199 lines
4.7 KiB
C
199 lines
4.7 KiB
C
/*
|
|
* Copyright (c) 2009 Oliver Lehmann <oliver@FreeBSD.org>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $Id: u130.c,v 1.7 2009/08/12 04:54:25 olivleh1 Exp $
|
|
*/
|
|
|
|
#include <time.h>
|
|
#include "u130.h"
|
|
|
|
int rdvalue();
|
|
int invalue();
|
|
void outvalue();
|
|
long timegm();
|
|
struct tm *gmtime();
|
|
|
|
int
|
|
u130_init()
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
void
|
|
u130_set(time)
|
|
long time;
|
|
{
|
|
struct tm *clktime;
|
|
long time2;
|
|
|
|
time2=time;
|
|
|
|
clktime = gmtime(&time2);
|
|
if(clktime->tm_year > 100)
|
|
clktime->tm_year -= 100;
|
|
clktime->tm_mon ++;
|
|
|
|
outvalue(0x02); /* Datum einstellen */
|
|
outvalue(0x03); /* Korrektur Monat */
|
|
outvalue(0x00);
|
|
while ((invalue(U130MMx1,1) + invalue(U130MM1x,1)*10) != clktime->tm_mon)
|
|
;
|
|
outvalue(0x01); /* Korrektur Zehnerstelle Tag */
|
|
outvalue(0x00);
|
|
while (invalue(U130DD1x,1) != clktime->tm_mday/10)
|
|
;
|
|
outvalue(0x01); /* Korrektur Einerstelle Tag */
|
|
outvalue(0x00);
|
|
while (invalue(U130DDx1,1) != clktime->tm_mday%10)
|
|
;
|
|
outvalue(0x01); /* Korrektur Zehnerstelle Jahr */
|
|
outvalue(0x00);
|
|
while (invalue(U130YY1x,1) != clktime->tm_year/10)
|
|
;
|
|
outvalue(0x01); /* Korrektur Einerstelle Jahr */
|
|
outvalue(0x00);
|
|
while (invalue(U130YYx1,1) != clktime->tm_year%10)
|
|
;
|
|
outvalue(0x02); /* Korrektur Ende */
|
|
outvalue(0x00);
|
|
|
|
outvalue(0x01); /* Zeit stellen */
|
|
outvalue(0x00);
|
|
outvalue(0x02); /* Sekunden auf Null */
|
|
outvalue(0x00);
|
|
outvalue(0x01);
|
|
outvalue(0x00);
|
|
outvalue(0x01); /* Korrektur Stunden */
|
|
outvalue(0x00);
|
|
while ((invalue(U130HHx1,1) + invalue(U130HH1x,1)*10) != clktime->tm_hour)
|
|
;
|
|
outvalue(0x01); /* Korrektur Zehner-Minuten */
|
|
outvalue(0x00);
|
|
while (invalue(U130MI1x,1) != clktime->tm_min/10)
|
|
;
|
|
outvalue(0x01); /* Korrektur Einer-Minuten */
|
|
outvalue(0x00);
|
|
while (invalue(U130MIx1,1) != clktime->tm_min%10)
|
|
;
|
|
outvalue(0x01); /* Korrektur Stop */
|
|
outvalue(0x00);
|
|
}
|
|
|
|
void
|
|
u130_start()
|
|
{
|
|
outvalue(0x01); /* Start der Zeit */
|
|
outvalue(0x00);
|
|
}
|
|
|
|
long
|
|
u130_get()
|
|
{
|
|
long time;
|
|
struct tm *clktime;
|
|
|
|
outvalue(0x02); /* Umschalten auf Datum */
|
|
clktime->tm_year = rdvalue(U130YYx1);
|
|
if (clktime->tm_year < 70)
|
|
clktime->tm_year+=100;
|
|
clktime->tm_mday = rdvalue(U130DDx1);
|
|
clktime->tm_mon = rdvalue(U130MMx1);
|
|
clktime->tm_mon --;
|
|
outvalue(0x00);
|
|
clktime->tm_sec = inb(U130MM1x) & 0x28; /* Umschalten auf Zeit */
|
|
if (clktime->tm_sec == 0x08 || clktime->tm_sec == 0x20) {
|
|
outvalue(0x02);
|
|
outvalue(0x00);
|
|
}
|
|
while ((clktime->tm_sec = rdvalue(U130SSx1)) == 59);
|
|
clktime->tm_min = rdvalue(U130MIx1);
|
|
clktime->tm_hour = rdvalue(U130HHx1);
|
|
|
|
time = timegm(clktime);
|
|
return(time);
|
|
}
|
|
|
|
void
|
|
outvalue(t)
|
|
register t;
|
|
{
|
|
outb(U130BASE, t);
|
|
t = 10000;
|
|
while (t--)
|
|
;
|
|
}
|
|
|
|
int
|
|
invalue(addr, flag)
|
|
register addr;
|
|
register flag;
|
|
{
|
|
register seg7, takt;
|
|
|
|
seg7 = inb(addr);
|
|
if (seg7 != inb(addr))
|
|
seg7 = inb(addr);
|
|
takt = seg7 & 0x80; /* nur gueltig bei 6. Stelle */
|
|
if (seg7 & 0x20)
|
|
seg7 = ~seg7;
|
|
if (addr == U130MM1x) /* 6.Stelle */
|
|
seg7 &= 0x07;
|
|
seg7 &= 0x1f;
|
|
if (seg7 == 0x0f)
|
|
return(0);
|
|
if (seg7 == 0x00) {
|
|
if (flag == 0)
|
|
return(0);
|
|
if (addr == U130MM1x && takt)
|
|
return(0);
|
|
}
|
|
if (seg7 == 0x02)
|
|
return(1);
|
|
if (seg7 == 0x17 || seg7 == 0x05)
|
|
return(2);
|
|
if (seg7 == 0x13)
|
|
return(3);
|
|
if (seg7 == 0x1a)
|
|
return(4);
|
|
if (seg7 == 0x19)
|
|
return(5);
|
|
if (seg7 == 0x1d)
|
|
return(6);
|
|
if (seg7 == 0x03)
|
|
return(7);
|
|
if (seg7 == 0x1f)
|
|
return(8);
|
|
if (seg7 == 0x1b)
|
|
return(9);
|
|
return(0xff);
|
|
}
|
|
|
|
int
|
|
rdvalue(addr)
|
|
unsigned addr;
|
|
{
|
|
return(invalue(addr,0) + invalue(addr+2,0)*10);
|
|
}
|