GEM COLOR CASCADE
How to convert 8-bit Atari program for the ST
by PATRICK BASS, Antic ST Program EditorIn May, 1985 I wrote a letter to the Editors of Antic asking
if I could perhaps write an article or three for them. I mentioned that
I had been a game designer/programmer for the old Atari during its heyday,
and that later I programmed games for two Silicon Valley start-up companies
that didn't quite "start up."
So one Thursday when I'd just gotten home from being told
I was overqualified to deliver pizzas, my father told me Antic phoned
and wanted me to come up to San Francisco and see the editors. The next
morning I hopped onto my Yamaha 250 motorcycle and hit the freeway. Shortly
before noon, Antic sat me down at a 520ST and wouldn't let me leave.
I was in hog heaven when Antic hired me to learn
how to program their development ST. I had already decided to buy a 520ST
when it became available, my only problem was figuring out how to afford
one.
The pile of highly technical documentation that came with
Antic's
520ST was almost three feet high. I took home as much as I could carry
and spent the weekend reading it.
Back at Antic on Monday morning I confidently expected
to start writing my first 520ST program using 68000 machine language, which
I'm familiar with. However, the ST had other ideas.
For one whole day I was stuck at one seemingly innocent
statement (.ORG or Originate) that told the computer where to start putting
my program into memory. The 520ST absolutely would not get past this.
After what seemed like a couple of eternities I finally
figured out that I was mistakenly assuming the 520ST acts like a microcomputer.
In fact it acts much more like a minicomputer.
The ST operating system is essentially Digital Research's
CP/M 68K, which is a multi-tasking system that can run more than one program
at the same time. If two or more programs tried to occupy the same memory
address at the same time, the computer would fail.
Therefore every application program written for the ST
must be completely relocatable, able to run from any address. This is not
really so strange. Any interpreted BASIC program on any computer is completely
relocatable, it's constantly being shifted up and down in memory as you
add or delete lines to your program.
COLOR SINEWAVE
It took another two weeks of solving more mysteries like "The Riddle
of the Crashing ORG Statement" before I was actually ready to get a program
up and running on the 520ST...
I had never programmed in C before I sat down at the ST.
And I was happy to discover it's possible to write programs in C that look
very much like BASIC. To demonstrate this, I'll explain how I wrote a program
that does the same thing in C on a 520ST and in BASIC on any 8-bit Atari
computer.
A simple program that I've used many times creates an
impressive graphic display. It plots a sine wave from left to right and
a cosine wave from right to left. Then each time it plots a pair of sine
and cosine dots, it draws a line between them. The result is a pattern
of lines that cascades differently across the screen each time.
BASIC COLOR SINE
It's safe to assume that more Antic readers can program in BASIC than
in C. So let's get started by examining the BASIC program for 8-bit Ataris
line by line.
Line 100 opens a channel to the keyboard and line 110
sets the X, Y screen limits of Graphics Mode 8.
Line 120 creates an endless loop. If you program a loop
in BASIC with a STEP size of zero, that loop will never end. Since we have
a beginning value of zero and an exit value of one, the loop will never
reach one until we reset LOOP to a value higher than one. This is as close
as we can get to a REPEAT... UNTIL construct in Atari BASIC.
Lines 130-140 set the graphics mode and set the background
and border colors to black.
Lines 150-160 select a random number between 10 and 80
for the AMPLITUDE (height) of the wave.
Lines 170-180 select random numbers between 5 and 75 for
the PERIOD of the wave. The period of a sine or cosine function determines
how many times the value returned from sine or cosine will cycle within
a given space. The smaller the number, the more "hills and valleys."
Line 190 places a random value between 1 and 6 into the
variable SIZE. Line 200 uses SIZE as a STEP value in a FOR/NEXT loop which
determines the number of X points to be plotted along the X axis.
Line 210 figures the first Y axis point. Look at it as
BASIC would, beginning from the innermost set of parentheses. XPOINT and
SINE-PERIOD might typically hold values of 110 and 30 which result in 3.66
when divided. BASIC will then calculate the SIN of the result, which will
yield -0.5012.
This is then multiplied by SINE-AMPLITUDE, (typically
around 50) giving an answer of -25.06. Since sine and cosine values may
range below zero, and BASIC cannot PLOT negative values, we add half the
screen height (YRES/2) in order to shift the dot about halfway down the
screen.
Line 220 performs the same action as 210 for the cosine
value.
Line 230 PLOTs the first pair of points, using XPOINT
and SINEY, and DRAWs a line TO the right side of the screen minus XPOINT
and COSINEY.
Line 240 checks to see if a key has been pressed while
the computer was figuring and drawing the line. If so, it cleanly finishes
the loop by setting the XPOINT counter to its highest expected value, which
line 250 awaits to finish its drawing loop.
Line 250 completes the logic of the drawing loop.
Line 260 places the value of any key pressed during the
loop into KEYPRESS. Line 270 then checks to see if the character pressed
was an X. If so, the value for the LOOP counter is set greater than its
exit value and we the leave loop-and the program.
GEM COLOR SINE
Now that we've gone through the BASIC program, let's take a look at
how it works in the C listing, step by step. If you are unfamiliar with
C, you should first read our sidebar-C at a Glance.
The first two lines of the C listing are comment lines
bracketed between / * and * /. The next five lines cause the C compiler
to #include files containing previously typed defihitions that may
be used throughout the program. You may use or ignore these definitions
as you see fit.
The whole next block of code- down to, but not including
main(
)- is our declaration of the variables and arrays to be used by the
program. The first two lines are required by GEM and provide a way to send
GEM control and input parameters, while GEM sends back parameters as answers
or limitations.
The rest of the int's are 16-bit variables which we chose
for the program. There are also two doubles because these variables will
be required to hold values greater than 16 bits.
extern double means that these are routines already
saved on another disk file which we will link in our program during compilation.
Think of these routines as pre-written functions.
Since our program is small, it will all be contained within
the main() function. All functions called within main( ) will be provided
by either the C library, or whichever files are included or linked at compilation
time. Most of the functions will be GEM calls.
THE MAIN
Now that we've taken care of all the declarations, let's look at our
main(
) program, step by step.
The first thing you see is a left curly bracket (brace).
This means "begin." At the bottom of the program, you will find the right
brace which means "end." But within the program are more braces containing
the beginning and ending of logical routines
Our first actual program statement is appl_init( );.
We can see that it's a complete statement since it ends with a semicolon.
appl_init(
) is a routine that prepares GEM to receive information from our application.
Following this is handle = graf_ handle(&dummy,
&dummy, &dummy, &dummy);. Since GEM can have more than
one screen window open at any time, we need a way to keep track of which
window we want.
When we make this call, GEM assigns a number to the new
window and stores it in the variable we have chosen to call "handle."
GEM returns additional information from the graf_handle
call- such as the X,Y co-ordinate of the upper left corner of our window.
Our program doesn't use this information, but we need to provide parameters
(&dunmy) for GEM to store the data.
C "FOR" LOOP
Now we get to a statement which is very similar to a BASIC FOR/NEXT
loop. The elements are: FOR (entry condition of loop; condition to be satisfied
for the loop to continue; STEP value for loop). In BASIC this would be:
FOR I=0 TO 9 STEP 1: NEXT I.
In C the loop says: for (i starts at zero; continue as
long as i is less than 10; use i, then increment it). The last part could
also have been written as i=i+1, or, more cryptically, i+ =1.
The instruction executed within the loop is contained
between the braces. This loop fills an array called 1_intin with
information such as line style, color, and character size. This data is
needed by GEM prior to opening the graphics window.
The next statement is v_opnvwk (1_intin, &handle,
1_out); similar to a GRAPHICS call from BASIC. 1_intin is the
list of parameters passed to GEM that we prepared above. &handle
means: "give the address of the handle to GEM", and 1_out is an
array that GEM returns describing things like screen size and number of
colors. We can later access these values if and when we need them.
For example, right below we use three of those values.
xres
is how wide the screen is, yres is how high the screen is and max_color
is how many colors we can work with on the device opened. By using these
variables, instead of constants, we can be assured our program will work
in all video resolutions.
Now, we encounter a FOR loop which directly corresponds
to the FOR loop in the BASIC program that defines our "endless" loop. This
line reads: Loop starts at zero. Continue as long as loop is less than
one. Each loop add nothing to Loop.
The next DO WHILE construct will choose a color. It reads:
DO choose a random number called COLOR between 0 and 15 WHILE COLOR is
less than zero OR (the two vertical lines mean OR) COLOR is greater than
the maximum number of colors we can show on the screen.
The next line vsl_color (handle, color);, corresponds
directly to the COLOR statement in the BASIC program. It selects which
color the line will be drawn with next.
The next line selects a random number between one and
four for the STEP value in our drawing loop.
The next four DO WHILE constructs will select a random
number for the amplitude and period of our sine and cosine values in the
drawing loop.
DRAWING LOOP
Now we enter the drawing loop itself, which uses the variable iter
as a counter across the screen.
We indent again to show we are in another loop.
Next we set xpoint, a double precision variable,
equal to the value of iter so we can perform floating point math
on it.
The next two pairs of lines will figure the values needed
for our two line endpoints. The GEM call that draws a line is called v_pline(
), but before we call it we need to figure in advance which X,Y points
the routine will draw to. Then we place them as elements in an array variable
which will become one of the parameters in the GEM call. We could specify
more than just one pair of points if we needed to.
V_PLINE
We now come to the nucleus of the program: vpline( ). This call
reads: "GEM, draw a polyline inside window 'handle'. The line has two points
and the X, Y coordinates for the line are in an array called 'ptsin'."
v_pline( ) is very much like the BASIC USR calls
which are in Antic's GUP program (June, 1985). You establish your
parameters and variables, then place them in the parentheses and make the
call. GEM does the rest.
The matching brace which ends our drawing loop FOR construct
acts the same as NEXT in BASIC
ENDLESS LOOPING
We now come to a DO WHILE construct that creates an endless loop. The
GEM call vq_key_s( ) will cause GEM to put the value of Shift/ Alternate/Control
keys in a variable called key_state.
It will continue to do this as long as key_state
is equal to zero, which means no keys are pressed. (The == means
"test for equality" and is different from a single , which means "is assigned
the value of.")
The IF statement causes the loop to exit by comparing
the key_state value to eight-the value of the Alternate key. When
the Alternate key is pressed, key-state is set to eight and the
value for our "endless" loop counter is incremented, causing the exit of
the loop.
If the alternate was pressed, we fall down to the v_clsvwk(handle)
call,
which will free the space GEM set aside for our workstation.
Then we come to the appl_exit( ); call, in which
we "un-hook" our application from GEM, and free the memory used for other
applications.
The last line is the brace that ends our main() function.
We hope this detailed take-apart gives you some idea of
how GEM is implemented in the Atari ST Many of you have never used C, so
you may have to struggle a bit. Again, take a look at GUP in our June,
1985 issue. GUP is very similar in concept to the GEM calls. The main difference
is that GEM uses the elements within arrays and the arrays utilized as
parameter elements in the calls.
Listing 1 SINEWAVE.BAS Download
Listing 2 Color Sinewave Program (GEM) (not available)
C AT A GLANCE
C is a compiled language, like assembly language. This means the original program is written on a text editor and saved in a file called the "source" code. This source code is compiled (translated) into machine or "object" code.
C source code contains no line numbers. The compiler uses spaces as delimiters between the recognizable symbols. Therefore it ignores spaces and carriage returns. For this reason, you can write C source code in any format you please. However over the years certain standards in C formatting have developed.
By custom. C code is written in lower-case letters, although it usually doesn't matter to the compiler. Indentation is an important element in C readability. Nested loops, for example, are indented.
NO LINE NUMBERS
Since there are no line numbers the compiler recognizes the semicolon
(;) to separate logical lines or statements. Similarly, there are structures-such
as the BASIC FOR/ NEXT loop, or the ACTION! DO...OD structure-which require
a delimiter that does not even appear on the Atari 8-bit keyboard. This
is the curly bracket "{". Left curly bracket means "begin" and right curly
bracket, "}" means "end."
DECLARING
In Atari BASIC all strings or array variables must be DlMensioned so
that BASIC knows how much room in memory to reserve for them. ln C, all
variables must be "declared."
This is necessary because C variables can take up different
amounts of memory, depending on their data type. Declared variables can
be a ''char'' (8 bits), ''int'' (16 bits), or "double" (32 bits).
Let's take a quick look at the overall structure of a
C program, and then we'll list some books which can really give c you the
details.
C programs are made up of a group of subroutines called
"functions". Functions may be written by the user, provided by the C compiler,
or provided by other files called "libraries." These library files are
merged with the code during compilation.
BASIC programmers may think of functions as USR calls.
Parameters may or may not be passed to them, and values may or may not
be expected in return.
Each function title will contain the name of the function,
followed by a pair of parentheses which contain any required parameters.
If a value is to be returned by a function, the word ''return'' followed
by parentheses must appear at the end of the function.
MAIN
Every C program must have one function called ''main'', which calls
the others. A small program may contain only the main function. To follow
a C listing, first look within the main function, which will act as a "table
of contents'' of the other functions.
Since C functions may come from the language, or the user,
or the library files, it becomes a matter of experience to differentiate
between those function titles reserved by the language and libraries, and
those created by the programmer. In the specific case of the Atari ST GEM
libraries, any function beginning with the letter ''v'' will be part of
a GEM VDI call.
C BIBLIOGRAPHY
THE C PROGRAMMING
LANGUAGE
by Brian W. Kernighan and
Dennis M. Ritchie
Prentice-Hall Software Series
Englewood Cliffs, NJ 07632
228 pages, paperbound
$24.50
SUREFIRE PROGRAMMING IN C
by Warren A. Stewart
TAB Books, Inc.
Blue Ridge Summit, PA 17214
270 pages, paperbound
$16.95
THE C PROGRAMMING TUTOR
by Leon A. Wortman and
Thomas 0. Sidebottom
Robert J. Brady Co.
(Prentice-Hall)
Bowie, MD 20715
274 pages, paperbound
$19.95
UNDERSTANDING C
by Bruce H. Hunter
SYBEX, Inc.
2344 Sixth Street
Berkeley, CA 94710
320 pages, paperbound
$17.95
LEARNING TO PROGRAM IN C
by Thomas Plum
Prentice-Hall, Inc.
Englewood Cliffs, NJ 07632
230 pages, hardcover
$32.95