Page 1 of 1

VGA Vertical blank interrupts

Posted: Thu Jun 17, 2021 5:16 am
by thorfdbg
Hi folks,

how do the vertical blank interrupts at legacy VGA chips work? I have a strange situation here I do not quite understand...

From what I understand right now, I can check INPUTSTATUS0 bit 7 in the interrupt handler whether a vertical retrace interrupt is pending, and then acknowledge the interrupt by clearning bit 4 of GR11, and again set bit 4 in GR11 again to allow capturing the next interrupt. Also, I need to clear the interrupt at the interrupt controller (not a PIC or APIC here, but yes, that is done).

So far, so good.

Problem is, after setting GR11_4 to 1, the interrupt comes back *immediatly* on the same VBI, even without INPUTSTATUS0_7 being set, so something is broken. The system then hangs indefinitely in the interrupt handler being unable to detect the interrupt source. Yes, the interrupt is also cleared at the interrupt at the IRQ controller of the system.

One suspicion I have is that the input to the VBI interrupt generator is wired to the vertical sync active indicator of the chip (essentially, INPUTSTATUS1 bit 3), and it is level-triggered, not edge triggered. That is, at the time I clear the interrupt, the chip is *still* in the vertical blank, and the interrupt simply goes on again.

What I did right now is that I acknowledge the interrupt in the interrupt handler just again, without checking INPUTSTATUS0_7, I'm just not forwarding the result to the application in case INPUTSTATUS0_7 is not set. This seems "to work" (for some definition of "working", i.e. it creates an increased load on the CPU, having to go through the interrupt handler often), though I suspect that the interrupt is triggered multiple times until the chip leaves the blank area.

Does this sound plausible? Is there anything I have forgotten when acknowledging the interrupt? Is there any way to make the interrupt edge-triggered rather than level-triggered, or have it delayed or acknowledged *after* leaving the blanking region?

This is (again) this (dreadful) S3Virge chip on which I observe this.

Re: VGA Vertical blank interrupts

Posted: Thu Jun 17, 2021 1:28 pm
by Octocontrabass
thorfdbg wrote:how do the vertical blank interrupts at legacy VGA chips work?
Good question! Pretty often the wire between the VGA chip and the interrupt controller physically didn't exist, so programmers couldn't rely on it functioning, so there's not a whole lot of documentation.

What happens if you also set bit 5 when you clear bit 4? One source suggests that it might be necessary.

If there really is no way to stop it from constantly triggering an interrupt during vertical blank, then the best solution would be to disable the interrupt (set bit 5) in the handler and use a timer or something to re-enable it after vertical blank has ended.

Re: VGA Vertical blank interrupts

Posted: Thu Jun 17, 2021 2:42 pm
by Gigasoft
The order of operations is important, did you remember to clear the interrupt at the graphics card first and then at the interrupt controller?

Re: VGA Vertical blank interrupts

Posted: Fri Jun 18, 2021 3:39 pm
by thorfdbg
Octocontrabass wrote: What happens if you also set bit 5 when you clear bit 4? One source suggests that it might be necessary.
Good idea. I haven't tried that yet.

The current mode of operations is:
1) Read CRTI, keep a backup (so don't interfere with a program that is about to change a CRT register)
2) Reset bit 4. That should acknowledge the interrupt, but keep it disabled (as I read the manual)
3) Clear bit 5, allow the interrupt.
4) Set bit 4, allow the interrupt to trigger again.
5) Restore CRTI.

Probably I should keep bit 5 set until the very end (in step 4).

On a cirrus GD542x, the sequence is quite simple ("from the book"), replace 2) to 4) by just "clear bit 4", "set bit 4", and you are good, but the S3 seems to be somewhat "special" (again).

Now that I read the procedure: Is it true that on the PC IRQ 2 is edge-triggered or level-triggered? The way how the S3 manual reads is that the output of the IRQ flip-flop is directly connected to the interrupt controller such that setting the bit to 1 manually is indeed required to receive another HI-LO flank.

It is level-triggered on this particular system, meaning that setting the bit to HI could indeed trigger the interrupt again?
Octocontrabass wrote: If there really is no way to stop it from constantly triggering an interrupt during vertical blank, then the best solution would be to disable the interrupt (set bit 5) in the handler and use a timer or something to re-enable it after vertical blank has ended.
Well.... if I had a timer. This is a bit touchy as this is a driver that should not interfere with other system resources.

Re: VGA Vertical blank interrupts

Posted: Fri Jun 18, 2021 3:40 pm
by thorfdbg
Gigasoft wrote:The order of operations is important, did you remember to clear the interrupt at the graphics card first and then at the interrupt controller?
Thanks for asking, but yes. The interrupt controller bit is cleared at the very end of the interrupt chain by the Os (not by my code).