Classic Computer Magazine Archive COMPUTE! ISSUE 87 / AUGUST 1987 / PAGE 72

ST Outlook

Philip I. Nelson, Assistant Editor

Page Flipping

Like many other microcomputers, the Atari ST has the ability to flip from one display screen to another almost instantly. While you're looking at one screen, a program can be secretly preparing a second, hidden screen in the background. As soon as the hidden screen is ready, you flip to that one, concealing the first.

Page flipping has many uses. In a word processor or database program, for instance, you might prepare several hidden help screens when the program starts. When the user requests help, you can display any of the help screens instantly. It's a slick solution that doesn't involve the delay of writing each help screen from scratch or the uncertainty of having to read a help file from disk.

This month we'll demonstrate two different approaches to page flipping. Both programs do essentially the same thing: They prepare two different screens and let you flip between them by pressing any key (press ESC to quit). But the methods are somewhat different.

Program 1, written in C, illustrates the conventional method of page flipping. The XBIOS routine known as Setscreen allows you to reset the ST's physical screen base and/or logical screen base. The physical base tells the ST's hardware which memory area to display on the screen, and the logical base tells the system where to send screen output. Program 1 sets up two screens in memory—the original screen and an alternate screen. Each time you press a key, the program swaps the screen addresses and calls Setscreen to display the active page. When you exit the program, it flips back to the original screen and deallocates the memory used for the alternate screen.

You could use the same method in GFA BASIC, since that lan-

Program 1 : Page Flipping In C
/* Short demonstration of page flipping on the ST */
/* Definitions for GEMDOS and XBIOS routines */
# include <osbind.h>
/* Line A commands to turn mouse off and on */
#define MOUSE_DIE asm { DC.W 0xa00a }
#define MOUSE_LIVE asm { DC.W 0xa009 }
long hidden_page, active_page, temp;
char msg1[ ] = "This is the original screen." ;
char msg2[ ] = "This is the alternate screen." ;
char msg3[ ] = "Press ESC to exit, any key to flip." ;
char crlf[ ] = { 13, 10, 0 } ;
main()
{
int key, foo;
long mem_chunk, pagel, page2, log;
pagel = Physbase(); /* Get physical screen base */
log = Logbase(); /* and logical screen base */
/* Get enough memory to hold the alternate screen. We need */
/* 32, 000 bytes plus enough to align on a 256-byte boundary */ mem_chunk = Malloc(0x8100L);
/* Find page-aligned address within our chunk */
page2 = ( mem_chunk | 0xff ) + 1;
active_page = page1; /* Original screen is active */
hidden_page = page2; /* Alternate screen is hidden */
MOUSE_DIE /* Hide mouse for the moment */
Cconws(crlf);
Print_it(msg1); /* Print message on original screen */
Flip (); /* Flip to alternate screen */
Print_it(msg2); /* and print message there */
Print_it(msg3);
MOUSE_LIVE /* Show mouse again */
foo = 1;
while (foo) /* Endless loop (loop until we break) */
{
key = Crawcin(); /* Wait for keypress */
if (key = = 27) break; /* Exit if it's ESC */
else Flip(); /* Flip screens otherwise … */
}
Setscreen(log, page1, -1L); /* Restore the original screen */
Mfree(mem_chunk); /* Release memory we grabbed earlier */
} /* end of main */
Flip()
{
MOUSE_DIE
/* Swap the screens */
temp = hidden_page;
hidden_page = active_page;
active_page = temp;
/* Display the active page */
Setscreen(active_page, active_page, -1L);
MOUSE_LIVE
}
Print_it(message)
char message[];
{
Cconws(crlf);
Cconws(message);
}
Program 2 : Page Flipping In GFA BASIC
' GFA BASIC Page-flipping Demonstration
'
' DIMension string array to hold screen images
Dim Screen$(1)
' Draw first screen
Circle 100, 51, 100
Deffill 1, 2, 9
Fill 100, 100
For J = 1 To 5
Print
Next J
Print Tab(4);"This is page one"
' Save image in Screen$(0)
Sget Screen$(0)
' Draw second screen
Cls
Print
Print Tab(4);"This is page two."
Print Tab(4);"Press any key to flip screens."
Print Tab(4);"Press ESC to exit."
Box 5, 5, 300, 40
Deffill 1, 2, 16
Fill 100, 100
' Save image in Screen$(1)
Sget Screen$(1)
' Flip screens 50 times
For J = 1 To 50
Flip
Next J
' Flip at your leisure
X = 1
While X
Flip
Waitkey
If Key$ = Chr$(27) Then
X = 0
Endif
Wend
Edit
'
Procedure Flip
' Exchange these variables
Swap Screen$(0), Screen$(1)
' Display Screen$(0)
Sput Screen$(0)
Return
'
Procedure Waitkey
Key$ = ""
While Key$ = ""
Key$ = Inkey$
Wend
Return

guage gives you access to system routines, but it also includes BASIC commands that make the job even easier. Program 2, written in GFA BASIC, begins by DIMensioning a two-element array named Screen$. After drawing the first screen, we use SGET (Screen GET) to capture the entire screen image and store it in the first array. Then we clear the screen, draw the second display page, and SGET that one into the second array.

Now there are two screens stored in memory—one in Screen$(0) and the other in Screen$(1). Time to use two more interesting GFA BASIC commands: The SPUT command lets you copy any screen-size string into the current display screen, and SWAP can exchange any two variables. The procedure named Flip performs a SWAP to exchange Screen$(0) and Screen$(1), followed by SPUT to display whatever happens to be in Screen$(0).

Because SPUT does a screen copy, we're not doing exactly the same thing as in Program 1. Rather than swap pointers with Setscreen, SPUT presumably copies the contents of the string directly into physical screen memory, a somewhat slower operation. The slight difference in speed won't matter in most applications, however, and nearly everyone will find the BASIC program easier to understand. To show how fast GFA BASIC can flip the screens, the program does 50 rapid flips before turning control over to you. If that's not fast enough for you, it's a fairly simple matter to call the Setscreen routine as in Program 1.