home *** CD-ROM | disk | FTP | other *** search
- From: osh@cbnewsh.ATT.COM (david.a.oshinsky)
- Newsgroups: comp.sys.ibm.pc
- Subject: Re: Turbo C timer interrupt handler
- Date: 24 Apr 89 22:01:20 GMT
- Keywords: turbo C interrupt handler
- Summary: short Turbo C program
-
- The following program demonstrates how to handle timer interrupts
- from Turbo C.
- Hope this helps,
- David Oshinsky
- AT&T Bell Laboratories
- Holmdel, NJ
- phone: (201)949-0037
- uucp: att!houxs!osh
-
- ------------------------- Cut here --------------------------
- /* 8253 timer test program for Turbo C 1.5/2.0. */
- /* Author: David Oshinsky, 11/14/88. */
-
- /* This program demonstrates how to use counter 0 in the */
- /* 8253 chip to provide "real-time clock" functions on the */
- /* IBM PC or PC/AT. */
-
- /* SOME QUICK INFO ON PC INTERRUPTS: */
- /* The interrupt lines INT2 through INT7 appear on the PC */
- /* bus. INT0 and INT1 appear only on the motherboard. */
- /* Interrupt line usage is as follows: */
- /* INT0 is used by counter 0 of the 8253 programmable */
- /* interval timer chip */
- /* INT1 is used by the keyboard */
- /* INT5 is used by the hard disk controller */
- /* INT6 is used by the floppy disk controller */
-
- /* The above is not completely accurate when applied to */
- /* the PC/AT; however, the timer interrupt uses INT0 on */
- /* both the PC and PC/AT. (This program works on both the */
- /* PC and the PC/AT.) */
-
- /* The 8259 Peripheral Interrupt Controller (PIC) chip */
- /* maps the INTx line to interrupt number x+8 (this is */
- /* programmable, set by MS-DOS). Hence, the timer */
- /* interrupt is number 8. */
-
- #include <dos.h>
-
- #define ZERO_FLAG 0x040
- #define CONTROL_C 3
- #define MS_PER_TICK 53 /* milliseconds per IBM PC clock tick */
-
- unsigned long count;
- unsigned ticks;
- void interrupt timer(), interrupt (*old_handler)();
-
- main()
- {
- union REGS sreg, rreg;
-
- /* time starts at zero */
- count = 0;
- ticks = 0;
-
- /* initializations related to MS-DOS call to read keyboard */
- sreg.x.dx = 0xff;
- sreg.h.ah = 0x06;
-
- printf("\nTo stop the timer test program, type CTRL-C.");
- printf("\nTo display time since starting the program, hit any key.");
- printf("\nThe time is accurate to roughly the nearest 1 msec.\n\n");
-
- /* Save the address of the current timer interrupt handler */
- old_handler = getvect(8);
-
- /* Call "timer" function when timer interrupt occurs. */
- setvect(8, timer);
-
- /* Set up 8259 PIC chip to allow INT0 interrupt. */
- outportb(0x21, inportb(0x21) & 0xfe);
-
- /* issue command to 8253: counter 0, binary counter, rate generator */
- /* (mode 2), load least significant byte of counter followed by */
- /* most significant byte */
- outportb(0x43, 0x34);
-
- /* Timer is set for 0x4cd * 813.8 ns = 1 ms (LSB followed by MSB). */
- outportb(0x40, 0xcd); /* least significant byte of timer count */
- outportb(0x40, 0x04); /* most significant byte of timer count */
-
- while (1) {
- /* wait for keystroke */
- while ( 1 ) {
- intdos(&sreg, &rreg);
- if ( ! (rreg.x.flags & ZERO_FLAG) )
- break;
- }
-
- /* stop the program if ctrl-C */
- if ( (rreg.x.ax & 0xff) == CONTROL_C ) {
- /* NOTE: the following code MUST be executed before */
- /* returning to MS-DOS in order to allow proper */
- /* operation of programs which use the 8253 timer. */
-
- /* restore 8253 to original state set during PC boot */
- /* NOTE: this program leaves 8259 mask register with */
- /* least significant bit clear (i.e., INT0 enabled). */
- outportb(0x43, 0x34);
- outportb(0x40, 0);
- outportb(0x40, 0);
-
- /* restore original interrupt vector for number 8 */
- setvect(8, old_handler);
-
- printf("Timer test program returning to MS-DOS.\n");
- exit(0);
- }
- else
- printf("TIME = %lu MSEC.\n",count);
- }
- }
-
- /* timer interrupt service routine (interrupt number 8) */
- void interrupt
- timer()
- {
- count++;
-
- /* chain to the MS-DOS timer handler approx. 18 times per second */
- if (++ticks == MS_PER_TICK) {
- old_handler();
- ticks = 0;
- }
-
- /* issue end-of-interrupt command to 8259 PIC chip */
- outportb(0x20, 0x20);
- }
-