home *** CD-ROM | disk | FTP | other *** search
- /* setclock - set the AT real time clock Author: Stefan Schroer */
- /* derived from 'readclock' by T. Holm & E. Froese */
-
- /************************************************************************/
- /* */
- /* setclock.c */
- /* */
- /* Read the current gmtime from the PC. */
- /* If the system is an AT then the time is written */
- /* into the hardware real time clock. */
- /* */
- /* If the system is not an AT then an error message */
- /* is written to standard output. */
- /* */
- /************************************************************************/
- /* setclock 1991-Oct-24 sts */
- /* origination 1987-Dec-29 efth */
- /************************************************************************/
-
-
- #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 DEC_TO_BCD(x) (( ((x/10) << 4) + (x % 10) ) & 0xff)
-
-
- main()
- {
- struct tm *tm;
- time_t t;
- int i;
- int cpu_type;
-
- cpu_type = peek(CPU_TYPE_SEGMENT, CPU_TYPE_OFFSET);
- if ((cpu_type != PC_XT) || (chk_clk() != 0))
- {
- fprintf(stderr, "This computer doesn't have a non volatile ram\n");
- exit(1);
- }
- time(&t);
- tm = gmtime(&t);
- set_time(tm);
-
- exit(0);
- }
-
-
-
- /************************************************************************/
- /* */
- /* set_time( time ) */
- /* */
- /* Update the hardware real-time clock of the AT. */
- /* Set the clock mode to BCD format if mode is binary. */
- /* */
- /************************************************************************/
-
- set_time(t)
- struct tm *t;
- {
- write_register(YEAR, t->tm_year - 80);
- write_register(MONTH, t->tm_mon + 1);
- write_register(DAY, t->tm_mday);
- write_register(HOUR, t->tm_hour);
- write_register(MINUTE, t->tm_min);
- write_register(SECOND, t->tm_sec);
- }
-
-
- 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");
- exit(1);
- }
- return ((tens & 0x0F) * 10 + (units & 0x0F));
- }
-
- write_register(reg_addr, reg_value)
- char reg_addr;
- int reg_value;
- {
- unsigned port;
-
- port = CLK_IO + reg_addr;
- if (write_port(port, reg_value % 10) < 0 ||
- write_port(port + 1, reg_value / 10) < 0)
- {
- fprintf(stderr, "setclock: error writing hardware clock.\n");
- exit(1);
- }
- }
-
- write_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_out(port, value);
- port_out(CLK_STAT, status & 0xFE);
- return (io_result);
- }
-
-
- 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);
- }
-