• Please review our updated Terms and Rules here

Can't share an IRQ in DOS with a device I'm not even using?

doshea

Experienced Member
Joined
Dec 22, 2009
Messages
90
Location
Australia
Apologies if this has been asked many times before, but: I've read lots of things saying that IRQs can't be shared, and I understand why that could be the case if I had two devices triggering the same IRQ line and two drivers I wanted to process those interrupts but the hardware and software weren't designed to cooperate in this way (I have seen explanations about this), but why can't they be shared if one device isn't actually being used and (to the best of my knowledge) no running software cares about it?

I've got a Dell OptiPlex GXL 5100 which has:
- onboard Sound Blaster Vibra 16S (ISA PnP)
- onboard 3COM EtherLink III; I turned off PnP for this
- onboard parallel port and 2 serial ports

I've recently installed a clone of an IBM Enhanced 5250 Emulation ISA adapter. It seems that this card lets you set the IRQ via software, and some programs that use the card let you pick an IRQ, but older software seems to always use IRQ 5.

I do have Windows 3.x installed and will probably install 9x at some point, but for these tests I'm just using DOS.

My onboard Vibra 16 was using IRQ 5, and I hoped that if I just didn't run the DIAGNOSE utility to tell the Vibra 16 what IRQ to use (at least that's my understanding of what DIAGNOSE does), the 5250 adapter should be able to use IRQ 5. However, that didn't work - the IBM Enhanced 5250 Emulation Program kept indicating "System Available" and then losing that again - until I turned off the onboard audio in the BIOS settings.

Then I tried changing the Vibra 16 over to IRQ 7 (set BLASTER to include that value before running DIAGNOSE), and hoped that so long as I wasn't actually using the parallel port, sound should still work, but it only worked in some games - in others digital sound no longer worked. It was only when I went into the BIOS settings and turned off the parallel port that sound worked in all games.

In these cases I don't think it's a software thing - when both the 5250 adapter and sound card were on IRQ 5, I don't think any software would have hooked IRQ 5 apart from the IBM Enhanced 5250 Emulation Program, and I don't see why the Vibra 16 would have been generating interrupts. Similarly when both the sound card and parallel port were on IRQ 7, I don't know if maybe the BIOS hooks IRQ 7 on boot for some reason, but surely the game hooked it after that anyway, and the parallel port shouldn't have generated any interrupts anyway?

Is it a hardware thing where two different devices are driving the same IRQ line to different voltage levels, rather than when a device isn't signalling an interrupt it leaves that bus line in a high-impedance state or something, so that IRQ sharing only works between certain devices which have been designed correctly at the hardware level?

It's not so bad if I have to go into the BIOS settings to turn devices on and off based on what hardware I want to use at any given point in time, but it would be nice if there was a better way!
 
If you are not using the parallel port, you can use INT 7. If not using COM2, INT 3 is free.
 
Generally, it depends on the driver software and the device hardware.
For example, it's possible to have two floppy controllers share the same interrupt, as there is a bit in a control register that tristates the interrupt request line for a given controller. The printer port is one such device--unless the interrupt is enabled by software explicitly by setting a bit in a register, the device doesn't interrupt at all.

Similarly, driver software that "behaves like a good citizen" can share interrupts by determining if an interrupt was caused by itself or some other device; if the latter, the topmost ISR passes the interrupt along to the next lower device ISR ("chained" ISRs). Not all drivers behave this way, however.
 
Interrupt sharing only works if the following conditions hold true:
  • all devices can be queried for their interrupt status at all times (reading the interrupt status does not have side-effects)
  • all devices can handle the interrupt line being triggered elsewhere
  • all device drivers can handle spurious interrupts (being called even though the device did not request it)
  • all device drivers can chain to the next driver correctly
  • all device drivers enable/disable interrupts only at the device level, not at the interrupt controller level
There are some possible exceptions for the last device in the ISR chain.

Since most of the work is actually in the driver architecture, Linux actually supports interrupt sharing for many ISA devices. Interrupt sharing for serial ports was common as well; Xenix can handle a dozen serial terminals, and some DOS BBS systems handled many lines as well.

Of course, interrupt sharing does not matter between devices which do not assert interrupts in the first place. Unless you use it for non-printer purposes, its interrupt is only used for background printing and is unused most of the time. Which is why early SoundBlaster cards defaulted to IRQ 7 (avoiding IRQ 5, which might have been used for XT-style hard drives). So A220 and I7 is an incredibly common configuration and should work with all games.

That being said, I've got a later Vibra 16X and had issues getting it to work reliably with UNISOUND.
 
If you are not using the parallel port, you can use INT 7.
That's what I thought but it doesn't seem to be the case :( I just tried it again, and I thought it was suddenly successful this time around but I was just looking at the wrong setting and I'd left the parallel port disabled in the BIOS.


I suppose it's possible that some games might check the BIOS Data Area to see if the I/O port for the first parallel port is set, and if it's set then they assume IRQ 7 is in use, and they refuse to use it despite being told to do so in their configuration, but it seems unlikely to me that they'd do all that work to check but then not actually tell you why they've disabled sound.

  • all devices can handle the interrupt line being triggered elsewhere
Thanks, what you said all made sense to me apart from this part. Are there devices which sense the interrupt line as well as driving it?

Of course, interrupt sharing does not matter between devices which do not assert interrupts in the first place. Unless you use it for non-printer purposes, its interrupt is only used for background printing and is unused most of the time.
That's what I thought..

That being said, I've got a later Vibra 16X and had issues getting it to work reliably with UNISOUND.
..but if you've had trouble with this too I'll definitely give up trying now (or even trying to understand why) :biggrin:
 
One interesting (to me) data point: it seems to me that if I don't run the Sound Blaster DIAGNOSE utility on boot, I think the sound card ends up with IRQ 5, because the net result is the same as if I set the BLASTER environment variable to specify IRQ 5 and then ran DIAGNOSE: IRQ 5 doesn't seem to trigger for the 5250 emulation adapter.
 
That's what I thought but it doesn't seem to be the case :( I just tried it again, and I thought it was suddenly successful this time around but I was just looking at the wrong setting and I'd left the parallel port disabled in the BIOS.
It doesn't matter if the parallel port is enabled or not. If nothing is using it, you can still use INT 7. And even if something is using it, you probably can use it. If you use a SoundBlaster and a printer, the interrupt routine for INT 5, placed there by the DB driver/software, first checks if the interrupt has been generated by the SB and if not, jumps to the original interrupt routine.
 
all devices can handle the interrupt line being triggered elsewhere

Take this with a grain of salt, but my vague recollection is that this is critical matter: IBM didn't design the IRQ lines in the 5150-5170 to use level-triggered open collector logic. (IE, logic in which you can have multiple devices sitting on a single line that by default is kept up or down by a single resistor until one or more devices pull it up/down. This is, for instance, how the single interrupt line in the Apple II works; if the single shared IRQ line is held down, IE, level-triggered, the OS is supposed to iterate through all the possible interrupt handlers to figure out which of them might have triggered it; it could well be more than one.) The PIC, with its multiple dedicated IRQ lines, is instead set up for edge-triggered interrupts where it's expected that a TTL totem pole driver will pull down *and then pull up* to trigger an IRQ.

Here's a page that references an IBM design document to explain why interrupt sharing is a problem with this design. How bad of a problem depends on the cards. Some cards are equipped with always-on TTL drivers on the IRQ line, IE, they're *always* active and pulling down whenever they're not pulling up (IE, pulling down whenever an IRQ *hasn't* been triggered). When you add a second card that's going to try to pull the line up when its IRQ fires it's going to have a rough time overcoming the pull-down from the other device, which will essentially be shorting its attempt to trigger the IRQ straight to ground. (The "pull down" of TTL devices is usually stronger than the "pull up", so it's pretty likely the IRQ will never fire.) If you have newer cards that have tri-state drivers then the situation is somewhat better; if the cards are designed "politely" in such a way that the pull-down will only be enabled if the card itself is actually in use then it's possible to for these two devices to coexist in the system, with the proviso that bad things can still happen if you try running both at once.

On one hand I'd vaguely assume that with a system as new as this one at least all the onboard devices would *probably* have tri-state IRQ drivers, but on the other, well, you never know? The Vibra may well be behaving "greedily" and locking down whatever IRQ it's being assigned to in a way that's unfriendly to sharing with anything else. (As might be the parallel port.) If you really need both that 5250 emulation capability and a sound card you might just have to deal with either having no parallel port or looking for a PCI version of the emulation card.
 
Thanks, what you said all made sense to me apart from this part. Are there devices which sense the interrupt line as well as driving it?
There are probably some which do that (to save a wire or something like that), wouldn't be surprised.

Eudimorphodon already explained this point: If a device actively drives the interrupt line in its inactive state, any other device trying to signal an interrupt will cause a bus conflict / short circuit. Apart from stressing the components, the resulting signal level might end up somewhere in between LOW and HIGH, so the interrupt might not even be detected.

..but if you've had trouble with this too I'll definitely give up trying now (or even trying to understand why) :biggrin:
I am lucky enough to just replace the card with an ESS 688-based card, which works flawlessly. An integrated card like yours is worth more effort to get working, and since you have a workaround (disabling the on-board LPT), you are good. Although I still recommend trying UNISOUND, it's a great tool.

As an experiment, you could try your problematic games with the Vibra on IRQ 7, and the parallel port on IRQ 7 / IRQ 5 / disabled. That should be conclusive.

If nothing is using it, you can still use INT 7.
Please note that you are talking about IRQ 7, which is different from INT 7. The PC platform does not identity-map IRQs and INTs.
 
What I said earlier: (1) the device has to be implemented to allow sharing of interrupts and (2) the software has to be written such that more than one device sharing interrupts is possible.

For example, one can share a single interrupt on several serial (COMx) devices if the software for each can determine the device/card asserting the interrupt. Then it becomes a matter of "not mine, I'll pass it along"--assuming that the ISRs are chained; that is, the topmost ISR is aware that there are lower-level ISRs and it can pass the interrupt down the chain.

Unfortunately, some devices are constructed such that the interrupt itself identifies the device as the sole source of the interrupt. There's no "it isn't me" logic possible, because the cause of the interrupt either isn't or can't be determined.

Similarly, some software is written such that a device is treated as the sole owner of the interrupt; no "it isn't me" logic is implemented.

Consider the lowly (legacy) floppy controller. If you have more than one sharing the same interrupt, the situation in (1) obtains, because an interrupt is the direct result of issuing a command and the interrupt request line can be tristated. So the situation is:

1. Enable the interrupt request line
2. Issue the command
3. Wait for the interrupt and acknowledge it
4. Disable the interrupt request line.

A different way to do things is to "chain the ISRs--have one return to the next down the line if applicable. In this case, all sources of the interrupt request are enabled on the same IRQ line and the flow goes like this:

1. Do something on any device.
2. Wait for an interrupt.
3. Check the first device to see if any of the status bits are set to indicate that an interrupt has been created by the device. If so, service it and exit the ISR.
4. Otherwise, pass control to the next ISR in the chain.

In fact, the PC BIOS plugs the interrupt vector list with IRET instructions, so that there's no reason that all PC ISRs don't engage is the "pass it on" behavior.

PC software typically is agnostic about both of these situations, sadly.
 
Last edited:
For example, one can share a single interrupt on several serial (COMx) devices if the software for each can determine the device/card asserting the interrupt.

The claim that multiple serial cards can share an interrupt got me looking at some datasheets/schematics, and... I wonder how often this is actually true on a hardware level? According to the 8250 and 16550 datasheets the INT pin isn't tri-state; IE, it's going to be pulling down even if you've programmed the interrupt control register to neuter interrupts entirely. The original IBM Async serial communications card (and the serial card they sold for the AT) actually does, however, have a tristate buffer that's controlled by the user-defined "OUT" control signals, so it should be possible to disable the interrupt on a card to get along with something else.

(That said, I've found schematics for several 16550-based cards that don't include that buffer, IE, they're just leaving the OUT lines hanging... and I also will plead guilty to have built a 16552D dual-serial card for my Tandy 1000s that also directly connects the IRQ lines, which I'll blame on me basing it on the schematics of one of those directly-connected 16550 cards. (Reading the datasheet for it and the manual for the IBM cards it looks like I could have enabled the disable-IRQ functionality by using the "MF" lines on the 16552; they default to behaving like the OUT2 line on the 8250/16550.) I wonder if it was common for this disable-interrupt functionality to be missing on COM cards; if it turns out I picked the worst example to follow when building my homemade card I'll be embarassed. Not that it matters, I'm not *trying* to share IRQs with it, but... bleah, regardless.)

... anyway. The thing is, even if you use that buffer I'm still confused how you could do anything but polling I/O on all but one of the cards? The buffer IBM used is a 74LS125, which is tristate but still TTL when enabled, not open-collector/open-emitter, and I don't see any way you could just magically have it come on during the interrupt. (The tri-state control for it is via the bit in the modem control register and manually needs to be turned on and off?) I'm not clear how you could somehow "stack ISRs" with this given they can't do a "wire-or" of their interrupt signals? Did some cards implement it that way?
 
If you had several UARTS on a single card however, you could cascade their interrupts with a simple OR gate. (IRQx on ISA is active high). Multiple cards, of course, would be more complicated. Did anyone ever do this? I don't recall, but it seems logical.
 
I suppose if you had a box full of plain serial cards you could rig up a little daughterboard with a multi-input OR gate and wires going to the IRQ jumper blocks of each card (assuming it's a simple arrangement where the IRQ pin from the UART is directly connected to one of the bus lines) to convert a pile of them into a level-triggered multi-uarts-one-IRQ cluster. You might also need to hack the address circuitry of some of the cards to resolve port conflicts, of course, but... sure, write a driver that understands this mess and you'd be good to go?
 
I've seen documentation for dual / quad / octa serial boards. Both per-port and common interrupt configurations exist (and some allow mixing as well). The documents also explain how to configure e.g. Xenix accordingly. I believe this implies interrupt sharing within such a board.

The DOS world has FOSSIL drivers (such as X00) which can share interrupts on compatible hardware. The BNU FAQ (Q10b) goes into more detail, and SynchroNet (4.2) also has a section on this. So it's definitely not unheard of, but only relevant for people running many UARTs.
 
I could see UART cards modified to drive the IRQ line through a diode. A pulldown on the IRQ line would complete the picture. You could run multiple cards modified the same way.
 
As an experiment, you could try your problematic games with the Vibra on IRQ 7, and the parallel port on IRQ 7 / IRQ 5 / disabled. That should be conclusive.
I can't change the parallel port's IRQ in the BIOS (unless perhaps changing the I/O port number changes the IRQ too, but the documentation doesn't suggest that it does), but to test the other two combinations:

IRQ 7 used by:both Vibra and parallel portVibra only
DOOM 1.9music but no digital soundmusic and digital sound
Prince of Persia 1music and Adlib sound instead of digital soundmusic and digital sound
Prince of Persia 2seems to be normal initially, but seems to hang when playing some sound effectsmusic and digital sound
Wolfenstein 3-D 1.4music with digital sound sometimes playingmusic and digital sound
Windows for Workgroups 3.11startup and shutdown sounds are cut off; locks up on shutdownstartup and shutdown sounds are normal; doesn't lock up on shutdown

I thought I already had tested this, but previously I hadn't noticed that every single test case fails in some way when the parallel port is enabled - previously I thought that a few games did work.

Thanks @Eudimorphodon, it's reassuring to know that there are devices that will always drive the IRQ line and hence it's not worth spending too much time on the software side unless I can establish that the hardware does the right thing.
 
I can't change the parallel port's IRQ in the BIOS (unless perhaps changing the I/O port number changes the IRQ too, but the documentation doesn't suggest that it does)
Normally, the first parallel port is I/O 0x378 IRQ 7, and the second parallel port is I/O 0x278 IRQ 5. (There is also the 0x3BC port on MDA cards.)

So I'd assume changing the I/O address to also change the IRQ. But anyway, your test seems pretty conclusive, thank you.
 
Apart from stressing the components
Perhaps it did stress the components, as the machine died after about 10 further minutes of use after my last post :LOL: The keyboard stopped responding while playing Wolfenstein 3-D, then after a reset it said the keyboard controller wasn't working, then after power cycling the BIOS no longer showed the right model number or CPU speed and the memory test counter seemed to be going all over the place and never finishing.
 
Just a follow up to my last post, the machine wasn't dead, although somehow at the time resetting it didn't fix whatever was wrong with it, so I thought it was dead. It was able to start again the next day, and since then I've managed to play Wolfenstein 3-D right through (the above failure happened on the very first level I tried) with only two more problems - one more hang while playing which was resolved with a reset, and one failure to boot - so it's failing too infrequently for me to really be able to diagnose it. Maybe I'll try memtest or something sometime.
 
Back
Top