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