/* $OpenBSD: clock.c,v 1.5 2006/08/17 06:31:10 miod Exp $ */ /* $NetBSD: clock.c,v 1.3 1995/02/20 00:12:09 mycroft Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1982, 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * from: Utah $Hdr: clock.c 1.18 91/01/21$ * * @(#)clock.c 8.2 (Berkeley) 1/12/94 */ #include #include #include "samachdep.h" #include "hilreg.h" #include extern void send_hil_cmd(struct hil_dev *, u_char, u_char *, u_char, u_char *); static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; u_char bbc_registers[13]; struct hil_dev *bbcaddr = (struct hil_dev *)BBCADDR; int bbc_to_gmt(u_long *); void read_bbc(void); u_char read_bbc_reg(int); time_t getsecs() { static int bbcinited = 0; u_long timbuf = 0; if (!bbc_to_gmt(&timbuf) && !bbcinited) printf("WARNING: bad date in battery clock\n"); bbcinited = 1; /* Battery clock does not store usec's, so forget about it. */ return((time_t)timbuf); } int bbc_to_gmt(u_long *timbuf) { int i; u_long tmp; int year, month, day, hour, min, sec; read_bbc(); sec = bbc_to_decimal(1, 0); min = bbc_to_decimal(3, 2); /* * Hours are different for some reason. Makes no sense really. */ hour = ((bbc_registers[5] & 0x03) * 10) + bbc_registers[4]; day = bbc_to_decimal(8, 7); month = bbc_to_decimal(10, 9); year = bbc_to_decimal(12, 11) + 1900; range_test(hour, 0, 23); range_test(day, 1, 31); range_test(month, 1, 12); range_test(year, STARTOFTIME, 2038); /* 2038 is the end of time. */ tmp = 0; for (i = STARTOFTIME; i < year; i++) tmp += days_in_year(i); if (leapyear(year) && month > FEBRUARY) tmp++; for (i = 1; i < month; i++) tmp += days_in_month(i); tmp += (day - 1); tmp = ((tmp * 24 + hour) * 60 + min) * 60 + sec; *timbuf = tmp; return(1); } void read_bbc() { int i, read_okay; read_okay = 0; while (!read_okay) { read_okay = 1; for (i = 0; i <= NUM_BBC_REGS; i++) bbc_registers[i] = read_bbc_reg(i); for (i = 0; i <= NUM_BBC_REGS; i++) if (bbc_registers[i] != read_bbc_reg(i)) read_okay = 0; } } u_char read_bbc_reg(int reg) { u_char data = reg; if (bbcaddr) { #if 0 send_hil_cmd(bbcaddr, BBC_SET_REG, &data, 1, NULL); send_hil_cmd(bbcaddr, BBC_READ_REG, NULL, 0, &data); #else HILWAIT(bbcaddr); bbcaddr->hil_cmd = BBC_SET_REG; HILWAIT(bbcaddr); bbcaddr->hil_data = data; HILWAIT(bbcaddr); bbcaddr->hil_cmd = BBC_READ_REG; HILDATAWAIT(bbcaddr); data = bbcaddr->hil_data; #endif } return(data); }