13

I'm making a small graphics library for MS-DOS 6.22, using mode 13h with Turbo C on VirtualBox.

Recently, I was able to code a small snippet to move a sprite on the screen, using double buffering and I saw that there was a lot of flicker... I started browsing documentation and found that I need to synchronize the vertical blanking interval to my program refresh rate. But how?

Do I need to access port 03DAh?

1
  • 6
    Mode 13h has 70 Hz refresh rate by default, so unless you can get your actual physical screen to run at that rate, it will not look smooth, no matter what you do in your DOS program, emulator or virtual machine. And even if you manage to set up a properly synchronized 70 Hz display yourself, practically the whole rest of the world will be 60 Hz, so your program will look bad on practically everybody else's monitor. If you want a Youtube era compatible 60 Hz VGA mode, you'll have to use a "tweaked mode" of some kind, or the 640x480x4bpp mode which is 60 Hz without tweaking. Apr 30 at 11:31

2 Answers 2

13

Yes, you need to synchronize framebuffer updates to happen so that the framebuffer area is not updated by your code while that area of framebuffer is being drawn on screen.

Port 03DAh has bit 3 signalling the vertical sync. Whenever that bit is low, assume that the visible area of the screen is being drawn. When that bit is high, the vertical sync period is ongoing and framebuffer data can be updated safely.

So have your code wait for 03DAh bit 3 to become low, and then wait for that bit to go high, and then update the framebuffer.

In C-like pseudocode which is not optimized for simplicity:

while( (inportb(0x03DA) & 0x08) == 0x08);
while( (inportb(0x03DA) & 0x08) == 0x00);

However not many virtual machine environments properly emulate VGA vertical sync at this level, as their intended purpose is not to run games or graphical software which directly use VGA ports.

You might have better luck with emulators intended for this, such as DOSBox, PCEm, or the like.

3
  • why are you using 0x08 instead of 0x04? Isn't 0x08 the fourth bit?
    – SlickSpore
    Apr 30 at 14:02
  • 5
    @SlickSpore No, because bit 0 is the first and bit 7 is the last.
    – Justme
    Apr 30 at 14:05
  • 4
    On Vbox still doesn't work, but on DosBox works just fine without the VBI sync...
    – SlickSpore
    Apr 30 at 14:47
8

It depends on the details of the graphics card simulation on VBox, which in turn depends on which graphics mode you have chosen, but assuming you are interested in how it worked on legacy VGA, you have chosen VBoxVGA, and VBox emulates the VGA faithfully:

Then yes, you'd poll port 03DAh bit 3, and wait for the vertical retrace to happen, and switch the buffer only during vertical retrace.

It's up to you if you do busy polling, or if you do something useful while waiting.

Also note that this is pretty inefficient both on more modern graphics cards and with more advanced emulated graphics adapters under VBox.

With regards to using an IRQ: That's likely possible in the other VBox modes, but you really need to read up on the details of the emulation.

7
  • 6
    +1 There is no vblank IRQ on standard VGA hardware so you need to poll, but on a real machine or on a faithful emulator you can reprogram the PIT (timer) each frame to trigger just before the vsync, which minimizes how long you need to poll for.
    – matja
    Apr 30 at 10:27
  • 6
    @matja That is actually incorrect. There is VBLANK IRQ on standard IBM VGA, for example on PS/2 systems where it is integrated to motherboard. The use of it is difficult though, so usually it is not used by games. It is difficult because clone manufacturers may not implement it properly, and it was anyway fixed to IRQ2, which on dual PIC systems was physically IRQ9, and some other devices such as Roland MPU-401 PC adapters use IRQ2 by default. So you could not rely on it being available or working.
    – Justme
    Apr 30 at 11:10
  • 2
    @Justme In actual cases that actually matter, there was actually no vblank IRQ, so matja is actually correct. :) Apr 30 at 11:27
  • 5
    @piiperiReinstateMonica Running code on standard PS/2 models is an actual case that mattered. But it is unusable on other clone hardware due to practical reasons. It does not remove the fact that standard VGA hardware was designed with vblank IRQ, even if due to clones and other practical reasons, you could not utilize it. There is a big difference between not having it at all (false) and having it but being unable to use it for technical compatibility reasons (true).
    – Justme
    Apr 30 at 11:53
  • 1
    @Justme I suppose you know at least a few games which used the PS/2 vblank IRQ? Why would anybody have wasted time targeting game code specifically for IBM PS/2, it makes no sense. May 6 at 13:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .