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); }