myxm@beta.UUCP (Mike Mitchell) (05/08/87)
After getting a copy of the program which will read the date and time from the AST boards, I felt that modifying this utility to read the date and time from the MCT Multi-IO card would fit quite nicely in my system. I hope that others may be able to make use of this as well. Included are two files: mioclock.c and port_io.s. These files are fairly similar to those distributed with the astclock program. The mioclock.c program has been modified to read the date and time from the Multi-IO card and then set the system date. To compile this under Minix, you should use the command: cc -o mioclock mioclock.c port_io.s To enable automatic date and time setting upon boot, add the following line to your /etc/rc file: /bin/mioclock ; date Thanx to tom poindexter for the original astclock code. And now for the program: mioclock.c ---/---/---/---/---/---/---/ TEAR HERE ---/---/---/---/---/---/---/--- /* mioclock.c - read the clock on the multi i/o card from mct */ /* original code from astclock.c, tom poindexter, 4/87 */ /* modified for use with mio card, mike mitchell, 5/87 */ #include "stdio.h" int days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; struct tm { int year, month, day, hour, min, sec; }; /* define the current decade */ #define DECADE 80 /* ports for the mio clock */ #define MIO_SEC 0x02c2 #define MIO_MIN 0x02c3 #define MIO_HRS 0x02c4 #define MIO_DOW 0x02c5 #define MIO_DOM 0x02c6 #define MIO_MOY 0x02c7 #define MIO_YER 0x02ca #define TRIES 10 /******************************************************************/ main() { struct tm tm1; struct tm tm2; int i; long t; long calc_sec(); int stime(); /* stime() sets the date in minix */ /* try several times to read the clock */ for (i = 0; i < TRIES; i++) { read_clk(&tm1); /* read the clock twice */ read_clk(&tm2); if (tm1.year == tm2.year && /* and compare the results */ tm1.month == tm2.month && tm1.day == tm2.day && tm1.hour == tm2.hour && tm1.min == tm2.min && tm1.sec == tm2.sec) { t = calc_sec(&tm1); /* calculate the seconds */ if (stime(&t) == -1) { /* and set the time */ die("mioclock: can't set stime(), are you super user?\n"); } exit(0); /* normal termination */ } } /* too many errors in reading the ast clock chip, give up */ die("mioclock: can't get a consistent time from the ast clock"); } /* calculate seconds since epoch; this code borrowed from `date.c' */ long calc_sec(tp) struct tm *tp; { int i = 0; long ct; long s_p_min; long s_p_hour; long s_p_day; long s_p_year; /* first, calculate seconds per known intervals */ 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; /* calculate seconds from epoch until the start of this year */ tp->year -= 70; /* deal with years since 1970 */ ct = tp->year * s_p_year; /* seconds per year since epoch */ ct += ((tp->year + 1) / 4) * s_p_day; /* add in the leap years and */ if (((tp->year + 2) % 4) == 0) { /* check if this year is a leap */ days_per_month[1]++; /* and make feb one more day */ } /* calculate seconds from january until the start of this month */ tp->month--; while (i < tp->month) { ct += days_per_month[i++] * s_p_day; } /* calculate seconds of the days this month */ ct += --tp->day * s_p_day; /* calculate seconds of the hour this day */ ct += tp->hour * s_p_hour; /* calculate seconds of the minutes this hour */ ct += tp->min * s_p_min; /* and finally add in the seconds so far this minute */ ct += tp->sec; return (ct); } /* read the mio clock and fill values into a tm structure */ read_clk(tp) struct tm *tp; { int r; port_in(MIO_YER, &r); tp->year = DECADE + btod(r); port_in(MIO_MOY, &r); tp->month = btod(r); port_in(MIO_DOM, &r); tp->day = btod(r); port_in(MIO_HRS, &r); tp->hour = btod(r); port_in(MIO_MIN, &r); tp->min = btod(r); port_in(MIO_SEC, &r); tp->sec = btod(r); } /* die() - print a message on stderr and exit with false code */ die(msg) char *msg; { fprintf(stderr,msg); fflush(stderr); _cleanup(); exit(1); } /* btod - bcd to decimal conversion */ int btod(num) int num; { return(((num & 0x00f0) >> 4) * 10 + (num & 0x000f)); } ---/---/---/---/---/---/---/ TEAR HERE ---/---/---/---/---/---/---/--- port_io.s ---/---/---/---/---/---/---/ TEAR HERE ---/---/---/---/---/---/---/--- | this file was grafted from klib88.s .globl _port_out, _port_in |*===========================================================================* |* port_out * |*===========================================================================* | port_out(port, value) writes 'value' on the I/O port 'port'. _port_out: push bx | save bx mov bx,sp | index off bx push ax | save ax push dx | save dx mov dx,4(bx) | dx = port mov ax,6(bx) | ax = value out | output 1 byte pop dx | restore dx pop ax | restore ax pop bx | restore bx ret | return to caller |*===========================================================================* |* port_in * |*===========================================================================* | port_in(port, &value) reads from port 'port' and puts the result in 'value'. _port_in: push bx | save bx mov bx,sp | index off bx push ax | save ax push dx | save dx mov dx,4(bx) | dx = port in | input 1 byte xorb ah,ah | clear ah mov bx,6(bx) | fetch address where byte is to go mov (bx),ax | return byte to caller in param pop dx | restore dx pop ax | restore ax pop bx | restore bx ret | return to caller ---/---/---/---/---/---/---/ TEAR HERE --- of qantepop ad to thet have