MEGEVAND%CGEUGE51.BITNET@cunyvm.cuny.edu (02/02/88)
Hello,
My XT Clone also has a Calendar/Clock on a card labelled "Multi I/O"
that also contains the Floppy Disk controller, a parallel port, a serial port
and a joystick controller port.
I tried to use three programs posted on this group to read the battery
backup clock: One was for the AT clock. Another was for an AST card, and the
last was for another Multi-I/O card. None of the three worked.
So, as the other guys, I debugged my own card program, and was soon able
to read the date and time from the card and set the minix date at boot time.
Here is a shar file: This is my contribution in case someone uses the
same card as me.
================================================================================
E-Mail: || Denis Megevand
megevand@cgeuge51.bitnet || Geneva Observatory
=================================== || 51 ch. des Maillettes
soon to be || CH-1290 SAUVERNY
megevand@cgeuge54.bitnet || SWITZERLAND
================================================================================
--------------------------- cut here ------------------------------------------
#
# This is a shar archive, extract it with sh, not csh.
# The rest of this file will extract:
# Makefile, timedate.c, port_io.s
#
echo x - Makefile
gres '^X' '' > Makefile << '/'
X#makefile for "timedate"
X
Xall:
X cc -F -o /usr/bin/timedate timedate.c port_io.s
X
X
/
echo x - timedate.c
gres '^X' '' > timedate.c << '/'
X/* timedate.c - get date and time from a Multi I/O Card
X * and print on standard out. Format is MMDDYYHHMMSS
X * as required by "date".
X * Should be run in /etc/rc as: date `/usr/bin/timedate`
X * Compile as: cc -F -o timedate timedate.c port_io.s
X *
X * Author: Denis Megevand - January 1988
X * (adapted from other utilities)
X */
X
X#include <stdio.h>
X
Xstruct tm {
X int year;
X int month;
X int day;
X int hour;
X int min;
X int sec;
X};
X
X/* Ports for the hard clock:
X * You need to read both ports until bit0 of result is 0
X * before getting date.
X */
X
X#define CLK_PORT 0x0377
X#define CLK_STATUS 0x5377
X
X/* Data ports on the hard clock:
X * Data returned is two BCD digits
X */
X
X#define SECONDS 0x0B77
X#define MINUTES 0x0F77
X#define HOURS 0x1377
X#define DAY 0x1B77
X#define MONTH 0x1F77
X
X/* Data ports on the hard clock:
X * Data returned is encoded as 11xx11xx
X */
X
X#define YEAR_LOW 0x2777
X#define YEAR_HIGH 0x2377
X
X/* Bit masks */
X
X#define BIT_0 0x01
X#define BITS1_0 0x03
X#define BITS3_2 0x0C
X#define BITS3_0 0x0F
X#define BITS5_4 0x30
X#define BITS7_6 0xC0
X#define BITS7_4 0xF0
X
X/* Maximum number of times to read clock */
X
X#define TRIES 10
X
X
Xmain(argc, argv)
X int argc;
X char *argv[];
X{
X struct tm tm1;
X struct tm tm2;
X int i;
X
X/* Try several times to read the clock.*/
X
X for (i = 0; i < TRIES; i++)
X {
X read_clk(&tm1); /* read the clock twice */
X read_clk(&tm2);
X
X if ( tm1.year == tm2.year /* and compare the results */
X && tm1.month == tm2.month
X && tm1.day == tm2.day
X && tm1.hour == tm2.hour
X && tm1.min == tm2.min
X && tm1.sec == tm2.sec)
X {
X printf("%02d%02d%02d%02d%02d%02d\n",
X tm1.month, tm1.day, tm1.year,
X tm1.hour, tm1.min, tm1.sec);
X exit(0); /* normal termination */
X }
X }
X
X/* too many errors in reading the clock give up */
X
X fprintf(stderr, "%s: hard clock unstable\n", argv[0]);
X fflush(stderr);
X _cleanup();
X exit(1);
X}
X
X/* read the hard clock and fill values into a tm structure */
X
Xread_clk(tp)
X struct tm *tp;
X{
X int tmp;
X
X do {
X port_in(CLK_PORT, &tmp); /* prepare clock */
X port_in(CLK_STATUS, &tmp);
X } while (tmp & BIT_0 != 0);
X
X tp->year = 80 + get_val(YEAR_HIGH) * 4 + get_val(YEAR_LOW);
X tp->month = get_BCD(MONTH);
X tp->day = get_BCD(DAY);
X tp->hour = get_BCD(HOURS);
X tp->min = get_BCD(MINUTES);
X tp->sec = get_BCD(SECONDS);
X
X}
X
X/* get_val() - read a encoded register from the hard clock */
X
Xint get_val(reg)
X
X int reg;
X
X{
X int val;
X
X port_in (reg, &val); /* get the value of the reg */
X
X return ((val & BITS1_0) + ((val / 4) & BITS3_2));
X
X}
X
X/* get_BCD() - read a BCD register from the hard clock */
X
Xint get_BCD(reg)
X
X int reg;
X
X{
X int val;
X
X port_in (reg, &val); /* get the value of the reg */
X
X return ((val & BITS7_4) / 16 * 10 + (val & BITS3_0));
X
X}
X
/
echo x - port_io.s
gres '^X' '' > port_io.s << '/'
X| this file was grafted from klib88.s
X
X.globl _port_out, _port_in
X
X
X
X|*===========================================================================*
X|* port_out *
X|*===========================================================================*
X| port_out(port, value) writes 'value' on the I/O port 'port'.
X
X_port_out:
X push bx | save bx
X mov bx,sp | index off bx
X push ax | save ax
X push dx | save dx
X mov dx,4(bx) | dx = port
X mov ax,6(bx) | ax = value
X out | output 1 byte
X pop dx | restore dx
X pop ax | restore ax
X pop bx | restore bx
X ret | return to caller
X
X
X|*===========================================================================*
X|* port_in *
X|*===========================================================================*
X| port_in(port, &value) reads from port 'port' and puts the result in 'value'.
X_port_in:
X push bx | save bx
X mov bx,sp | index off bx
X push ax | save ax
X push dx | save dx
X mov dx,4(bx) | dx = port
X in | input 1 byte
X xorb ah,ah | clear ah
X mov bx,6(bx) | fetch address where byte is to go
X mov (bx),ax | return byte to caller in param
X pop dx | restore dx
X pop ax | restore ax
X pop bx | restore bx
X ret | return to caller
/