home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / pc_hw / timer / uclock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-25  |  1.5 KB  |  66 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <time.h>
  4. #include <pc.h>
  5. #include <libc/farptrgs.h>
  6. #include <go32.h>
  7. #include <libc/bss.h>
  8.  
  9. static int uclock_bss = -1;
  10.  
  11. /* tics = about 18.2 * 65536 (1,192,755)
  12.  
  13.    actually, it's   0x1800b0 tics/day (FAQ)
  14.                   / 24*60*60 sec/day
  15.                   * 65536 utics/tic
  16.           = 1,193,180 utics/sec */
  17.  
  18. uclock_t
  19. uclock(void)
  20. {
  21.   static uclock_t base = 0;
  22.   static unsigned long last_tics = 0;
  23.   unsigned char lsb, msb;
  24.   unsigned long tics, otics;
  25.   uclock_t rv;
  26.  
  27.   if (uclock_bss != __bss_count)
  28.   {
  29.     /* switch the timer to mode 2 (rate generator) */
  30.     /* rather than mode 3 (square wave), which doesn't count linearly. */
  31.  
  32.     outportb(0x43, 0x34);
  33.     outportb(0x40, 0xff);
  34.     outportb(0x40, 0xff);
  35.  
  36.     base = 0;
  37.     last_tics = 0;
  38.     uclock_bss = __bss_count;
  39.   }
  40.  
  41.   /* Make sure the numbers we get are consistent */
  42.   do {
  43.     otics = _farpeekl(_dos_ds, 0x46c);
  44.     outportb(0x43, 0x00);
  45.     lsb = inportb(0x40);
  46.     msb = inportb(0x40);
  47.     tics = _farpeekl(_dos_ds, 0x46c);
  48.   } while (otics != tics);
  49.  
  50.   /* calculate absolute time */
  51.   msb ^= 0xff;
  52.   lsb ^= 0xff;
  53.   rv = ((uclock_t)tics << 16) | (msb << 8) | lsb;
  54.  
  55.   if (base == 0L)
  56.     base = rv;
  57.  
  58.   if (last_tics > tics) /* midnight happened */
  59.     base -= 0x1800b00000LL;
  60.  
  61.   last_tics = tics;
  62.  
  63.   /* return relative time */
  64.   return rv - base;
  65. }
  66.