[comp.sys.atari.st] Screen flicker, top

currier@romeo.cs.duke.edu (Bob Currier - DCAC Network Comm. Specialist) (08/14/89)

Greetings,

This weekend, while noodling around with animation, I came across a
most puzzling phenomena.  My graphics displayed fine while on the
lower part of the screen (I am using a monochrome 1040), but when
my little critters got about 30 or 40 pixels from the top they
started to get a bad case of the flickers.  I was using Vsync() to
control flicker, and it seemed to work well, except for this
twilight zone. 
 
I pulled my hair out for a couple of hours on this one, dug thru all
my books, and finally, at about 1 a.m., in the premier issue of START,
found a comment in an article about al graphics that went like this:

"...vsync, but you will still see flicker near the top of the screen.  This
is a problem that can only be dealt with by very complex multiple screen
flipping techniques..."

So, does anyone know of this problem?  What causes it? And, Virginia, how
can I eliminate it?


Bob Currier
currier@romeo.cs.duke.edu
rdc@northlab.ac.duke.edu

leo@philmds.UUCP (Leo de Wit) (08/15/89)

In article <15286@duke.cs.duke.edu> currier@romeo.cs.duke.edu (Bob Currier - DCAC Network Comm. Specialist) writes:
|Greetings,
|
|This weekend, while noodling around with animation, I came across a
|most puzzling phenomena.  My graphics displayed fine while on the
|lower part of the screen (I am using a monochrome 1040), but when
|my little critters got about 30 or 40 pixels from the top they
|started to get a bad case of the flickers.  I was using Vsync() to
|control flicker, and it seemed to work well, except for this
|twilight zone. 
| 
|I pulled my hair out for a couple of hours on this one, dug thru all
|my books, and finally, at about 1 a.m., in the premier issue of START,
|found a comment in an article about al graphics that went like this:
|
|"...vsync, but you will still see flicker near the top of the screen.  This
|is a problem that can only be dealt with by very complex multiple screen
|flipping techniques..."
|
|So, does anyone know of this problem?  What causes it? And, Virginia, how
|can I eliminate it?

My name is not Virginia, Bob, but I still think I can make some sensible
remarks about this one.

Flicker is caused by updating the physical screen, that is: writing to
the physical screen in some way. Most often one erases part of the
screen, then draws on the erased part; at the same time this part of
the screen is being read by the video stuff. Most animations use a
separate screen to draw in, then as the picture is complete, swap the
screens. All GEMDOS, (X)BIOS and GEM functions that deal with graphics
(including characters) are being drawn on the logical screen (a chunk
of 30000 bytes of memory pointed to by a system vector, 0x44e if my
memory is OK 8-). The physical screen location is determined in two I/O
addresses (it always starts on a 256 byte boundary).  For reading the
screen 3 I/O addresses are being used; they correspond to registers in
the shifter (an ST custom chip for the video stuff). After each VBL
these addresses are reinitialized from the two 'physical screen start'
I/O addresses (this is also the reason that, though you could alter the
physical screen start between VBL's (the XBIOS function Setscreen()
does this), it can only take effect at the moment of the next VBL (the
3 I/O addresses for reading the screen are read-only).

The Vsync() is not totally unuseful: it synchronizes your software with
the VBL, that is, you know that after a Vsync() statement the shifter
reads at the top of the screen (so at that moment avoid updates there).
You could do updates to the lower part of the screen, or use a timing
loop so you know the shifter already has had the upper part.
Alternatively you could read the 3 I/O addresses (in supervisor mode,
of course) to determine where the shifter is currently reading; in this
case you don't need the Vsync(), which really can speed things up (I
know, I did this myself).

The most commonly used technique is to use two separate screens, one as
the physical screen, one as the logical (as mentioned above), draw your
stuff on the logical one, then use Setscreen to swap the screens. Now
you must do a Vsync() before any new updates of the (new) logical
screen, because remember until VBL it is still the old physical screen,
which is being read by the shifter.  This technique is guaranteed to be
flicker-free, and, as opposed to what was possibly mentioned in START,
is not difficult at all.

A third technique is a somewhat more complicated variant of the second one.
Its main idea is to use several screens (more than two) to avoid using
Vsync(), thus gaining in speed. You use the screens alternatively:

screen1 physical, screen2 logical
screen2 physical, screen3 logical
etc.

screenn physical, screen1 logical
screen1 physical, screen2 logical
etc.

The number of screens to use depends on the speed with which you can
draw a new image on the logical screen. Since a physical screen remains
fixed for at least one VBL period, doing the cycle of n screens must
take at least one VBL. Since it doesn't make sense to swap screens a
lot during a VBL period (only the last one takes effect) and it DOES
take some time in general to redraw your screen, a useful number of
screens is 3.

Hope this helps - if you need the exact location of the I/O addresses
I can look it up for you.

    Leo.