home *** CD-ROM | disk | FTP | other *** search
- /* readclock - read the AT real time clock Authors: T. Holm & E. Froese */
-
- /************************************************************************/
- /* */
- /* readclock.c */
- /* */
- /* Read the AT real time clock, write the time to */
- /* standard output in a form usable by date(1). */
- /* If the system is an AT then the time is read */
- /* from the built-in clock, and written to standard */
- /* output in the form: */
- /* */
- /* mmddyyhhmmss */
- /* */
- /* If the system is not an AT then ``-q'' is written */
- /* to standard output. This is useful for placement in */
- /* the ``/etc/rc'' script: */
- /* */
- /* /usr/bin/date `/usr/bin/readclock` </dev/tty */
- /* */
- /************************************************************************/
- /* origination 1987-Dec-29 efth */
- /************************************************************************/
-
- /************************************************************************
- * modified to load the Minix software clock from the battery *
- * backed read-time clock on the PC-XT multi-function board. *
- * *
- * The clock Port address are 0x02c0 - 0x2cf *
- * *
- * Modified by Robert R. Hall (hall@pnet01.cts.com) *
- * Date: 25 Jul 1992 *
- * *
- ************************************************************************/
-
-
- #include <time.h>
- #include <stdio.h>
-
- #define CPU_TYPE_SEGMENT 0xFFFF /* BIOS segment for CPU type */
- #define CPU_TYPE_OFFSET 0x000E /* BIOS offset for CPU type */
- #define PC_AT 0xFC /* IBM code for PC-AT (0xFFFFE) */
- #define PS_386 0xF8 /* IBM code for 386 PS/2's */
- #define PC_XT 0xFE
-
-
- #define CLK_ELE 0x70 /* ptr corresponding to element
- of time to be */
- #define CLK_IO 0x02C0 /* read or written is written
- to port clk_ele */
- #define CLK_STAT 0x02CD
- /* The element can then be read or written by */
- /* Reading or writing port clk_io. */
-
- #define YEAR 10 /* Clock register addresses */
- #define MONTH 8
- #define DAY 6
- #define HOUR 4
- #define MINUTE 2
- #define SECOND 0
- #define STATUS 0x0b
-
- #define BCD_TO_DEC(x) ( (x>>4) * 10 + (x & 0x0f) )
-
-
- struct time
- {
- unsigned year;
- unsigned month;
- unsigned day;
- unsigned hour;
- unsigned minute;
- unsigned second;
- };
-
-
-
- main()
- {
- struct time time1;
- int i;
- int cpu_type;
-
- cpu_type = peek(CPU_TYPE_SEGMENT, CPU_TYPE_OFFSET);
- if ((cpu_type != PC_XT) || (chk_clk() != 0))
- {
- printf("-q\n");
- fprintf(stderr, "readclock ERROR: chk_chk\n");
- exit(1);
- }
- get_time(&time1);
- printf("%02d%02d%02d%02d%02d%02d\n",
- time1.month, time1.day, time1.year,
- time1.hour, time1.minute, time1.second);
- exit(0);
- }
-
-
-
- /***********************************************************************/
- /* */
- /* get_time( time ) */
- /* */
- /* Update the structure pointed to by time with the current time */
- /* as read from the hardware real-time clock of the AT. */
- /* If necessary, the time is converted into a binary format before */
- /* being stored in the structure. */
- /* */
- /***********************************************************************/
-
- get_time(t)
- struct time *t;
- {
- t->year = read_register(YEAR) + 80;
- t->month = read_register(MONTH);
- t->day = read_register(DAY);
- t->hour = read_register(HOUR);
- t->minute = read_register(MINUTE);
- t->second = read_register(SECOND);
- }
-
-
- read_register(reg_addr)
- char reg_addr;
- {
- int units, tens;
- unsigned port;
-
- port = CLK_IO + reg_addr;
- if (read_port(port, &units) < 0 || read_port(port + 1, &tens) < 0)
- {
- printf("-q\n");
- fprintf(stderr, "readclock ERROR: read_register\n");
- exit(1);
- }
- return ((tens & 0x0F) * 10 + (units & 0x0F));
- }
-
- read_port(port, value)
- unsigned port;
- int *value;
- {
- int status, io_result;
- int i;
-
- for (i = 256; i > 0; i--)
- {
- io_result = port_in(CLK_STAT, &status);
- port_out(CLK_STAT, status | 1);
- io_result = port_in(CLK_STAT, &status);
- if ((status & 2) == 0)
- break;
- port_out(CLK_STAT, status & 0xFE);
- }
-
- if (i == 0)
- return (-1);
- io_result = port_in(port, value);
- port_out(CLK_STAT, status & 0xFE);
- return (io_result);
- }
-
- int
- chk_clk()
- {
- unsigned sec0, sec1;
- time_t t0, t1;
-
-
- if (read_port(SECOND, &sec0) < 0)
- {
- fprintf(stderr, "No Real time clock installed.\n");
- return (-1);
- }
- time(&t0);
-
- do
- {
- read_port(SECOND, &sec1);
- if (sec1 > sec0)
- break;
- time(&t1);
- }
- while (t1 < (t0 + 2));
-
- if (sec1 > sec0)
- return (0);
- else
- return (-1);
- }
-