xref: /original-bsd/sys/i386/isa/clock.c (revision fa921481)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * William Jolitz.
7  *
8  * Added stuff to read the cmos clock on startup - Don Ahn
9  *
10  * %sccs.include.386.c%
11  *
12  *	@(#)clock.c	5.2 (Berkeley) 06/23/90
13  */
14 
15 /*
16  * Primitive clock interrupt routines.
17  */
18 #include "param.h"
19 #include "time.h"
20 #include "kernel.h"
21 #include "icu.h"
22 
23 #define DAYST 119
24 #define DAYEN 303
25 
26 startrtclock() {
27 
28 	/* initialize 8253 clock */
29 	outb (0x43, 0x36);
30 	outb (0x40, 1193182/60);
31 	outb (0x40, (1193182/60)/256);
32 }
33 
34 clkreld() {
35 pg("clkreld");
36 }
37 
38 /* convert 2 digit BCD number */
39 bcd(i)
40 int i;
41 {
42 	return ((i/16)*10 + (i%16));
43 }
44 
45 /* convert years to seconds (from 1970) */
46 unsigned long
47 ytos(y)
48 int y;
49 {
50 	int i;
51 	unsigned long ret;
52 
53 	ret = 0; y = y - 70;
54 	for(i=0;i<y;i++) {
55 		if (i % 4) ret += 31536000;
56 		else ret += 31622400;
57 	}
58 	return ret;
59 }
60 
61 /* convert months to seconds */
62 unsigned long
63 mtos(m,leap)
64 int m,leap;
65 {
66 	int i;
67 	unsigned long ret;
68 
69 	ret = 0;
70 	for(i=1;i<m;i++) {
71 		switch(i){
72 		case 1: case 3: case 5: case 7: case 8: case 10: case 12:
73 			ret += 2678400; break;
74 		case 4: case 6: case 9: case 11:
75 			ret += 2592000; break;
76 		case 2:
77 			if (leap) ret += 2505600;
78 			else ret += 2419200;
79 		}
80 	}
81 	return ret;
82 }
83 
84 
85 /*
86  * Initialze the time of day register, based on the time base which is, e.g.
87  * from a filesystem.
88  */
89 inittodr(base)
90 	time_t base;
91 {
92 	unsigned long sec;
93 	int leap,day_week,t,yd;
94 
95 	outb(0x70,9); /* year    */
96 	sec = bcd(inb(0x71)); leap = !(sec % 4); sec += ytos(sec);
97 	outb(0x70,8); /* month   */
98 	yd = mtos(bcd(inb(0x71)),leap); sec += yd;
99 	outb(0x70,7); /* date    */
100 	t = (bcd(inb(0x71))-1) * 86400; sec += t; yd += t;
101 	outb(0x70,6); /* day     */
102 	day_week = inb(0x71);
103 	outb(0x70,4); /* hour    */
104 	sec += bcd(inb(0x71)) * 3600;
105 	outb(0x70,2); /* minutes */
106 	sec += bcd(inb(0x71)) * 60;
107 	outb(0x70,0); /* seconds */
108 	sec += bcd(inb(0x71));
109 
110 	/* XXX off by one? Need to calculate DST on SUNDAY */
111 	/* Perhaps we should have the RTC hold GMT time to save */
112 	/* us the bother of converting. */
113 	yd = yd / 86400;
114 	if ((yd >= DAYST) && ( yd <= DAYEN)) {
115 		sec -= 3600;
116 	}
117 	sec += tz.tz_minuteswest * 60;
118 
119 	time.tv_sec = sec;
120 }
121 
122 /*
123  * Initialze the time of day register, based on the time base which is, e.g.
124  * from a filesystem.
125  */
126 test_inittodr(base)
127 	time_t base;
128 {
129 
130 	outb(0x70,9); /* year    */
131 	printf("%d ",bcd(inb(0x71)));
132 	outb(0x70,8); /* month   */
133 	printf("%d ",bcd(inb(0x71)));
134 	outb(0x70,7); /* day     */
135 	printf("%d ",bcd(inb(0x71)));
136 	outb(0x70,4); /* hour    */
137 	printf("%d ",bcd(inb(0x71)));
138 	outb(0x70,2); /* minutes */
139 	printf("%d ",bcd(inb(0x71)));
140 	outb(0x70,0); /* seconds */
141 	printf("%d\n",bcd(inb(0x71)));
142 
143 	time.tv_sec = base;
144 }
145 
146 
147 /*
148  * Restart the clock.
149  */
150 resettodr()
151 {
152 }
153 
154 enablertclock() {
155 	INTREN(IRQ0);
156 	splnone();
157 }
158