home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / turbo_c / timertst.c < prev    next >
Internet Message Format  |  1989-04-25  |  4KB

  1. From: osh@cbnewsh.ATT.COM (david.a.oshinsky)
  2. Newsgroups: comp.sys.ibm.pc
  3. Subject: Re: Turbo C timer interrupt handler
  4. Date: 24 Apr 89 22:01:20 GMT
  5. Keywords: turbo C interrupt handler
  6. Summary: short Turbo C program
  7.  
  8. The following program demonstrates how to handle timer interrupts
  9. from Turbo C.
  10.             Hope this helps,
  11.             David Oshinsky
  12.             AT&T Bell Laboratories
  13.             Holmdel, NJ
  14.         phone:    (201)949-0037
  15.         uucp:    att!houxs!osh
  16.  
  17. ------------------------- Cut here --------------------------
  18. /* 8253 timer test program for Turbo C 1.5/2.0.           */
  19. /* Author:  David Oshinsky, 11/14/88.               */
  20.  
  21. /* This program demonstrates how to use counter 0 in the   */
  22. /* 8253 chip to provide "real-time clock" functions on the */
  23. /* IBM PC or PC/AT.                       */
  24.  
  25. /* SOME QUICK INFO ON PC INTERRUPTS:               */
  26. /* The interrupt lines INT2 through INT7 appear on the PC  */
  27. /* bus.  INT0 and INT1 appear only on the motherboard.     */
  28. /* Interrupt line usage is as follows:               */
  29. /*    INT0 is used by counter 0 of the 8253 programmable */
  30. /*        interval timer chip               */
  31. /*    INT1 is used by the keyboard               */
  32. /*    INT5 is used by the hard disk controller       */
  33. /*    INT6 is used by the floppy disk controller       */
  34.  
  35. /* The above is not completely accurate when applied to       */
  36. /* the PC/AT; however, the timer interrupt uses INT0 on       */
  37. /* both the PC and PC/AT.  (This program works on both the */
  38. /* PC and the PC/AT.)                       */
  39.  
  40. /* The 8259 Peripheral Interrupt Controller (PIC) chip       */
  41. /* maps the INTx line to interrupt number x+8 (this is       */
  42. /* programmable, set by MS-DOS).  Hence, the timer       */
  43. /* interrupt is number 8.                   */
  44.  
  45. #include <dos.h>
  46.  
  47. #define ZERO_FLAG    0x040
  48. #define CONTROL_C    3
  49. #define MS_PER_TICK    53    /* milliseconds per IBM PC clock tick */
  50.  
  51. unsigned long count;
  52. unsigned ticks;
  53. void interrupt timer(), interrupt (*old_handler)();
  54.  
  55. main()
  56. {
  57.     union REGS sreg, rreg;
  58.  
  59.     /* time starts at zero */
  60.     count = 0;
  61.     ticks = 0;
  62.  
  63.     /* initializations related to MS-DOS call to read keyboard */
  64.     sreg.x.dx = 0xff;
  65.     sreg.h.ah = 0x06;
  66.     
  67.     printf("\nTo stop the timer test program, type CTRL-C.");
  68.     printf("\nTo display time since starting the program, hit any key.");
  69.     printf("\nThe time is accurate to roughly the nearest 1 msec.\n\n");
  70.     
  71.     /* Save the address of the current timer interrupt handler */
  72.     old_handler = getvect(8);
  73.  
  74.     /* Call "timer" function when timer interrupt occurs. */
  75.     setvect(8, timer);
  76.     
  77.     /* Set up 8259 PIC chip to allow INT0 interrupt. */
  78.     outportb(0x21, inportb(0x21) & 0xfe);
  79.     
  80.     /* issue command to 8253:  counter 0, binary counter, rate generator */
  81.     /* (mode 2), load least significant byte of counter followed by      */
  82.     /* most significant byte                         */
  83.     outportb(0x43, 0x34);
  84.     
  85.     /* Timer is set for 0x4cd * 813.8 ns = 1 ms (LSB followed by MSB). */
  86.     outportb(0x40, 0xcd); /* least significant byte of timer count */
  87.     outportb(0x40, 0x04); /* most significant byte of timer count  */
  88.     
  89.     while (1) {
  90.         /* wait for keystroke */
  91.         while ( 1 ) {
  92.             intdos(&sreg, &rreg);
  93.             if ( ! (rreg.x.flags & ZERO_FLAG) )
  94.                 break;
  95.             }
  96.     
  97.         /* stop the program if ctrl-C */
  98.         if ( (rreg.x.ax & 0xff) == CONTROL_C ) {
  99.             /* NOTE:  the following code MUST be executed before  */
  100.             /* returning to MS-DOS in order to allow proper          */
  101.             /* operation of programs which use the 8253 timer.    */
  102.     
  103.             /* restore 8253 to original state set during PC boot  */
  104.             /* NOTE:  this program leaves 8259 mask register with */
  105.             /* least significant bit clear (i.e., INT0 enabled).  */
  106.             outportb(0x43, 0x34);
  107.             outportb(0x40, 0);
  108.             outportb(0x40, 0);
  109.     
  110.             /* restore original interrupt vector for number 8 */
  111.             setvect(8, old_handler);
  112.     
  113.             printf("Timer test program returning to MS-DOS.\n");
  114.             exit(0);
  115.         }
  116.         else
  117.             printf("TIME = %lu MSEC.\n",count);
  118.     }
  119. }
  120.     
  121. /* timer interrupt service routine (interrupt number 8) */
  122. void interrupt
  123. timer()
  124. {
  125.     count++;
  126.     
  127.     /* chain to the MS-DOS timer handler approx. 18 times per second */
  128.     if (++ticks == MS_PER_TICK) {
  129.         old_handler();
  130.         ticks = 0;
  131.     }
  132.     
  133.     /* issue end-of-interrupt command to 8259 PIC chip */
  134.     outportb(0x20, 0x20);
  135. }
  136.