home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / os / minix / 3770 / xt_clock.lzh / readclock.c next >
Encoding:
C/C++ Source or Header  |  1992-07-25  |  5.4 KB  |  191 lines

  1. /* readclock - read the AT real time clock    Authors: T. Holm & E. Froese */
  2.  
  3. /************************************************************************/
  4. /*                                    */
  5. /*   readclock.c                            */
  6. /*                                    */
  7. /*        Read the AT real time clock, write the time to        */
  8. /*        standard output in a form usable by date(1).        */
  9. /*        If the system is an AT then the time is read        */
  10. /*        from the built-in clock, and written to standard    */
  11. /*        output in the form:                    */
  12. /*                                    */
  13. /*            mmddyyhhmmss                    */
  14. /*                                    */
  15. /*        If the system is not an AT then ``-q'' is written     */
  16. /*        to standard output. This is useful for placement in    */
  17. /*        the ``/etc/rc'' script:                    */
  18. /*                                    */
  19. /*           /usr/bin/date `/usr/bin/readclock` </dev/tty      */
  20. /*                                    */
  21. /************************************************************************/
  22. /*    origination          1987-Dec-29              efth                */
  23. /************************************************************************/
  24.  
  25. /************************************************************************
  26.  *    modified to load the Minix software clock from the battery        *
  27.  *    backed read-time clock on the PC-XT multi-function board.         *
  28.  *                                                                      *
  29.  *         The clock Port address are 0x02c0 - 0x2cf                    *
  30.  *                                                                      *
  31.  *    Modified by Robert R. Hall (hall@pnet01.cts.com)                  *
  32.  *    Date: 25 Jul 1992                                                 *
  33.  *                                                                      *
  34.  ************************************************************************/
  35.  
  36.  
  37. #include <time.h>
  38. #include <stdio.h>
  39.  
  40. #define CPU_TYPE_SEGMENT   0xFFFF    /* BIOS segment for CPU type      */
  41. #define CPU_TYPE_OFFSET    0x000E    /* BIOS offset for CPU type      */
  42. #define PC_AT              0xFC        /* IBM code for PC-AT (0xFFFFE) */
  43. #define PS_386        0xF8        /* IBM code for 386 PS/2's */
  44. #define PC_XT        0xFE
  45.  
  46.  
  47. #define CLK_ELE 0x70            /* ptr corresponding to element
  48.                        of time to be */
  49. #define CLK_IO 0x02C0            /* read or written is written
  50.                        to port clk_ele */
  51. #define CLK_STAT 0x02CD
  52. /* The element can then be read or written by */
  53. /* Reading or writing port clk_io.            */
  54.  
  55. #define  YEAR            10        /* Clock register addresses     */
  56. #define  MONTH            8
  57. #define  DAY              6
  58. #define  HOUR             4
  59. #define  MINUTE           2
  60. #define  SECOND           0
  61. #define  STATUS           0x0b
  62.  
  63. #define  BCD_TO_DEC(x)      ( (x>>4) * 10 + (x & 0x0f) )
  64.  
  65.  
  66. struct time
  67. {
  68.    unsigned        year;
  69.    unsigned        month;
  70.    unsigned        day;
  71.    unsigned        hour;
  72.    unsigned        minute;
  73.    unsigned        second;
  74. };
  75.  
  76.  
  77.  
  78. main()
  79. {
  80.    struct time     time1;
  81.    int             i;
  82.    int             cpu_type;
  83.  
  84.    cpu_type = peek(CPU_TYPE_SEGMENT, CPU_TYPE_OFFSET);
  85.    if ((cpu_type != PC_XT) || (chk_clk() != 0))
  86.    {
  87.       printf("-q\n");
  88.       fprintf(stderr, "readclock ERROR: chk_chk\n");
  89.       exit(1);
  90.    }
  91.    get_time(&time1);
  92.    printf("%02d%02d%02d%02d%02d%02d\n",
  93.        time1.month, time1.day, time1.year,
  94.        time1.hour, time1.minute, time1.second);
  95.    exit(0);
  96. }
  97.  
  98.  
  99.  
  100. /***********************************************************************/
  101. /*                                                                     */
  102. /*    get_time( time )                                                 */
  103. /*                                                                     */
  104. /*    Update the structure pointed to by time with the current time    */
  105. /*    as read from the hardware real-time clock of the AT.             */
  106. /*    If necessary, the time is converted into a binary format before  */
  107. /*    being stored in the structure.                                   */
  108. /*                                                                     */
  109. /***********************************************************************/
  110.  
  111. get_time(t)
  112.    struct time    *t;
  113. {
  114.    t->year = read_register(YEAR) + 80;
  115.    t->month = read_register(MONTH);
  116.    t->day = read_register(DAY);
  117.    t->hour = read_register(HOUR);
  118.    t->minute = read_register(MINUTE);
  119.    t->second = read_register(SECOND);
  120. }
  121.  
  122.  
  123. read_register(reg_addr)
  124.    char            reg_addr;
  125. {
  126.    int             units, tens;
  127.    unsigned        port;
  128.  
  129.    port = CLK_IO + reg_addr;
  130.    if (read_port(port, &units) < 0 || read_port(port + 1, &tens) < 0)
  131.    {
  132.       printf("-q\n");
  133.       fprintf(stderr, "readclock ERROR: read_register\n");
  134.       exit(1);
  135.    }
  136.    return ((tens & 0x0F) * 10 + (units & 0x0F));
  137. }
  138.  
  139. read_port(port, value)
  140.    unsigned        port;
  141.    int            *value;
  142. {
  143.    int             status, io_result;
  144.    int             i;
  145.  
  146.    for (i = 256; i > 0; i--)
  147.    {
  148.       io_result = port_in(CLK_STAT, &status);
  149.       port_out(CLK_STAT, status | 1);
  150.       io_result = port_in(CLK_STAT, &status);
  151.       if ((status & 2) == 0)
  152.      break;
  153.       port_out(CLK_STAT, status & 0xFE);
  154.    }
  155.  
  156.    if (i == 0)
  157.       return (-1);
  158.    io_result = port_in(port, value);
  159.    port_out(CLK_STAT, status & 0xFE);
  160.    return (io_result);
  161. }
  162.  
  163. int 
  164. chk_clk()
  165. {
  166.    unsigned        sec0, sec1;
  167.    time_t          t0, t1;
  168.  
  169.  
  170.    if (read_port(SECOND, &sec0) < 0)
  171.    {
  172.       fprintf(stderr, "No Real time clock installed.\n");
  173.       return (-1);
  174.    }
  175.    time(&t0);
  176.  
  177.    do
  178.    {
  179.       read_port(SECOND, &sec1);
  180.       if (sec1 > sec0)
  181.      break;
  182.       time(&t1);
  183.    }
  184.    while (t1 < (t0 + 2));
  185.  
  186.    if (sec1 > sec0)
  187.       return (0);
  188.    else
  189.       return (-1);
  190. }
  191.