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 /