home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / os / minix / 3770 / xt_clock.lzh / setclock.c < prev   
Encoding:
C/C++ Source or Header  |  1991-11-11  |  4.9 KB  |  200 lines

  1. /* setclock - set the AT real time clock    Author: Stefan Schroer    */
  2. /*              derived from 'readclock' by  T. Holm & E. Froese    */
  3.  
  4. /************************************************************************/
  5. /*                                    */
  6. /*   setclock.c                                */
  7. /*                                    */
  8. /*        Read the current gmtime from the PC.            */
  9. /*        If the system is an AT then the time is written        */
  10. /*        into the hardware real time clock.            */
  11. /*                                    */
  12. /*        If the system is not an AT then an error message    */
  13. /*        is written to standard output.                */
  14. /*                                    */
  15. /************************************************************************/
  16. /*    setclock             1991-Oct-24              sts                 */
  17. /*    origination          1987-Dec-29              efth                */
  18. /************************************************************************/
  19.  
  20.  
  21. #include <time.h>
  22. #include <stdio.h>
  23.  
  24. #define CPU_TYPE_SEGMENT   0xFFFF    /* BIOS segment for CPU type      */
  25. #define CPU_TYPE_OFFSET    0x000E    /* BIOS offset for CPU type      */
  26. #define PC_AT              0xFC        /* IBM code for PC-AT (0xFFFFE) */
  27. #define PS_386           0xF8        /* IBM code for 386 PS/2's */
  28. #define PC_XT           0xFE
  29.  
  30.  
  31. #define CLK_ELE 0x70            /* ptr corresponding to element
  32.                        of time to be */
  33. #define CLK_IO 0x02C0            /* read or written is written
  34.                        to port clk_ele */
  35. #define CLK_STAT 0x02CD
  36. /* The element can then be read or written by */
  37. /* Reading or writing port clk_io.            */
  38.  
  39. #define  YEAR            10        /* Clock register addresses     */
  40. #define  MONTH            8
  41. #define  DAY              6
  42. #define  HOUR             4
  43. #define  MINUTE           2
  44. #define  SECOND           0
  45. #define  STATUS           0x0b
  46.  
  47. #define  DEC_TO_BCD(x)    (( ((x/10) << 4) + (x % 10) ) & 0xff)
  48.  
  49.  
  50. main()
  51. {
  52.    struct tm      *tm;
  53.    time_t          t;
  54.    int             i;
  55.    int             cpu_type;
  56.  
  57.    cpu_type = peek(CPU_TYPE_SEGMENT, CPU_TYPE_OFFSET);
  58.    if ((cpu_type != PC_XT) || (chk_clk() != 0))
  59.    {
  60.       fprintf(stderr, "This computer doesn't have a non volatile ram\n");
  61.       exit(1);
  62.    }
  63.    time(&t);
  64.    tm = gmtime(&t);
  65.    set_time(tm);
  66.  
  67.    exit(0);
  68. }
  69.  
  70.  
  71.  
  72. /************************************************************************/
  73. /*                                                                         */
  74. /*    set_time( time )                                                     */
  75. /*                                                                         */
  76. /*    Update the hardware real-time clock of the AT.            */
  77. /*    Set the clock mode to BCD format if mode is binary.        */
  78. /*                                                                         */
  79. /************************************************************************/
  80.  
  81. set_time(t)
  82.    struct tm      *t;
  83. {
  84.    write_register(YEAR, t->tm_year - 80);
  85.    write_register(MONTH, t->tm_mon + 1);
  86.    write_register(DAY, t->tm_mday);
  87.    write_register(HOUR, t->tm_hour);
  88.    write_register(MINUTE, t->tm_min);
  89.    write_register(SECOND, t->tm_sec);
  90. }
  91.  
  92.  
  93. read_register(reg_addr)
  94.    char            reg_addr;
  95. {
  96.    int             units, tens;
  97.    unsigned        port;
  98.  
  99.    port = CLK_IO + reg_addr;
  100.    if (read_port(port, &units) < 0 || read_port(port + 1, &tens) < 0)
  101.    {
  102.       printf("-q\n");
  103.       exit(1);
  104.    }
  105.    return ((tens & 0x0F) * 10 + (units & 0x0F));
  106. }
  107.  
  108. write_register(reg_addr, reg_value)
  109.    char            reg_addr;
  110.    int             reg_value;
  111. {
  112.    unsigned        port;
  113.  
  114.    port = CLK_IO + reg_addr;
  115.    if (write_port(port, reg_value % 10) < 0 ||
  116.        write_port(port + 1, reg_value / 10) < 0)
  117.    {
  118.       fprintf(stderr, "setclock: error writing hardware clock.\n");
  119.       exit(1);
  120.    }
  121. }
  122.  
  123. write_port(port, value)
  124.    unsigned        port;
  125.    int             value;
  126. {
  127.    int             status, io_result;
  128.    int             i;
  129.  
  130.    for (i = 256; i > 0; i--)
  131.    {
  132.       io_result = port_in(CLK_STAT, &status);
  133.       port_out(CLK_STAT, status | 1);
  134.       io_result = port_in(CLK_STAT, &status);
  135.       if ((status & 2) == 0)
  136.      break;
  137.       port_out(CLK_STAT, status & 0xFE);
  138.    }
  139.  
  140.    if (i == 0)
  141.       return (-1);
  142.    io_result = port_out(port, value);
  143.    port_out(CLK_STAT, status & 0xFE);
  144.    return (io_result);
  145. }
  146.  
  147.  
  148. read_port(port, value)
  149.    unsigned        port;
  150.    int            *value;
  151. {
  152.    int             status, io_result;
  153.    int             i;
  154.  
  155.    for (i = 256; i > 0; i--)
  156.    {
  157.       io_result = port_in(CLK_STAT, &status);
  158.       port_out(CLK_STAT, status | 1);
  159.       io_result = port_in(CLK_STAT, &status);
  160.       if ((status & 2) == 0)
  161.      break;
  162.       port_out(CLK_STAT, status & 0xFE);
  163.    }
  164.  
  165.    if (i == 0)
  166.       return (-1);
  167.    io_result = port_in(port, value);
  168.    port_out(CLK_STAT, status & 0xFE);
  169.    return (io_result);
  170. }
  171.  
  172. int
  173. chk_clk()
  174. {
  175.    unsigned        sec0, sec1;
  176.    time_t          t0, t1;
  177.  
  178.  
  179.    if (read_port(SECOND, &sec0) < 0)
  180.    {
  181.       fprintf(stderr, "No Real time clock installed.\n");
  182.       return (-1);
  183.    }
  184.    time(&t0);
  185.  
  186.    do
  187.    {
  188.       read_port(SECOND, &sec1);
  189.       if (sec1 > sec0)
  190.      break;
  191.       time(&t1);
  192.    }
  193.    while (t1 < (t0 + 2));
  194.  
  195.    if (sec1 > sec0)
  196.       return (0);
  197.    else
  198.       return (-1);
  199. }
  200.