Video Screen Anim
Volume Number: 2
Issue Number: 6
Column Tag: Pascal Procedures
Alternate Video Screen Animation 
By Mike Morton, Lotus Corp.
This article discusses using the Mac's alternate hardware screen to get smooth,
flicker-free animation. We'll use the “vertical retrace manager” to synchronize
screen-switching with the hardware screen refresh. The subroutine package presented
does this synchronizing and helps the calling program ensure that it's drawing
animation frames at the desired speed. It also tells the program how much “slack”
time it has after drawing each frame. The source for a simple bouncing square demo
program which uses the subroutines is included here. Another program,
“Vanlandingham”, uses the same package to mimic Amiga's famous bouncing ball demo,
but its source is too convoluted to publish. Both applications are distributed on
MacTutor's source code disk #9.
Hidden Gotcha
Warning: These programs use the alternate screen buffer, an area of memory
that is also used by the Mac Plus RAM cache. As a result, when the program exits,
Finder information previously in the cache will be lost causing a system crash. To
prevent this, turn off your RAM cache with the control panel. It's possible to design an
interface to let the system know your application is using the alternate video buffer,
forcing the Mac to configure the cache somewhere else. We invite readers to investigate
how this might be done. For similar reasons, this program doesn't work with all
software or hardware. It may not like RAM disks, debuggers, or some hard disks. As
with any application which doesn't have a QA group to test it, you should back up your
files and take other precautions before trying it.
The animation package uses two slightly obscure features of the Mac, one in
hardware and one in software. The hardware feature is the alternate screen, a second
bitmap in RAM which can be displayed instead of the default one. The software feature
is the vertical retrace manager, which calls subroutines periodically, in sync with the
“vertical retrace interrupt”, a sort of hardware heartbeat in the Macintosh. Both of
these are covered only briefly here, since they're documented elsewhere.
Quick review #1: The alternate screen
The Mac hardware redraws the screen 60 times a second, repeatedly reading the
screen from RAM and interpreting bits as black or white pixels. By default, it reads
from a hardwired address, available from the base address of Quickdraw's
“screenBits” bitmap. The hardware can also read from a second address, 32K lower
than the default, and software can request that this alternate screen (sometimes called
the alternate video “page”) be used.
Fig. 1 Bouncing Ball from the “Vanlandingham” Program
A simple animation program without the second screen just repeatedly erases
and redraws images. The problem with this is that the hardware “strobes” the image
in RAM at unpredictable times. The bitmap may be strobed between animation frames
and the software can get caught with its pants down. The result is flicker.
A better solution is to use two screens. The hardware displays one screen while
the next animation frame is drawn on the other. Software can detect when the current
screen refresh is complete, and ask that the next refresh be drawn from the newly
drawn bitmap. Then while that bitmap is showing, the original bitmap can be erased
and filled with another frame. This way, drawing and display always use different
screens. The result is much less flicker.
Apple didn't make it easy to use the alternate screen. The decision to configure
the alternate screen is usually made by the program which launches you; the Finder
won't ever do it, though. You can't reserve the second screen through traditional
memory management after launch, because you can't specify the area to allocate. The
generally accepted method of getting the second screen is to check whether it's available
at startup and, if it's not, to re-launch oneself with a request for the second screen.
(Of course, if the request ever fails for any reason, such a program will loop
forever)
There are some problems to keep in mind when using the alternate screen:
•future Macintosh models may not support it (the May 1985 software supplement
warned about this)
•cursor handling seems to assume that the default screen is in use; do a HideCursor
call before switching
•you should switch to the main screen before exiting to the Finder
•Debuggers, RAM disks, and other things which survive across launches may occupy
the memory where the alternate screen is; this is hard to detect and avoid
For more on the alternate screen, see Tom Taylor's article on the subject in the
August 1985 issue of MacTutor. For a detailed description of the hardware, I
recommend The IM Underground. The latter has some ideas on allocating the screen.
Quick review #2: Vertical retrace tasks
The Mac operating system lets you leave “wake-up calls” for subroutines,
allowing you to specify the delay (in 60ths of a second) before the subroutine is called.
This is handy for a lot of things, including screen switching.
Each time a screen refresh is completed, the Macintosh gets a “vertical retrace
interrupt”. At this time, the system may perform several housekeeping tasks:
updating the cursor position, bumping the tick count, and so forth. It also checks the
list of subroutines which have left wake-up calls, seeing if it's time to call any of
them.
Vertical retrace tasks, as these dozing subroutines are called, are pretty simple.
The chapter of Inside Macintosh which describes the vertical retrace manager is just a
few pages. Ignoring a few fields, the essential parts of the “queue block” for the task
are (1) the address of the routine and (2) the time left until it should be called.
The exact time at which these routines are called is perfect for switching
screens. It happens between screen refreshes, so the switch doesn't occur halfway
down the screen (giving you a fleeting split image). [It is possible for many
time-consuming retrace tasks to be called, and for the switch to be delayed until after
the refresh has started. This is very unlikely.]
Some problems crop up in calling routines this way. The most insidious appears
randomly when someone alters A5. This is legal as long as they don't call anyone who
expects A5 to be correct. If an interrupt comes in while A5 is changed, the system will
call the retrace tasks with the wrong value of A5. It's up to each task to either load the
correct value from “CurrentA5” in low memory or not use A5 at all. Recent versions
of Inside Macintosh describe the OS Utilities “SetUpA5” and “RestoreA5” which can be
used to avoid this problem in Pascal. Note that even if your application doesn't mess
with A5, desk accessories and the ROM still may. Be paranoid.
Lesser problems with vertical retrace tasks include:
•you should make sure that your task is gone from the queue before leaving the
application; otherwise someone else's code (such as the Finder's) will be loaded
over the task's old address and the vertical retrace manager will call that address
with horrifying results
•your task can't perform any memory management, since the state of the heap may
not be consistent; in general, you must be careful about any operations on global
data structures
•the task must set its “alarm” each time it's called, or it won't be called again
Inside Macintosh covers the vertical retrace manager pretty well. Robert
Denny's article in the August 1985 MacTutor gives a good example of using these tasks.
Fig. 2 Our bouncing square demo program
Putting it all together
Here's a package to synchronize screen switching. It has three subroutines:
getaltscreen -- This should be the first thing your application calls. It checks
whether the alternate screen is configured and, if not, relaunches the application to
include the screen.