VGA Vertical blank interrupts
Posted: Thu Jun 17, 2021 5:16 am
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.
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.