[comp.sys.ibm.pc] Need help with PC interrupt handler

erd@lear.cs.duke.edu (Ed Darken) (01/15/90)

Hi. I'm having a hairy problem with a PC interrupt handler, and I'm
posting this article in the desperate hope that somebody out there
can suggest a solution.

Here's the short version of the problem: I've written an interrupt
handler to capture counter/timer board interrupts on IRQ3 every 20
milliseconds, but the handler fails after 1000-35,000 interrupts.

The longer version: We have a counter/timer board in an 
AT-compatible 16-Mhz 80386SX PC (in case you're interested, the timer 
board is made by Data Translation, Inc., and the AT-compatible 
motherboard is from WaveMate). The timer board is configured to 
interrupt on IRQ3. There aren't any COM boards in this PC, and 
I'm sure the timer board is the only thing using IRQ3.

I've written my own interrupt handler to capture the IRQ3 interrupt
and reload the clock with another count. I initially wrote the handler
in Microsoft C 5.1 but rewrote it (and this is a measure of my desperation)
in Microsoft Assembler 4.0. I also wrote routines that initialize 
(i.e., enable IRQ3 interrupts, load an initial count, etc.) and shut 
down the timer. 

My test program calls the init routine and then waits for the user
to type 'q' on the keyboard, upon which it exits with a report on
the number of timer interrupts and the like, read from global variables
set by the interrupt handler. 

In addition to keeping a count of the number of interrupts, the handler
raises and lowers a bit on a parallel port. I monitor that line on an
oscilloscope (you know you're in trouble when you're debugging your
programs with an oscilloscope).

When I start the program, everything looks hunky-dory on the scope; 
I see spikes every 20 milliseconds. However, after 1,000 to 35,000
interrupts (20 to 700 seconds), I stop seeing the spikes. All looks 
well with the program: I type 'q', and everything ends nicely (most
specifically, there doesn't appear to be any corruption of the stack); 
BUT, the interrupt handler (or the timer) has stopped doing its job.

My handler does the following (there's at most a 50-microsecond lapse
from the time it sets the parallet bit high to the time it sets the bit
low):
	=====> INTERRUPT!
	Push regs
	Set up local data and stack segments
	Re-enable interrupts (STI)
	Set parallel port bit high (using OUT instructions)
	Reload and start clock (using OUT instructions)
	Set parallel port bit low (using OUT instructions)
	Send non-specific EOI (using OUT instruction)
	Restore data and stack segments
	Restore regs
	Return from interrupt (IRET)

The initialization routine uses INT21 to save the old interrupt vector
(35H) and to set the new vector (25H). The shutdown routine uses INT21
(function 25H) to restore the original vector. These are the only times
that INT21 is used; the handler itself does NOT use INT21.

I've tried fiddling with stacks and stack sizes, with no effect
whatsoever. I've also tried turning off all interrupts except 
keyboard and IRQ3 (using the interrupt mask). The problem persists
(and I don't even type anything at the keyboard until the spikes
disappear).  It looks to me like my interrupt gets dropped or 
trampled in a probabilistic manner. I suspected the system clock 
interrupts (IRQ0), but turning them off doesn't seem to help.

HELP! I'll listen to anything you have to say.

				Thanks,
				Ed Darken
				erd@cs.duke.edu

P.S. By the way, I wrote a program that does the same thing by polling
the timer rather than responding to interrupts. THAT runs ad infinitum.

davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (01/16/90)

In article <16815@duke.cs.duke.edu> erd@lear.cs.duke.edu (Ed Darken) writes:

| 	Reload and start clock (using OUT instructions)
| 	Set parallel port bit low (using OUT instructions)
==> Disable interrupts
| 	Send non-specific EOI (using OUT instruction)
| 	Restore data and stack segments
| 	Restore regs
| 	Return from interrupt (IRET)
-- 
bill davidsen	(davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen)
            "Stupidity, like virtue, is its own reward" -me