Starflight
Volume Number: 3
Issue Number: 8
Column Tag: Forth Forum
Starflight in the Forth Dimension
By Jörg Langowski, MacTutor Editorial Board, Grenoble, France
Starflight Demo in Forth
We’ll have another contribution from our active reader in Finland this month.
Juri Munkki has worked out some graphics animation routines in Mach 2 which will
work with either the alternate screen buffer (fast, but not supported on the Mac II) or
with a separately defined off-screen buffer (slower, but Mac II - compatible). The
program example is Mike Morton’s Starflight demo, rewritten in Forth. In the course
of this article, we will not only learn something about animation in Forth, but also of
things to consider in a turnkey application when the alternate screen buffer is used.
Finally, I’ll briefly inform you about the latest release of Mach2 (v2.11). But
let’s first look at the graphics animation demo and the comment that I received from
Juri with it.
The Many Faces of the Alternate Screen
Animation is the basis of all arcade games. A microcomputer fast enough to satisfy
the needs of every games programmer has yet to be designed. An alternate graphics
buffer is very useful in eliminating flicker. The program can draw on a buffer while
the user is watching the other buffer. When the frame is ready, it is displayed and the
previously visible buffer is hidden.
Double buffering is available on the Mac 128K, 512K and Plus, but it is not
available on the Mac II and probably will be missing or different in future Macintosh
models. Because of this, the programmer must choose between fast animation and
future compatibility. This choice has usually been made at the time the program is
written, but doesn’t have to be that way.
In this article I will present a basis of a double-buffering animation system. I
have written two interchangeable programs that eliminate flicker from animation. The
first program can not be used on machines that don’t have the alternate screen, but it
is much faster than the other one. The second program should work on all computers.
The second program allocates 22K of RAM and draws only to this place. It then
copies the result to the screen with CopyBits. It takes more time because we have to
make the copy instead of flipping one bit in the VIA.
There are three main routines: InitAnim, StartDraw and ShowB. In addition to
these the program may access a handle to the drawing buffer. An animation program
starts by calling InitAnim, which may relaunch if the alternate buffer is not available.
StartDraw is called before drawing an animation frame. It clears the buffer to black
and makes Grabu the “ handle” to the buffer. You may draw directly in the buffer with
his own routines or you can use QuickDraw. When the frame is finished, a call to
ShowB will either copy it onto the screen or it will switch display buffers.
Freeing the Alternate Buffer for Animation
Gaining access to the alternate buffer has never been easy. With the old ROMs the
program had to launch itself to move the stack below the screen memory. New ROMs
place the cache RAM on the alternate screen buffer. [Get the idea that Apple is
discouraging our use of this feature? -Ed]
Most animation programs don’t work with the cache on because they write
directly on the cache memory. The segment loader isn’t smart enough to move or clear
the cache when it is asked to launch a program with the alternate screen option set.
(See fig. 1)
Fortunately it was very easy to guess where the cache settings were located. Since
they are saved even when the computer is turned off, they had to be in the parameter
RAM. The parameter RAM is located in the clock chip and it can hold 20 bytes. I
examined the parameter RAM with different cache settings and the results can be found
in figure 1. Since the old ROMs used only 18 bytes, the cache settings are saved in the
two remaining bytes. (Note that all of this discussion assumes a Mac Plus
configuration. If the Mac SE and the Mac II are different, I have not fully covered or
mentioned those differences)
The cache is never changes while an application is running. The segment loader
changes the size of the cache when a new application is launched. It looks at the RAM
copy of the parameters to determine if the cache needs to be changed. We can keep the
original cache settings in the clock chip while relaunching and restore the original
settings by calling _Initutil. (See fig. 2)
Of course, there is a catch. The new ROMs contain an interesting feature.
(feature: a bug as described by the marketing department, ref: APPLE ][ reference
manual) If the segment loader has to remove the cache, it forgets to allocate the
alternate buffer. If the program now looks at CurPageOption, it will see the value it
gave when launching and happily overwrite its own stack.
The program has to launch itself twice if the cache is on (Fig. 2). The first time
it turns the cache off and tries to launch with the alternate screen in case apple
changes the ROMs again. The second time around it probably detects that the stack is in
the wrong place and relaunches. This time the segment loader doesn’t have to change the
cache, so it gives some thought to the alternate screen. The third time around, there
should be no need to relaunch and the program continues.
Jörg’s Commentary
As Juri’s examples contains a lot of new interesting definitions that can be useful
in other contexts, I’ll add some explanatory remarks. First, you won’t be able to run
the alternate screen buffer version of the demo if you have things installed in high
memory that would be overwritten. TMON is an example of a resident program that
won’t work with programs using the alternate screen, except if you install it in the
system heap. Second, testing the first version from Mach2 (not having TURNKEYed the
program) will most probably throw you back into Mach2 again if a condition arises
that causes the program to relaunch itself. Then you should reload the demo and start
again. The second version with an off screen buffer defined independently of the
alternate screen will have none of these problems as long as enough buffer memory
(22K here) is available.
We have already seen (in the last column) the new version of ANEW that will