Date: Thu, 20 Feb 1997 21:42:49 +1100 From: Bruce Evans <bde@zeta.org.au> To: brian@awfulhak.demon.co.uk, hackers@freebsd.org Cc: brian@utell.co.uk Subject: Re: Screen flickering Message-ID: <199702201042.VAA30639@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>Essentially, the syscons screen "flickers" probably every couple of >seconds on average, and only with "vidcontrol -c destructive". From >what I can figure, the "while (!(inb(crtc_addr+6)&8)) ;" bit in >syscons.c doesn't work as expected (although removing it makes >things a *lot* worse).... The timing is sometimes interfered with by interrupts. The hardware is designed to be polled as follows: 1. Disable CPU interrupts. Don't worry about losing several thousand serial interrupts while interrupts are disabled. 2. Loop until the retrace bit is not set. 3. Loop until the retrace bit is set. Since interrupts are disabled, the previous test of the retrace bit was done less than 5 usec ago. Since the bit was previously not set, the video retrace must have begun less than 5 usec ago. Thus there is almost a full retrace period available for step 4. 4. Program the `sparkly' registers. 5. Enable interrupts. Disabling interrupts for a long time is unacceptable for a multitasking OS. The problem can be handled "right" if the video card can generate vertical retrace interrupts: 1. Make the vertical retrace interrupt handler a "fast" interrupt handler so that it has a low latency and can't be interrupted. Don't use too many other "fast" interrupt handlers, or the interrupt latency might be too high. 2. Program the sparkly registers in the vertical retrace interrupt handler. Do this in less than 20 usec or someone will complain that the interrupt latency is too high. Otherwise, the best that can be done is probably something like: 1. Loop until the retrace bit is not set, recording the current interrupt count before each test. 2. Loop until the retrace bit is set, recording the current interrupt from before each test whenever the loop continues. 3. Disable interrupts. 4. If the current interrupt count is different from the one before the test that found the retrace bit not set, then we must have been interrupted. Enable interrupts and go to step 1 in this case. 5. Program the `sparkly' registers. Do this in less than 20 usec or someone will complain that the interrupt latency is too high. 6. Enable interrupts. Busy-waiting for a long time like this (average almost 1/70 seconds) is also unacceptable for a multitasking OS. This method also takes a lot of code. It can probably be improved at the cost of even more code by recording timestamps instead of interrupt counts. Then it could tell that it was only interrupted for 50 usec (say), so there must be plenty of time before the retrace completes, so the "go to step 1" step is unnecessary. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702201042.VAA30639>