Re: Polling loop good here???
- From: Frank Kotler <fbkotler@xxxxxxxxxxx>
- Date: Sun, 28 Aug 2005 20:16:24 -0400
Any ideas how I might sync to bit 3 of port 0x3DA, the video card's vertical sync signal?
This is clearly on *very* old cards. I don't know the first thing about modern video cards (and *only* the first thing about older ones), but I'm pretty sure that on all modern cards, you've probably got an interrupt signal you can tap into for this purpose. The lack of an interrupt on vsynch was a problem that was well-known in the early 1980's in the PC architecture. I cannot imagine that this problem hasn't been addressed since then. No doubt, video drivers for Linux provide the abiility to tap into this signal, as appropriate. I'd even be surprised to find that you can't do something like programming the GPU to move data during the vsynch to vram and forget synching your code to it. Then again, as I said, I don't know the first thing about modern video cards.
Well, I don't either. If there *is* such an interrupt, no one seems to be able to tell me what it is. The original question on the linux-assembly list hasn't gotten *any* answers. I don't doubt that some cards with "hardware acceleration" have a means to synch themselves, but what I think is sought is something that would be reliably available on "any" card. The app seems to restrict itself to standard vga modes, so I assume it's intended to run on old hardware - but not so old as cga...
Just watching the bit in a loop doesn't seem like a good idea, since the CPU could be off doing something else, but as far as I know any timer function I might use will only be accurate to 1/100 of a second, which wouldn't be much better than watching the bit in a loop.
Since things like DOOM run in Linux, I think there must be some way to do it.
They don't run on 1982-era CGA cards. I suspect new games take full advantage of modern hardware. And they do it through the OS interface.
Okay. What OS interface?
I've discovered that simutaneously changing the screen data and the color palette without synchronization creates a flicker of a mess on the screen, and DOOM doesn't do that in Linux, so I guess it must be synchronizing somehow.
And I'd bet that Linux is providing this synchronization. Or at least the tools (like DirectX) to do it.
Maybe. There's no DirectX involved here, but maybe seeing how DirectX does it would be profitable.
I suspect we're all agreed (?) that it would be really cool if there were an interrupt on vertical retrace, but there isn't.
This was true on old CGA cards. Is it still true today? Is it even relevant today?
Well, the original poster's question suggests that it *is* relevant. The fact that he (or I) hasn't gotten any good answers suggests that there is no such interrupt ("standardized", that is), or that it's pretty well hidden.
There may be a way to "block" waiting for this, but I don't know how to do it. I fear we may be "stuck with" a polling loop here...
Anybody know the "right" way to do this?
Have the OS do it. I'm pretty sure that's the "right" way to do it.
Okay... how do we do that? My knowledge of Linux is pretty superficial, but it *seems* to be quite lacking in any graphics support. Various libraries provide the graphics interface, and finding out how they provide synchronization is probably the way to go.
As an aside (and a comment to other posts in this thread), a few years back I needed to do some high-performance SDLC processing on a 100MHz embedded 486-class device. I needed to send several SDLC packets 60 times/second (16.67ms) as *close* to that 16.67 period as possible (that is, on the zero-crossing of a power line). This was needed in order to produce less electrical noise (zero crossing is very quiet) and to extend the life of the components being so driven. I was running under QNX 6, a decent real-time OS. But even so, if I waited for the zero-crossing interrupt to occur, the latency between the interrupt and when my user-land process would run was just a bit too long. So what I wound up doing was setting a timer for about 10ms and waiting on that. When the 10 ms wakeup call came along, I did some processing that needed to be done before the zero crossing and then I polled the zero-crossing signal until it flipped, and then immediately started my code to process the outputs. Typically, I wound up waiting about 1-3 ms in the polling loop. But the latencies were *way* down, which is what was important here (btw, it was QNX, so I *could* turn off interrupts if I wanted to, though I didn't). Once in a *great* while I'd go a little beyond the 16.67ms barrier, but that was okay. Just didn't want to do it *all* the time.
That may suggest an approach that would work in this situation - poll a couple of vertical retraces and then "predict" when they'll occur and just poll for the exact occurrance. The whole multitasking nature makes this a *lot* more complicated than it was in dos. What happens if we detect our vertical retrace (by whatever means), and the lose our timeslice before we get the "flip" finished? Etc...
This is an example of where polling would be appropriate, even when an interrupt is available.
That's why I copied the question here. We've all been beating on Hutch about how bad an idea a polling loop is when there's a blocking API call available. But what about a situation where a blocking call isn't(?) available? How do we avoid the disadvantages of a polling loop (as much as possible) if we *haven't* got a blocking call?
I've heard some good suggestions, but nothing yet that I'm ready to post back to linux-assembly as "the answer".
I doubt this situation, however, applies to modern video cards (an interrupt is probably available, and the latency of the interrupt probably isn't a problem on modern CPUs [as opposed to a 100MHz embedded 486 chip]).
If someone can tell me what that interrupt is, *that* I'd post back to linux-assembly!
Best, Frank .
- Prev by Date: Re: Polling loop good here???
- Next by Date: Re: Polling loop good here???
- Previous by thread: Re: Polling loop good here???
- Next by thread: Re: Polling loop good here???