Date: Thu, 12 May 94 09:45 MET DST From: rene_j AT tudebg DOT et DOT tudelft DOT nl (Rene Jager) To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Q: Re: Q: timer interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7BIT X-Mailer: Mumail [version 2.3b i486-Linux] Thanx for replies from DJ and Gordon. I'll give some more info on the problem. We have a simulation tool which was originally coded using Borland. The need for more memory, while still being able to use the same graphics brought us to DJGPP. The combination DJGPP with GRX and BCC2GRX provided a simple upgrade to 32-bit, so no memory limits. At the momemt we're building in timer functions so we can not only simulate but also do "real-time" control with the same package. To do so, we set the 8253 timer to a resolution of 1ms, hook in our function to perform calculations as interrupt and every 55ms the original timer function is executed. Hence, the _go32_dpmi_..._chain_... can't do the job since it causes the original timer to be called every time the user timer returns. Below I included an example using Borland... Rene' * Rene' Jager * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Delft Univ. of Technology, Dept. of Electrical Engineering, Control Lab. * * snail-mail: Mekelweg 4, P.O. Box 5031, 2600 GA Delft, The Netherlands * * e-mail: r DOT jager AT et DOT tudelft DOT nl | voice: +31.15.785114 | fax: +31.15.626738 * * World Wide Web: http://dutera.et.tudelft.nl/people/rene_j/jager.html * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Example timer in Borland: ---------------->8---------------------->8--------------- #include #define TMR_INT 0x08 static char timeron; static unsigned int timercount; void (*userfunction)(void); void interrupt (*oldtimer)(void); /* old interrupt handler */ static unsigned int timercount; static unsigned int period; static char old55count; void interrupt timer(void) { --timercount; --old55count; if(!timercount) /* execute user timer every 'period' ms */ { timercount = period; (*userfunction)(); } if(!old55count) /* execute original timer */ { old55count = 55; oldtimer(); } outp(0x20, 0x20); } void installtimer(void (*userf)(void), unsigned int per) { if(!timeron) { timeron = 1; period = timercount = per; old55count = 55; userfunction = userf; outp(0x21, inp(0x21) | 0x01); /* interrupt disable */ oldtimer = getvect(TMR_INT); /* get current timer */ setvect(TMR_INT, timer); /* hook up new timer */ outp(0x43, 0x34); /* set timer to 1 ms */ outp(0x40, 167); /* ((65536L/55) & 0xFF) == 167 */ outp(0x40, 4); /* ((65536L/55) >> 8) & 0xFF) == 4 */ outp(0x21, inp(0x21) & ~0x01); /* interrupt enable */ } } void removetimer(void) { if(timeron) { outp(0x21, inp(0x21) | 0x01); /* interrupt disable */ setvect(TMR_INT, oldtimer); /* put back old timer */ outp(0x43, 0x34); /* set timer to 55 ms */ outp(0x40, 0); outp(0x40, 0); outp(0x21, inp(0x21) & ~0x01); /* interrupt enable */ timeron = 0; } } /* for testing... */ int tics = 0; void tic_it(void) { tics++; } int main(void) { int prvtics = 0; installtimer(tic_it, 30); /* execute tic_it every 30ms */ while(!kbhit()) if(prvtics != tics) { printf("tics = %d\n", tics); prvtics = tics; } removetimer(); return 0; }