The following is based on a newsgroup posting. I (Paul Hsieh) have made modifications where I thought there was a need for clarification: ============================================================================= From: alexad3@icebox.iceonline.com (Alexander J. Russell) Newsgroups: rec.games.programmer Subject: Re: I need some example sources (C/C++) of how to setup a TimerIRQ handler.... Date: Tue, 10 Oct 1995 03:40:21 GMT Organization: ICE Online Message-ID: >Simon van Tongeren (savant@euronet.nl) wrote: >: Hello, > >: Is the someone who can supply me with some sources of how >: I can setup a TimerIRQ handler (in borland C/C++ 3.1)???? > >: Any help, suggestions, source files are very welcome (prefered >: by e-mail). > >: Thanx, >: Simon. Here is an example: /* timer.c Copyright 1994, August 23 by Alec Russell, ALL rights reserved Permission granted to use ths code as you wish. Created - 1994/8/23 Used to speed up main timer to 60 Hz History: New file */ #include #include #define ULONG unsigned long #pragma inline volatile unsigned long fast_tick, slow_tick; /* "volatile" is essential */ static void interrupt (far *oldtimer)(void); /* BIOS timer handler */ void deinit_timer(void); /* You don't have to call the old timer, but if you don't you have to write some code to cleanup in de-init that fixes DOS's internal clock. This can usually be done by reading back the CMOS time. Its considered 'good form' to call the old int. If everyone does, then everything that other TSR's etc... may have installed will also work. If you skip the little chunk of ASM code- the out 20- you WILL LOCKUP all interupts, and your computer. Anyways, this test replacement just increments a couple of long ints. */ /* ---------------------- new_timer() ------------------- August 23,1994 */ static void interrupt new_timer(void) { asm cli fast_tick++; if ( !(fast_tick & 3) ) /* call old timer ever 4th new tick */ { oldtimer(); slow_tick++; } else { /* The following sends an End of Interrupt to the PIC */ asm { mov al, 20h out 20h, al } } asm sti } /* see that 1st line of inline asm? to set whatever clock speed you want load bx with 1193180/x where x is the clock speed you want in Hz. */ /* ---------------------- init_timer() ------------------ August 23,1994 */ void init_timer(void) { slow_tick=fast_tick=0l; oldtimer=getvect(8); // save old timer asm cli // speed up clock asm { mov bx, 19886 // set the clock speed to 60Hz (1193180/60) mov al, 00110110b out 43h, al mov al, bl out 40h, al mov al, bh out 40h, al } setvect(8, new_timer); asm sti } /* ---------------------- deinit_timer() ---------------- August 23,1994 */ void deinit_timer(void) { asm cli // slow down clock 1193180 / 65536 = 18.2, but we use zero asm { xor bx, bx // min rate 18.2 Hz when set to zero mov al, 00110110b out 43h, al mov al, bl out 40h, al mov al, bh out 40h, al } setvect(8, oldtimer); // restore oldtimer asm sti } /* ---------------------- waitt() --------------------- February 11,1995 */ void waitt(ULONG t) { t+=fast_tick; while ( t > fast_tick ) { /* empty */ } } #define TEST 1 #if TEST #include #include /* ---------------------- get_fast() -------------------- August 23,1994 */ ULONG get_fast(void) { return(fast_tick); } /* ---------------------- get_slow() -------------------- August 23,1994 */ ULONG get_slow(void) { return(slow_tick); } /* ---------------------- main() ------------------------ August 23,1994 */ void main(void) { ULONG t1, t2; printf("init timer\n"); init_timer(); while ( !bioskey(1) ) { t1=get_fast(); t2=get_slow(); printf("fast %lu slow %lu\n", t1, t2); } deinit_timer(); } #endif /* ------------------------------ EOF -------------------------------- */ The AnArChIsT - Anarchy! NOT Chaos! aka Alec Russell alexad3@icebox.iceonline.com