hcj@lzaz.ATT.COM (HC Johnson) (05/12/89)
The clock setting routines for ST minix with RS232 have been
extended to support the Dallas Semiconductor Clock. This is
the one that is in a socket that is inserted under a TOS ROM.
The Dallas Chip code is from work done by Bill Penner, and was
ported to this program by Bruce Szablak.
These routines can still be used with the BMS/SUPRA/ICD disk
based clocks.
diskrtc rtc will set the Minix clock from Dallas
diskset rtc will set the Dallas clock from Minix time.
Howard C. Johnson
ATT Bell Labs
att!lzaz!hcj
hcj@lzaz.att.com
================================cut here========================
/* DISKRTC.C */
#include <sgtty.h>
#define DEBUG
#define AD_RTC 0xFFFC20
#define SECL 0
#define SECH 1
#define MINL 2
#define MINH 3
#define HOURL 4
#define HOURH 5
#define DAYL 7
#define DAYH 8
#define MONL 9
#define MONH 10
#define YEARL 11
#define YEARH 12
#define N 13
int fd;
unsigned char a[N];
int m[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
long time();
char *ctime();
main(argc, argv)
char **argv;
{
register i, n, d, ok;
int x;
long ot, nt;
#ifdef DEBUG
int debug = argc != 2;
#endif
if(argc == 1) {
usage:
fatal("Usage: %s [bms1|bms2|supra|icd|rtc]\n",argv[0]);
exit(1);
}
if(strcmp(argv[1],"bms1") == 0)
x = DC_RBMS100;
else if(strcmp(argv[1],"bms2") == 0)
x = DC_RBMS200;
else if(strcmp(argv[1],"supra") == 0)
x = DC_RSUPRA;
else if(strcmp(argv[1],"icd") == 0)
x = DC_RICD;
else if(strcmp(argv[1],"rtc") == 0) {
bootclk();
goto dotime;
} else
goto usage;
fd = open("/dev/rhd0", 0);
if (fd < 0)
fatal("cannot open /dev/hd0 ");
for(n=0;n<3;n++) {
i = ioctl(fd,x,a);
if(i <0) {
perror("read");
printf("read (ioctl) returned %d\n",i);
exit(1);
}
if (a[SECL] == 15)
fatal("no RTC present");
break;
}
dotime:
if(debug)
printf("bms: %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12]);
a[HOURH] &= 3;
nt = 0;
i = dd(YEARL, 0, 99);
if ((i & 3) == 0)
m[1]++;
i += 80;
while (--i >= 70) {
nt += 365;
if ((i & 3) == 0)
nt++;
}
i = dd(MONL, 1, 12)-1;
while (--i >= 0)
nt += m[i];
nt += dd(DAYL, 1, 31) - 1;
nt *= 24;
nt += dd(HOURL, 0, 23);
nt *= 60;
nt += dd(MINL, 0, 59);
nt *= 60;
nt += dd(SECL, 0, 59);
time(&ot);
#ifdef DEBUG
if (debug) {
printf("old time = (%ld) %s\n", ot, ctime(&ot));
printf("new time = (%ld) %s\n", nt, ctime(&nt));
}
#endif
if (ot > nt)
fatal("cannot set time back\n");
if (stime(&nt) < 0)
fatal("stime() failed");
exit(0);
}
dd(i, min, max)
{
register n;
n = a[i] + 10 * a[i+1];
if (n < min || n > max)
fatal("ASSERT(idx=%d %d >= %d && %d <= %d)", i, n, min, n, max);
return(n);
}
fatal(s, a1, a2, a3, a4, a5)
char *s;
{
printf("bmsrtc: ");
printf(s, a1, a2, a3, a4, a5);
printf(" (fatal)\n");
exit(1);
}
/******************************************************/
/* BOOTCLK */
/*----------------------------------------------------*/
/* Time Load Program */
/* by */
/* Bill Penner */
/* 3235 Wright Avenue */
/* Bremerton, WA 98310 */
/*----------------------------------------------------*/
/* Written 31 January 1987 for use with the Dallas */
/* semiconductor DS1216E real time clock module. */
/*----------------------------------------------------*/
/* This program is entered into the public domain for */
/* use and distribution. */
/* Modified for MINIX ST by Bruce Szablak */
/******************************************************/
bootclk()
{
int *cwrite = 0xFE0000L; /* Location of clock write */
int *cread = 0xFE0008L; /* Location of clock read */
long code = 0x5CA33AC5L;/* Code to activate the DS1216E */
unsigned data[8]; /* Hold the read information */
unsigned temp; /* Temporary use integer */
int i,j;
temp = *cread; /* Send out enable sequence */
for(i=0;i<2;i++)
{
for(j=0;j<32;j++) temp = cwrite[(int)((code >> j) & 1)];
}
for(i=0;i<8;i++) /* Read the clock chip */
{
data[i] = 0;
for(j=0;j<8;j++)
data[i] = data[i] | ((*cread & 0x100) >> (8-j));
}
a[SECL] = data[1] & 0xF;
a[SECH] = (data[1] >> 4) & 0xF;
a[MINL] = data[2] & 0xF;
a[MINH] = (data[2] >> 4) & 0xF;
a[HOURL] = data[3] & 0xF;
a[HOURH] = (data[3] >> 4) & 0xF;
a[DAYL] = data[5] & 0xF;
a[DAYH] = (data[5] >> 4) & 0xF;
a[MONL] = data[6] & 0xF;
a[MONH] = (data[6] >> 4) & 0xF;
a[YEARL] = data[7] & 0xF;
a[YEARH] = ((data[7] >> 4) & 0xF) - 8;
}
================================cut here========================
/* DISKSET.C */
#include <sgtty.h>
/* bmsset - r set the date in bms Author: Howard Johnson
* taken from minix date, Author: Adri Koppes
*/
#define SECL 0
#define SECH 1
#define MINL 2
#define MINH 3
#define HOURL 4
#define HOURH 5
#define DAYW 6
#define DAYL 7
#define DAYH 8
#define MONL 9
#define MONH 10
#define YEARL 11
#define YEARH 12
#define N 13
int fd;
unsigned char a[N];
int days_per_month[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
struct {
int year, month, day, hour, min, sec;
} tm;
long s_p_min;
long s_p_hour;
long s_p_day;
long s_p_year;
int leap = 0;
main(argc, argv)
int argc;
char **argv;
{
long t, time();
int x;
int n,i;
if(argc == 1) {
usage:
fatal("Usage: %s [bms1|bms2|supra|icd|rtc]\n",argv[0]);
exit(1);
}
s_p_min = 60;
s_p_hour = 60 * s_p_min;
s_p_day = 24 * s_p_hour;
s_p_year = 365 * s_p_day;
if(strcmp(argv[1],"bms1") == 0)
x = DC_WBMS100;
else if(strcmp(argv[1],"bms2") == 0)
x = DC_WBMS200;
else if(strcmp(argv[1],"rtc") == 0)
setareal();
else
goto usage;
time(&t);
cv_time(t);
/* expected fmt
Thu Nov 10 13:59:34 EST 1988
.month 0-11
.day 1-31
.hour 0-23
.minute 0-59
.second 0-59
.year 1970 -
*/
tm.year -= 1980;
tm.month += 1;
a[SECL] = (tm.sec % 10) & 0xf;
a[SECH] = (tm.sec / 10) & 0xf;
a[SECL] = 0;
a[SECH] = 0;
a[MINL] = (tm.min % 10) & 0xf;
a[MINH] = (tm.min / 10) & 0xf;
a[HOURL] = (tm.hour % 10) & 0xf;
a[HOURH] = ((tm.hour / 10) & 0xf) | 0x8; /* 24 hr format */
a[DAYL] = (tm.day % 10) & 0xf;
a[DAYH] = ((tm.day / 10) & 0xf) | (leap?4:0);
a[MONL] = (tm.month % 10) & 0xf;
a[MONH] = (tm.month / 10) & 0xf;
a[YEARL] = (tm.year % 10) & 0xf;
a[YEARH] = (tm.year / 10) & 0xf;
a[DAYW] = 0;
fd = open("/dev/rhd0", 1);
if (fd < 0)
fatal("cannot open /dev/rhd0 ");
for(n=0;n<3;n++) {
i = ioctl(fd,x,a);
if(i == 0)
exit(0);
}
perror("write");
exit(1);
}
cv_time(t)
long t;
{
tm.year = 0;
tm.month = 0;
tm.day = 1;
tm.hour = 0;
tm.min = 0;
tm.sec = 0;
while (t >= s_p_year) {
if (((tm.year + 2) % 4) == 0)
t -= s_p_day;
tm.year += 1;
t -= s_p_year;
}
if (((tm.year + 2) % 4) == 0) {
days_per_month[1]++;
leap = 1;
}
tm.year += 1970;
while ( t >= (days_per_month[tm.month] * s_p_day))
t -= days_per_month[tm.month++] * s_p_day;
while (t >= s_p_day) {
t -= s_p_day;
tm.day++;
}
while (t >= s_p_hour) {
t -= s_p_hour;
tm.hour++;
}
while (t >= s_p_min) {
t -= s_p_min;
tm.min++;
}
tm.sec = (int) t;
}
fatal(s, a1, a2, a3, a4, a5)
char *s;
{
printf("bmsrtc: ");
printf(s, a1, a2, a3, a4, a5);
printf(" (fatal)\n");
exit(1);
}
/******************************************************/
/* SETAREAL */
/*----------------------------------------------------*/
/* Set Module Time Program */
/* by */
/* Bill Penner */
/* 3235 Wright Avenue */
/* Bremerton, WA 98310 */
/*----------------------------------------------------*/
/* Written 31 January 1987 for use with the Dallas */
/* semiconductor DS1216E real time clock module. */
/* Modified for MINIX ST by Bruce Szablak */
/*----------------------------------------------------*/
/* This program is entered into the public domain for */
/* use and distribution. */
/******************************************************/
setareal()
{
int *cwrite = 0xFE0000L;/* Location of clock write */
int *cread = 0xFE0008L;/* Location of clock read */
long code = 0x5CA33AC5L;/* Code to activate the DS1216E */
long datetime; /* Hold the date and time */
int data[8]; /* Hold the read information */
int i,j, temp;
time(&datetime); /* Go get the present t and d */
cv_time(datetime);
tm.month++;
tm.year -= 1900;
data[0] = 0;
data[1] = (tm.sec % 10) | ((tm.sec / 10) << 4);
data[2] = (tm.min % 10) | ((tm.min / 10) << 4);
data[3] = (tm.hour % 10) | ((tm.hour / 10) << 4);
data[4] = 0;
data[5] = (tm.day % 10) | ((tm.day / 10) << 4);
data[6] = (tm.month % 10) | ((tm.month / 10) << 4);
data[7] = (tm.year % 10) | ((tm.year / 10) << 4);
temp = *cread; /* Send out enable sequence */
for(i=0;i<2;i++)
{
for(j=0;j<32;j++) temp = cwrite[(int)((code >> j) & 1)];
}
for(i=0;i<8;i++) /* Write the clock chip */
{
for(j=0;j<8;j++) temp = cwrite[((data[i] >> j) & 1)];
}
exit(0);
}