Home | History | Annotate | Line # | Download | only in isa
isaclock.c revision 1.4
      1  1.4     agc /*	$NetBSD: isaclock.c,v 1.4 2003/08/07 16:29:22 agc Exp $	*/
      2  1.1  briggs 
      3  1.1  briggs /*-
      4  1.1  briggs  * Copyright (c) 1990 The Regents of the University of California.
      5  1.1  briggs  * All rights reserved.
      6  1.1  briggs  *
      7  1.1  briggs  * This code is derived from software contributed to Berkeley by
      8  1.1  briggs  * William Jolitz and Don Ahn.
      9  1.1  briggs  *
     10  1.1  briggs  * Redistribution and use in source and binary forms, with or without
     11  1.1  briggs  * modification, are permitted provided that the following conditions
     12  1.1  briggs  * are met:
     13  1.1  briggs  * 1. Redistributions of source code must retain the above copyright
     14  1.1  briggs  *    notice, this list of conditions and the following disclaimer.
     15  1.1  briggs  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  briggs  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  briggs  *    documentation and/or other materials provided with the distribution.
     18  1.4     agc  * 3. Neither the name of the University nor the names of its contributors
     19  1.4     agc  *    may be used to endorse or promote products derived from this software
     20  1.4     agc  *    without specific prior written permission.
     21  1.4     agc  *
     22  1.4     agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  1.4     agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  1.4     agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  1.4     agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  1.4     agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  1.4     agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  1.4     agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  1.4     agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  1.4     agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  1.4     agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  1.4     agc  * SUCH DAMAGE.
     33  1.4     agc  *
     34  1.4     agc  *	@(#)clock.c	7.2 (Berkeley) 5/12/91
     35  1.4     agc  */
     36  1.4     agc /*-
     37  1.4     agc  * Copyright (c) 1993, 1994 Charles M. Hannum.
     38  1.4     agc  *
     39  1.4     agc  * This code is derived from software contributed to Berkeley by
     40  1.4     agc  * William Jolitz and Don Ahn.
     41  1.4     agc  *
     42  1.4     agc  * Redistribution and use in source and binary forms, with or without
     43  1.4     agc  * modification, are permitted provided that the following conditions
     44  1.4     agc  * are met:
     45  1.4     agc  * 1. Redistributions of source code must retain the above copyright
     46  1.4     agc  *    notice, this list of conditions and the following disclaimer.
     47  1.4     agc  * 2. Redistributions in binary form must reproduce the above copyright
     48  1.4     agc  *    notice, this list of conditions and the following disclaimer in the
     49  1.4     agc  *    documentation and/or other materials provided with the distribution.
     50  1.1  briggs  * 3. All advertising materials mentioning features or use of this software
     51  1.1  briggs  *    must display the following acknowledgement:
     52  1.1  briggs  *	This product includes software developed by the University of
     53  1.1  briggs  *	California, Berkeley and its contributors.
     54  1.1  briggs  * 4. Neither the name of the University nor the names of its contributors
     55  1.1  briggs  *    may be used to endorse or promote products derived from this software
     56  1.1  briggs  *    without specific prior written permission.
     57  1.1  briggs  *
     58  1.1  briggs  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59  1.1  briggs  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60  1.1  briggs  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61  1.1  briggs  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62  1.1  briggs  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  1.1  briggs  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  1.1  briggs  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  1.1  briggs  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  1.1  briggs  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  1.1  briggs  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  1.1  briggs  * SUCH DAMAGE.
     69  1.1  briggs  *
     70  1.1  briggs  *	@(#)clock.c	7.2 (Berkeley) 5/12/91
     71  1.1  briggs  */
     72  1.1  briggs /*
     73  1.1  briggs  * Mach Operating System
     74  1.1  briggs  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
     75  1.1  briggs  * All Rights Reserved.
     76  1.1  briggs  *
     77  1.1  briggs  * Permission to use, copy, modify and distribute this software and its
     78  1.1  briggs  * documentation is hereby granted, provided that both the copyright
     79  1.1  briggs  * notice and this permission notice appear in all copies of the
     80  1.1  briggs  * software, derivative works or modified versions, and any portions
     81  1.1  briggs  * thereof, and that both notices appear in supporting documentation.
     82  1.1  briggs  *
     83  1.1  briggs  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     84  1.1  briggs  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     85  1.1  briggs  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     86  1.1  briggs  *
     87  1.1  briggs  * Carnegie Mellon requests users of this software to return to
     88  1.1  briggs  *
     89  1.1  briggs  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     90  1.1  briggs  *  School of Computer Science
     91  1.1  briggs  *  Carnegie Mellon University
     92  1.1  briggs  *  Pittsburgh PA 15213-3890
     93  1.1  briggs  *
     94  1.1  briggs  * any improvements or extensions that they make and grant Carnegie Mellon
     95  1.1  briggs  * the rights to redistribute these changes.
     96  1.1  briggs  */
     97  1.1  briggs /*
     98  1.1  briggs   Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
     99  1.1  briggs 
    100  1.1  briggs 		All Rights Reserved
    101  1.1  briggs 
    102  1.1  briggs Permission to use, copy, modify, and distribute this software and
    103  1.1  briggs its documentation for any purpose and without fee is hereby
    104  1.1  briggs granted, provided that the above copyright notice appears in all
    105  1.1  briggs copies and that both the copyright notice and this permission notice
    106  1.1  briggs appear in supporting documentation, and that the name of Intel
    107  1.1  briggs not be used in advertising or publicity pertaining to distribution
    108  1.1  briggs of the software without specific, written prior permission.
    109  1.1  briggs 
    110  1.1  briggs INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
    111  1.1  briggs INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
    112  1.1  briggs IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
    113  1.1  briggs CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    114  1.1  briggs LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
    115  1.1  briggs NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
    116  1.1  briggs WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    117  1.1  briggs */
    118  1.1  briggs 
    119  1.1  briggs /*
    120  1.1  briggs  * Primitive clock interrupt routines.
    121  1.1  briggs  */
    122  1.3   lukem 
    123  1.3   lukem #include <sys/cdefs.h>
    124  1.4     agc __KERNEL_RCSID(0, "$NetBSD: isaclock.c,v 1.4 2003/08/07 16:29:22 agc Exp $");
    125  1.3   lukem 
    126  1.1  briggs #include <sys/param.h>
    127  1.1  briggs #include <sys/systm.h>
    128  1.1  briggs #include <sys/callout.h>
    129  1.1  briggs #include <sys/time.h>
    130  1.1  briggs #include <sys/kernel.h>
    131  1.1  briggs #include <sys/device.h>
    132  1.1  briggs 
    133  1.1  briggs #include <machine/cpu.h>
    134  1.1  briggs #include <machine/intr.h>
    135  1.1  briggs #include <machine/pio.h>
    136  1.1  briggs 
    137  1.1  briggs #include <dev/isa/isareg.h>
    138  1.1  briggs #include <dev/isa/isavar.h>
    139  1.1  briggs #include <dev/ic/mc146818reg.h>
    140  1.1  briggs #include <dev/ic/i8253reg.h>
    141  1.1  briggs #include <sandpoint/isa/nvram.h>
    142  1.1  briggs #include <sandpoint/isa/spkrreg.h>
    143  1.1  briggs 
    144  1.1  briggs extern void disable_intr(void);	/* In locore.S */
    145  1.1  briggs extern void enable_intr(void);	/* In locore.S */
    146  1.1  briggs 
    147  1.1  briggs void	sysbeepstop __P((void *));
    148  1.1  briggs void	sysbeep __P((int, int));
    149  1.1  briggs void	rtcinit __P((void));
    150  1.1  briggs int	rtcget __P((mc_todregs *));
    151  1.1  briggs void	rtcput __P((mc_todregs *));
    152  1.1  briggs static int yeartoday __P((int));
    153  1.1  briggs int 	hexdectodec __P((int));
    154  1.1  briggs int	dectohexdec __P((int));
    155  1.1  briggs 
    156  1.1  briggs __inline u_int mc146818_read __P((void *, u_int));
    157  1.1  briggs __inline void mc146818_write __P((void *, u_int, u_int));
    158  1.1  briggs 
    159  1.1  briggs #define	SECMIN	((unsigned)60)			/* seconds per minute */
    160  1.1  briggs #define	SECHOUR	((unsigned)(60*SECMIN))		/* seconds per hour */
    161  1.1  briggs #define	SECDAY	((unsigned)(24*SECHOUR))	/* seconds per day */
    162  1.1  briggs #define	SECYR	((unsigned)(365*SECDAY))	/* seconds per common year */
    163  1.1  briggs 
    164  1.1  briggs __inline u_int
    165  1.1  briggs mc146818_read(sc, reg)
    166  1.1  briggs 	void *sc;					/* XXX use it? */
    167  1.1  briggs 	u_int reg;
    168  1.1  briggs {
    169  1.1  briggs 
    170  1.1  briggs 	isa_outb(IO_RTC, (u_char)reg);
    171  1.1  briggs 	return (isa_inb(IO_RTC+1));
    172  1.1  briggs }
    173  1.1  briggs 
    174  1.1  briggs __inline void
    175  1.1  briggs mc146818_write(sc, reg, datum)
    176  1.1  briggs 	void *sc;					/* XXX use it? */
    177  1.1  briggs 	u_int reg, datum;
    178  1.1  briggs {
    179  1.1  briggs 
    180  1.1  briggs 	isa_outb(IO_RTC, reg);
    181  1.1  briggs 	isa_outb(IO_RTC+1, datum);
    182  1.1  briggs }
    183  1.1  briggs 
    184  1.1  briggs static int beeping;
    185  1.1  briggs 
    186  1.1  briggs void
    187  1.1  briggs sysbeepstop(arg)
    188  1.1  briggs 	void *arg;
    189  1.1  briggs {
    190  1.1  briggs 	/* disable counter 2 */
    191  1.1  briggs 	disable_intr();
    192  1.1  briggs 	isa_outb(PITAUX_PORT, isa_inb(PITAUX_PORT) & ~PIT_SPKR);
    193  1.1  briggs 	enable_intr();
    194  1.1  briggs 	beeping = 0;
    195  1.1  briggs }
    196  1.1  briggs 
    197  1.1  briggs void
    198  1.1  briggs sysbeep(pitch, period)
    199  1.1  briggs 	int pitch, period;
    200  1.1  briggs {
    201  1.1  briggs 	static struct callout sysbeep_ch = CALLOUT_INITIALIZER;
    202  1.1  briggs 	static int last_pitch;
    203  1.1  briggs 
    204  1.1  briggs 	if (beeping)
    205  1.1  briggs 		callout_stop(&sysbeep_ch);
    206  1.1  briggs 	if (pitch == 0 || period == 0) {
    207  1.1  briggs 		sysbeepstop(0);
    208  1.1  briggs 		last_pitch = 0;
    209  1.1  briggs 		return;
    210  1.1  briggs 	}
    211  1.1  briggs 	if (!beeping || last_pitch != pitch) {
    212  1.1  briggs 		disable_intr();
    213  1.1  briggs 		isa_outb(IO_TIMER1 + TIMER_MODE,
    214  1.1  briggs 			 TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
    215  1.1  briggs 		isa_outb(IO_TIMER1 + TIMER_CNTR2, TIMER_DIV(pitch) % 256);
    216  1.1  briggs 		isa_outb(IO_TIMER1 + TIMER_CNTR2, TIMER_DIV(pitch) / 256);
    217  1.1  briggs 		isa_outb(PITAUX_PORT, isa_inb(PITAUX_PORT) | PIT_SPKR);	/* enable counter 2 */
    218  1.1  briggs 		enable_intr();
    219  1.1  briggs 	}
    220  1.1  briggs 	last_pitch = pitch;
    221  1.1  briggs 	beeping = 1;
    222  1.1  briggs 	callout_reset(&sysbeep_ch, period, sysbeepstop, NULL);
    223  1.1  briggs }
    224  1.1  briggs 
    225  1.1  briggs void
    226  1.1  briggs rtcinit()
    227  1.1  briggs {
    228  1.1  briggs 	static int first_rtcopen_ever = 1;
    229  1.1  briggs 
    230  1.1  briggs 	if (!first_rtcopen_ever)
    231  1.1  briggs 		return;
    232  1.1  briggs 	first_rtcopen_ever = 0;
    233  1.1  briggs 
    234  1.1  briggs 	mc146818_write(NULL, MC_REGA,			/* XXX softc */
    235  1.1  briggs 	    MC_BASE_32_KHz | MC_RATE_1024_Hz);
    236  1.1  briggs 	mc146818_write(NULL, MC_REGB, MC_REGB_24HR);	/* XXX softc */
    237  1.1  briggs }
    238  1.1  briggs 
    239  1.1  briggs int
    240  1.1  briggs rtcget(regs)
    241  1.1  briggs 	mc_todregs *regs;
    242  1.1  briggs {
    243  1.1  briggs 
    244  1.1  briggs 	rtcinit();
    245  1.1  briggs 	if ((mc146818_read(NULL, MC_REGD) & MC_REGD_VRT) == 0) /* XXX softc */
    246  1.1  briggs 		return (-1);
    247  1.1  briggs 	MC146818_GETTOD(NULL, regs);			/* XXX softc */
    248  1.1  briggs 	return (0);
    249  1.1  briggs }
    250  1.1  briggs 
    251  1.1  briggs void
    252  1.1  briggs rtcput(regs)
    253  1.1  briggs 	mc_todregs *regs;
    254  1.1  briggs {
    255  1.1  briggs 
    256  1.1  briggs 	rtcinit();
    257  1.1  briggs 	MC146818_PUTTOD(NULL, regs);			/* XXX softc */
    258  1.1  briggs }
    259  1.1  briggs 
    260  1.1  briggs static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    261  1.1  briggs 
    262  1.1  briggs static int
    263  1.1  briggs yeartoday(year)
    264  1.1  briggs 	int year;
    265  1.1  briggs {
    266  1.1  briggs 
    267  1.1  briggs 	return ((year % 4) ? 365 : 366);
    268  1.1  briggs }
    269  1.1  briggs 
    270  1.1  briggs int
    271  1.1  briggs hexdectodec(n)
    272  1.1  briggs 	int n;
    273  1.1  briggs {
    274  1.1  briggs 
    275  1.1  briggs 	return (((n >> 4) & 0x0f) * 10 + (n & 0x0f));
    276  1.1  briggs }
    277  1.1  briggs 
    278  1.1  briggs int
    279  1.1  briggs dectohexdec(n)
    280  1.1  briggs 	int n;
    281  1.1  briggs {
    282  1.1  briggs 
    283  1.1  briggs 	return ((u_char)(((n / 10) << 4) & 0xf0) | ((n % 10) & 0x0f));
    284  1.1  briggs }
    285  1.1  briggs 
    286  1.1  briggs static int timeset;
    287  1.1  briggs 
    288  1.1  briggs /*
    289  1.1  briggs  * Initialize the time of day register, based on the time base which is, e.g.
    290  1.1  briggs  * from a filesystem.
    291  1.1  briggs  */
    292  1.1  briggs void
    293  1.1  briggs inittodr(base)
    294  1.1  briggs 	time_t base;
    295  1.1  briggs {
    296  1.1  briggs 	mc_todregs rtclk;
    297  1.1  briggs 	time_t n;
    298  1.1  briggs 	int sec, min, hr, dom, mon, yr;
    299  1.1  briggs 	int i, days = 0;
    300  1.1  briggs 	int s;
    301  1.1  briggs 
    302  1.1  briggs 	/*
    303  1.1  briggs 	 * We mostly ignore the suggested time and go for the RTC clock time
    304  1.1  briggs 	 * stored in the CMOS RAM.  If the time can't be obtained from the
    305  1.1  briggs 	 * CMOS, or if the time obtained from the CMOS is 5 or more years
    306  1.1  briggs 	 * less than the suggested time, we used the suggested time.  (In
    307  1.1  briggs 	 * the latter case, it's likely that the CMOS battery has died.)
    308  1.1  briggs 	 */
    309  1.1  briggs 
    310  1.1  briggs 	if (base < 15*SECYR) {	/* if before 1985, something's odd... */
    311  1.1  briggs 		printf("WARNING: preposterous time in file system\n");
    312  1.1  briggs 		/* read the system clock anyway */
    313  1.1  briggs 		base = 17*SECYR + 186*SECDAY + SECDAY/2;
    314  1.1  briggs 	}
    315  1.1  briggs 
    316  1.1  briggs 	s = splclock();
    317  1.1  briggs 	if (rtcget(&rtclk)) {
    318  1.1  briggs 		splx(s);
    319  1.1  briggs 		printf("WARNING: invalid time in clock chip\n");
    320  1.1  briggs 		goto fstime;
    321  1.1  briggs 	}
    322  1.1  briggs 	splx(s);
    323  1.1  briggs 
    324  1.1  briggs 	sec = hexdectodec(rtclk[MC_SEC]);
    325  1.1  briggs 	min = hexdectodec(rtclk[MC_MIN]);
    326  1.1  briggs 	hr = hexdectodec(rtclk[MC_HOUR]);
    327  1.1  briggs 	dom = hexdectodec(rtclk[MC_DOM]);
    328  1.1  briggs 	mon = hexdectodec(rtclk[MC_MONTH]);
    329  1.1  briggs 	yr = hexdectodec(rtclk[MC_YEAR]);
    330  1.1  briggs 	yr = (yr < 70) ? yr+100 : yr;
    331  1.1  briggs 
    332  1.1  briggs 	n = sec + 60 * min + 3600 * hr;
    333  1.1  briggs 	n += (dom - 1) * 3600 * 24;
    334  1.1  briggs 
    335  1.1  briggs 	if (yeartoday(yr) == 366)
    336  1.1  briggs 		month[1] = 29;
    337  1.1  briggs 	for (i = mon - 2; i >= 0; i--)
    338  1.1  briggs 		days += month[i];
    339  1.1  briggs 	month[1] = 28;
    340  1.1  briggs 	for (i = 70; i < yr; i++)
    341  1.1  briggs 		days += yeartoday(i);
    342  1.1  briggs 	n += days * 3600 * 24;
    343  1.1  briggs 
    344  1.1  briggs 	n += rtc_offset * 60;
    345  1.1  briggs 
    346  1.1  briggs 	if (base < n - 5*SECYR)
    347  1.1  briggs 		printf("WARNING: file system time much less than clock time\n");
    348  1.1  briggs 	else if (base > n + 5*SECYR) {
    349  1.1  briggs 		printf("WARNING: clock time much less than file system time\n");
    350  1.1  briggs 		printf("WARNING: using file system time\n");
    351  1.1  briggs 		goto fstime;
    352  1.1  briggs 	}
    353  1.1  briggs 
    354  1.1  briggs 	timeset = 1;
    355  1.1  briggs 	time.tv_sec = n;
    356  1.1  briggs 	time.tv_usec = 0;
    357  1.1  briggs 	return;
    358  1.1  briggs 
    359  1.1  briggs fstime:
    360  1.1  briggs 	timeset = 1;
    361  1.1  briggs 	time.tv_sec = base;
    362  1.1  briggs 	time.tv_usec = 0;
    363  1.1  briggs 	printf("WARNING: CHECK AND RESET THE DATE!\n");
    364  1.1  briggs }
    365  1.1  briggs 
    366  1.1  briggs /*
    367  1.1  briggs  * Reset the clock.
    368  1.1  briggs  */
    369  1.1  briggs void
    370  1.1  briggs resettodr()
    371  1.1  briggs {
    372  1.1  briggs 	mc_todregs rtclk;
    373  1.1  briggs 	time_t n;
    374  1.1  briggs 	int diff, i, j;
    375  1.1  briggs 	int s;
    376  1.1  briggs 
    377  1.1  briggs 	/*
    378  1.1  briggs 	 * We might have been called by boot() due to a crash early
    379  1.1  briggs 	 * on.  Don't reset the clock chip in this case.
    380  1.1  briggs 	 */
    381  1.1  briggs 	if (!timeset)
    382  1.1  briggs 		return;
    383  1.1  briggs 
    384  1.1  briggs 	s = splclock();
    385  1.1  briggs 	if (rtcget(&rtclk))
    386  1.2     wiz 		memset(&rtclk, 0, sizeof(rtclk));
    387  1.1  briggs 	splx(s);
    388  1.1  briggs 
    389  1.1  briggs 	diff = rtc_offset * 60;
    390  1.1  briggs 	n = (time.tv_sec - diff) % (3600 * 24);   /* hrs+mins+secs */
    391  1.1  briggs 	rtclk[MC_SEC] = dectohexdec(n % 60);
    392  1.1  briggs 	n /= 60;
    393  1.1  briggs 	rtclk[MC_MIN] = dectohexdec(n % 60);
    394  1.1  briggs 	rtclk[MC_HOUR] = dectohexdec(n / 60);
    395  1.1  briggs 
    396  1.1  briggs 	n = (time.tv_sec - diff) / (3600 * 24);	/* days */
    397  1.1  briggs 	rtclk[MC_DOW] = (n + 4) % 7;  /* 1/1/70 is Thursday */
    398  1.1  briggs 
    399  1.1  briggs 	for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
    400  1.1  briggs 		n -= i;
    401  1.1  briggs 
    402  1.1  briggs 	rtclk[MC_YEAR] = dectohexdec(j - 1900);
    403  1.1  briggs 
    404  1.1  briggs 	if (i == 366)
    405  1.1  briggs 		month[1] = 29;
    406  1.1  briggs 	for (i = 0; n >= month[i]; i++)
    407  1.1  briggs 		n -= month[i];
    408  1.1  briggs 	month[1] = 28;
    409  1.1  briggs 	rtclk[MC_MONTH] = dectohexdec(++i);
    410  1.1  briggs 
    411  1.1  briggs 	rtclk[MC_DOM] = dectohexdec(++n);
    412  1.1  briggs 
    413  1.1  briggs 	s = splclock();
    414  1.1  briggs 	rtcput(&rtclk);
    415  1.1  briggs 	splx(s);
    416  1.1  briggs }
    417