Polling for VSYNC doesn't work (0x3DA port)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Brendan »

Hi,

Some assorted notes...

For CGA there was a hardware bug where changing things (e.g. palette) at the wrong time would cause "snow"; and you had to depend on vertical sync to avoid the hardware bugs. For VGA the bugs were fixed and you don't need vertical sync anywhere near as much. For VGA and anything more modern; without vertical sync there's a risk of something called "tearing", but this is not noticeable unless the entire frame is changed every frame and you're extremely unlucky and happen to update the screen at a "close to monitor refresh rate" frequency for long enough.

The VGA did not support any vertical sync IRQ. Modern "non-VGA cards" do support a vertical sync IRQ, but there's no standards and it can be tied in with unrelated things (e.g. where you have to read some sort of status register to determine if the IRQ was caused by vertical sync or something else, like maybe if a GPU command queue is empty).

For VGA; you can emulate a vertical sync IRQ. This is done by using the PIT configured in "one shot mode"; where your PIT IRQ handler polls VGA's vertical sync flag until vertical sync begins, then auto-adjusts an internal "time between vertical syncs" variable (increasing the delay if had to poll too long, decreasing the delay if you didn't poll for long enough or missed the vertical retrace), then sets a new PIT timer count to the new "time between vertical syncs" variable.

Almost all modern video cards have a "VGA emulation mode" where they try to emulate obsolete trash from 30 years ago (with various amounts of success and potential "VGA emulation bugs" in hardware). For VBE there's a "VGA compatible mode" flag in the "VBE mode info structure", and this flag will be clear for any video mode that doesn't make the end user vomit. In this case (if VBE says it's a "non-VGA mode") VBE must unlock extended/incompatible/proprietary registers (that are needed to configure higher resolutions, etc) and take the video card's hardware out of that "VBE emulation mode", and there's no longer any guarantee that any VGA IO ports behave the same (and you can not expect that polling VGA's "vertical sync" flag will work even when the video card doesn't have "VGA emulation bugs" in hardware).

VBE doesn't support any kind of vertical sync (no IRQ, and no polling). There was a second specification called VBE/AF ("VESA BIOS Extensions, Accelerator Functions") that added a whole pile of things (hardware bit blits, hardware mouse pointer, hardware line drawing, etc) which included support for multiple buffers in display memory and a "wait for vertical sync then switch the visible buffer" function that could've been used for ensuring vertical sync (via. internal polling done by VBE/AF, and not with a modern "page flip on vertical sync IRQ" approach). However, as far as I know, VBE/AF was never supported by any video card for multiple reasons - games were already using video card specific code because VBE/AF was "too little, too late", video cards were struggling to fit everything in the 64 KiB legacy video ROM area already and didn't have space to add new functionality to their ROMs, and VBE/AF was released in 1996 when everyone was abandoning DOS (and BIOS) and switching to Windows (with native video drivers) so nobody had a reason to care about VBE/AF anyway.

After decades of being crippled by legacy limitations (including the "64 KiB legacy video ROM area" limit that had been preventing video card ROMs from doing things like supporting VBE/AF, including support for multiple video cards/monitors, and including the idiocy of "VGA compatible") UEFI was introduced to solve all the problems. Ironically, everything had shifted to "firmware only used to boot an OS that has native drivers" long before UEFI was created, so UEFI didn't bother with much more than video mode setting.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Geri »

6502Rulez wrote:How would lowering FPS help in any way ? If I start updating the screen after it begun drawing there will be flickering regardless of framerate.
only if you are searching for it. otherwise your mind will adapt. we had no vsync in windows gamedev up to 2008, when only the drivers started to turn it on by default. nobody seemed to notice it. also be sure to update your screen with a properly fast algorythm (a proper memcpy for example) so the refresh will not take a lot of time, and generally will not lag into 3 or more frames.
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
Octocontrabass
Member
Member
Posts: 5567
Joined: Mon Mar 25, 2013 7:01 pm

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Octocontrabass »

6502Rulez wrote:Does that mean there's no way to get a screen without flickering ?
If you write a native video card driver, you can have a screen without flickering. (This is the only option if you're using UEFI.)

If you use VBE, you might be able to get a screen without flickering by using the "during vertical retrace" bit on certain functions. Since you're in protected mode, your options are switching back to real mode, using virtual 8086 mode, using an emulator of some sort, or using the VBE protected mode interface. Unfortunately, I don't think Windows uses those functions, which means they probably don't work.

If you happen to stumble across a machine so old it doesn't support VBE (or only supports a very old version of VBE that predates the functions you need), the hardware is probably close enough to VGA that you can poll port 0x3DA for vblank.
Brendan wrote:VBE doesn't support any kind of vertical sync (no IRQ, and no polling).
Not entirely true. Some VBE functions are defined as having a "during vertical retrace" bit that's supposed to make them wait until vblank to update the display. (Of course, it probably doesn't work.)
6502Rulez
Posts: 20
Joined: Tue May 16, 2017 6:50 am

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by 6502Rulez »

Brendan wrote:Hi,

Some assorted notes...

For CGA there was a hardware bug where changing things (e.g. palette) at the wrong time would cause "snow"; and you had to depend on vertical sync to avoid the hardware bugs. For VGA the bugs were fixed and you don't need vertical sync anywhere near as much. For VGA and anything more modern; without vertical sync there's a risk of something called "tearing", but this is not noticeable unless the entire frame is changed every frame and you're extremely unlucky and happen to update the screen at a "close to monitor refresh rate" frequency for long enough.

The VGA did not support any vertical sync IRQ. Modern "non-VGA cards" do support a vertical sync IRQ, but there's no standards and it can be tied in with unrelated things (e.g. where you have to read some sort of status register to determine if the IRQ was caused by vertical sync or something else, like maybe if a GPU command queue is empty).

For VGA; you can emulate a vertical sync IRQ. This is done by using the PIT configured in "one shot mode"; where your PIT IRQ handler polls VGA's vertical sync flag until vertical sync begins, then auto-adjusts an internal "time between vertical syncs" variable (increasing the delay if had to poll too long, decreasing the delay if you didn't poll for long enough or missed the vertical retrace), then sets a new PIT timer count to the new "time between vertical syncs" variable.

Almost all modern video cards have a "VGA emulation mode" where they try to emulate obsolete trash from 30 years ago (with various amounts of success and potential "VGA emulation bugs" in hardware). For VBE there's a "VGA compatible mode" flag in the "VBE mode info structure", and this flag will be clear for any video mode that doesn't make the end user vomit. In this case (if VBE says it's a "non-VGA mode") VBE must unlock extended/incompatible/proprietary registers (that are needed to configure higher resolutions, etc) and take the video card's hardware out of that "VBE emulation mode", and there's no longer any guarantee that any VGA IO ports behave the same (and you can not expect that polling VGA's "vertical sync" flag will work even when the video card doesn't have "VGA emulation bugs" in hardware).

VBE doesn't support any kind of vertical sync (no IRQ, and no polling). There was a second specification called VBE/AF ("VESA BIOS Extensions, Accelerator Functions") that added a whole pile of things (hardware bit blits, hardware mouse pointer, hardware line drawing, etc) which included support for multiple buffers in display memory and a "wait for vertical sync then switch the visible buffer" function that could've been used for ensuring vertical sync (via. internal polling done by VBE/AF, and not with a modern "page flip on vertical sync IRQ" approach). However, as far as I know, VBE/AF was never supported by any video card for multiple reasons - games were already using video card specific code because VBE/AF was "too little, too late", video cards were struggling to fit everything in the 64 KiB legacy video ROM area already and didn't have space to add new functionality to their ROMs, and VBE/AF was released in 1996 when everyone was abandoning DOS (and BIOS) and switching to Windows (with native video drivers) so nobody had a reason to care about VBE/AF anyway.

After decades of being crippled by legacy limitations (including the "64 KiB legacy video ROM area" limit that had been preventing video card ROMs from doing things like supporting VBE/AF, including support for multiple video cards/monitors, and including the idiocy of "VGA compatible") UEFI was introduced to solve all the problems. Ironically, everything had shifted to "firmware only used to boot an OS that has native drivers" long before UEFI was created, so UEFI didn't bother with much more than video mode setting.


Cheers,

Brendan
Thanks, that makes a lot of sence now. It's a shame. I wanted to do C64-esqe demo and some games, but that won't look too pretty without the sync. I was thinking about setting the PIT irq at ~70Hz and then do some delay. You could change the delay at run time via pressing buttons until it looks stable. What do you think ?
User avatar
~
Member
Member
Posts: 1227
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by ~ »

Octocontrabass wrote:
6502Rulez wrote:Does that mean there's no way to get a screen without flickering ?
If you write a native video card driver, you can have a screen without flickering. (This is the only option if you're using UEFI.)

If you use VBE, you might be able to get a screen without flickering by using the "during vertical retrace" bit on certain functions. Since you're in protected mode, your options are switching back to real mode, using virtual 8086 mode, using an emulator of some sort, or using the VBE protected mode interface. Unfortunately, I don't think Windows uses those functions, which means they probably don't work.
Windows 98/ME is capable of using the VESA VBE version present in the card, but you have to write a driver (VxD, etc).

This is how you can display 16-bit color with a generic VBE 2.0 driver in Windows 98. If you have VBE 3, you would need to adjust the source code. This driver is only capable of switching video modes during boot only for 16-bit modes. You can actually switch screen resolution for 16-bit color while you are running Windows 98, but you will have to run old Windows games in a DirectX window, let them fail, or make the computer freeze if for example you try to switch to 256-color 640x480 with this VBE 2.0 driver.

Here you can find the binaries and the source code (if you install it, use the 64 Megabytes, 064MB version of the driver, because that's the one that almost always works, just make sure you actually have VBE 2.0 or you'll only get the default 640x480 16-color VGA mode):
http://bearwindows.zcm.com.au/vbe9x.htm#2

Here you can see a video about how to install it:
Installing a Default Windows 98 SVGA VESA VBE 2.0 Driver
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
Octocontrabass
Member
Member
Posts: 5567
Joined: Mon Mar 25, 2013 7:01 pm

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Octocontrabass »

~ wrote:Windows 98/ME is capable of using the VESA VBE version present in the card, but you have to write a driver (VxD, etc).
If you have to write your own driver, that means most copies of Windows don't use them (instead of all copies), and they still probably do not work.
User avatar
~
Member
Member
Posts: 1227
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by ~ »

Octocontrabass wrote:
~ wrote:Windows 98/ME is capable of using the VESA VBE version present in the card, but you have to write a driver (VxD, etc).
If you have to write your own driver, that means most copies of Windows don't use them (instead of all copies), and they still probably do not work.
Remember that it's a generic VBE driver. Ideally all machines would use it as with Windows XP when you are still installing it.

You, I or somebody else could improve this driver so that it can automatically select between VBE 1, 2, 3, and different color resolutions (properly detecting them) and use them all without having to reset the machine.

The VBE 2.0 driver is there with source code, it works, many people want it to enable high color in new machines that don't have Windows 9x drivers. You can modify the driver so it can use VBE 3, then Windows 98 will be able to display good video even in newer machines and learn how to use it properly while doing that.

Half-Life 1, watching TV, using Flash games, work as if they were accelerated in a AMD64 3000+ with 2GB of RAM at 2GHz.

The trick here is to have dedicated RAM only for programs, and dedicated RAM only for video. That's how I normally work, with an AGP nVidia card from 2008 with this VBE 2.0 driver.

You can notice the difference in memory bus speed when the main RAM doesn't have to share bandwidth with the screen. It's noticeable even for lower-resolution videos, like the one that displays the Windows 98 logo. The speed is important.

Remember that you aren't the only one accessing video memory. The video controller also needs to do that to refresh the screen automatically, and if it doesn't have its own onboard RAM, as nVidia cards and other accelerated ones, the whole system will suffer immediately.

The first acceleration point for a video card is to have its own RAM, not share it with the main system RAM. It highly accelerates things even in Windows 98 and DOS. You are effectively using an implicit core for the CPU and an implicit core for the video just with this hardware setup.

The most important functionality for a Windows 98 machine started at the hardware, then the drivers and layered/modular software.
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Geri »

linux with x11 (and i think windows xp) will use the vbe, why to fight with win9x?
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
User avatar
~
Member
Member
Posts: 1227
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by ~ »

Geri wrote:linux with x11 (and i think windows xp) will use the vbe, why to fight with win9x?
Windows 9x is actually at the same level of people here who have made their own OSes, with the same sort of bugs and limitations that can be corrected, so it's logical that I use it. I feel it right at my current development level as to allow me to do interesting stuff.

For me it's a direct door to the raw PC platform (it's not platform-independent like Windows NT/XP/7 so I will find PC development details no matter what I do and still will be in Win32 with Win16), to DOS and to load my own kernel using DOS as a boot manager.

I know that if I understand how to develop that sort of things under Win9x, it will guide me to understand it as well in X11 or anything else, and the most important is that it will be oriented specifically to allow me to learn the details of the PC platform.

That's what I'm specifically interested in too, learn about the PC, the demos, tricks, etc., from the past, understand its source code, and use all that to learn the foundations of all computing, but I need that system to access directly the features of a PC as its own hardware API.

By the way, here's a mirror of ProgrammersHeaven.com with 4.3 Gigabytes of 90's code and information for the classic PC. It's very important, the sort of stuff that makes using DOS, Win9x and a PC with all ISA features and devices, make sense:
http://archive.org/download/2014_10_16_ ... en.com.zip

_______________________________________________________
_______________________________________________________
_______________________________________________________
_______________________________________________________
Linux is also platform-independent like NT, unfortunately, mixing code for PCs with that for many other architectures.

If there was a cleanly separate code base only for the PC (ISA, PS/2, PCI, UEFI) and also for each architecture, it would be ideal to learn lots of things without having to decipher what is actual functional code and what are lines of compatibility layers to manage all of the architectures in the same code.

It's considerably slower and harder, but it would need to be taken as a study project to develop to extract the actual tricks as they aren't so easy to find just with Google.
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
User avatar
Sik
Member
Member
Posts: 251
Joined: Wed Aug 17, 2016 4:55 am

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Sik »

Brendan wrote:For CGA there was a hardware bug where changing things (e.g. palette) at the wrong time would cause "snow"; and you had to depend on vertical sync to avoid the hardware bugs.
Yeah, it's in those tests I linked earlier.

For more details: writing to video RAM in 80×25 text mode results in whatever value you wrote being sent to screen, because there aren't enough memory cycles to allow both a write and a read. Note that this also affects reading from video RAM (since what you want to read isn't what the video hardware needs to read, so the latter gets the wrong address). This happens anywhere on screen, moving it to blanking area just helps hide it. Other video modes (40×25 text mode, both graphics modes) are not affected, since they only access video RAM half as often.

For the record, changing the palette is not one of the things that show garbage (since it's a register). Only stuff accessing video RAM (i.e. characters or their attributes) will cause garbage. And of course, this was fixed in all later video cards.
Brendan wrote:For VGA and anything more modern; without vertical sync there's a risk of something called "tearing", but this is not noticeable unless the entire frame is changed every frame and you're extremely unlucky and happen to update the screen at a "close to monitor refresh rate" frequency for long enough.
(emphasis mine) OH GOSH, THIS. I lost track of how many times I tell people that if the framerate isn't close to the refresh rate then vsync should be turned off, since it only results in an erratic framerate without any real benefit (as tearing was never noticeable in the first place). Only turn on vsync when the framerate is close to the refresh rate.
Octocontrabass
Member
Member
Posts: 5567
Joined: Mon Mar 25, 2013 7:01 pm

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Octocontrabass »

~ wrote:Remember that it's a generic VBE driver. Ideally all machines would use it as with Windows XP when you are still installing it.
I'm talking about the "wait for vblank" VBE functions, which aren't used by Windows XP as far as I know. (And if that's a generic VBE driver, it probably doesn't use them either.)
6502Rulez wrote:I wanted to do C64-esqe demo and some games, but that won't look too pretty without the sync.
There's a lot more variety in PC hardware than in C64 hardware. That makes bare-metal demos impractical unless you're targeting a specific model of PC.
6502Rulez wrote:I was thinking about setting the PIT irq at ~70Hz and then do some delay. You could change the delay at run time via pressing buttons until it looks stable. What do you think ?
The PIT and the video card won't necessarily be using the same time sources, so it might be difficult to get them to stay synchronized. I'd be interested in seeing how well this works for you.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by Brendan »

Hi,
6502Rulez wrote:Thanks, that makes a lot of sence now. It's a shame. I wanted to do C64-esqe demo and some games, but that won't look too pretty without the sync.
The entire point of C64-esqe demos was to go beyond what normal people believed the hardware is capable of (e.g. getting 1024 colours on CGA, because normal people wouldn't think that's possible).

For a C64-esqe demo on modern hardware the point would be the same, the only thing that has changed is what normal people think the hardware is capable of. For example, if normal people think modern GPU is capable of full 3D with lighting/shadows at 60 frames per second at 4K resolution with 16 million colours; then the goal of a modern C64-esqe demo would be to exceed that.
6502Rulez wrote:I was thinking about setting the PIT irq at ~70Hz and then do some delay. You could change the delay at run time via pressing buttons until it looks stable. What do you think ?
I think you're trying to create a very different type of demonstration - a demonstration where the goal is to exceed the user's expectation of how bad software can be. ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
6502Rulez
Posts: 20
Joined: Tue May 16, 2017 6:50 am

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by 6502Rulez »

Brendan wrote:Hi,
6502Rulez wrote:Thanks, that makes a lot of sence now. It's a shame. I wanted to do C64-esqe demo and some games, but that won't look too pretty without the sync.
The entire point of C64-esqe demos was to go beyond what normal people believed the hardware is capable of (e.g. getting 1024 colours on CGA, because normal people wouldn't think that's possible).

For a C64-esqe demo on modern hardware the point would be the same, the only thing that has changed is what normal people think the hardware is capable of. For example, if normal people think modern GPU is capable of full 3D with lighting/shadows at 60 frames per second at 4K resolution with 16 million colours; then the goal of a modern C64-esqe demo would be to exceed that.
6502Rulez wrote:I was thinking about setting the PIT irq at ~70Hz and then do some delay. You could change the delay at run time via pressing buttons until it looks stable. What do you think ?
I think you're trying to create a very different type of demonstration - a demonstration where the goal is to exceed the user's expectation of how bad software can be. ;)


Cheers,

Brendan
I know that C64 coding (or any demoscene coding for any platform) is about beating the limitations, I can code the C64. I just wanted to do some software rendered effects in the 320x200 VGA mode for fun. I thought that I'd be safe to use the VGA stuff as it's implemented in every PC, turns out it is not that complete and reliable. I'm still gonna try though, see how it goes.
Octocontrabass wrote: The PIT and the video card won't necessarily be using the same time sources, so it might be difficult to get them to stay synchronized. I'd be interested in seeing how well this works for you.
The biggest problem is that it's not possible to program the PIT at exactly 70Hz (as far as I know, I'm a newbie if it comes to PC coding at this level) since the base frequency is 1193181 Hz and I can only divide it to get 70.001818715Hz ... very close, but not quite. If it was the same it would be only a case of delaying it until it's in sync. WIth this I'd have to do different delay for each frame and I can't think of any algorithm now that could do that.
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by hgoel »

You can treat 70.0018... Hz as pretty much 70Hz, it's close enough and a clock at that rate likely won't be accurate to a difference of 367ns per tick anyway.
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
6502Rulez
Posts: 20
Joined: Tue May 16, 2017 6:50 am

Re: Polling for VSYNC doesn't work (0x3DA port)

Post by 6502Rulez »

hgoel wrote:You can treat 70.0018... Hz as pretty much 70Hz, it's close enough and a clock at that rate likely won't be accurate to a difference of 367ns per tick anyway.
Yeah I guess so. As I said, I just wanted to do some flashy effects, so that won't look pretty without proper sync, but this is all just x86 assembly exercise. I'll do something else. Here's a little C64-like boot up screen with text mode working like on the C64 (separate char rom and color rom) and keyboard typing. I'm not planing on doing whole basic (if that wasn't obvious) but just some mockup loading screen for the proper product.
Image
This should work on all PCs because I only enter the 0x13 GFX mode and don't change the standard palette.
Post Reply