By Mikey Walters / September 18, 2017
This is the eighth and final installment in a series of articles about programming in Atari BASIC. The previous installments are here. Space Assault source code and references can be found here. BAS files for use with Atari emulators of the original program and enhanced program can be found here.
330 PRINT “Game Over”
In Lesson Seven, we learned how to draw Space Assault’s title screen, complete with theme music generated by Atari BASIC’s SOUND statement, and through the course of this series, we’ve covered nearly the complete source code of the game. Appropriately, the last section of code to discuss is the “game over” screen, which uses yet another powerful feature of the Atari Home Computer to combine multiple graphics modes.
After the Clovis aliens have destroyed all of the Vegetation Processing Plants on the planet Kala (unfortunately leaving Earth to starve), the “game over” screen is displayed. This screen includes horizontally scrolling or “marquee” text to describe the player’s fate, along with the player’s score and high score record. While playing some random sounds (presumably the Clovis aliens’ victory anthem), we wait for the player to press the Start key to begin the action again.
You may notice that the text at the top and bottom of the “game over” screen is larger than the text in the middle, and this is because we are combining two different graphics modes. As I mentioned in Lesson Seven, the Atari Home Computer’s ANTIC chip provides several graphics modes for both bitmapped graphics and text. The top and bottom of the “game over” screen uses Graphics 2 and the middle uses Graphics 1, which is accomplished by manipulating the display list.
340 PRINT “ANTIC Antics”
The best way to imagine a display list is as a “program” for the ANTIC chip. The display list tells the chip what kind of graphics to put on the screen from top to bottom, scan line by scan line. When the statement GRAPHICS 7 is executed, the appropriate “program” or display list is loaded so the ANTIC chip will output bitmapped graphics. When the statement GRAPHICS 0 is executed, the display list that outputs 40-column text is used, and so on. However, if an Atari programmer creates a custom display list and tells ANTIC to use it, almost any combination of modes is possible. This feature makes sophisticated displays (for 1980s home computers) possible, although it can be a little daunting to learn.
To begin a custom display list, we first start by setting a base graphics mode. We’ll modify lines of this base mode to change them to the other graphics modes we want to use. For the “game over” screen, we’ll start with Graphics 1 (medium text) and modify eight lines that we want to be Graphics 2 (large text), which looks like this.
After setting our base graphics mode, we find the start of the current display list in memory by PEEKing a specific set of registers, then move our way down the list and POKE new modes into the lines we want to change. When we are finished, we POKE a special set of values that signifies the end of our modified display list. That’s the general concept in a nutshell, but of course there are a few nuances to keep in mind, so let’s look at the code.
We begin by setting the mode to GRAPHICS 1+16, which may seem unusual. Most Atari graphics modes include a few lines of standard 40 column text (Graphics 0) at the bottom, providing a simple way to combine bitmapped graphics and text with no custom work. These modes were provided as standard display lists to support applications such as Atari’s educational software, and were quite handy for programmers when they needed a large bitmapped area with some “status” text at the bottom. But since we don’t want this kind of text for our “game over” screen, we can add 16 to the graphics mode to remove it, giving us a full screen of medium-sized color text.
Next, we find the start of the current display list in memory by PEEKing registers 560 and 561 and converting these two 8-bit numbers into a 16-bit address, which we store in the variable DL (line 1950). Notice we’re also adding 4 to this number, which is to account for overscan. Since the Atari Home Computer was designed to use a standard television, each base graphics mode already includes several blank lines in the display list to skip over the part of the screen that will be “lost” due to overscan. Adding 4 to DL ensures that we leave this overscan region alone before we start modifying lines of graphics.
Before we start actually modifying the display list, it’s important to know that the ANTIC chip refers to graphics modes using a different number than programmers use in Atari BASIC. Since we want to change lines to Graphics 2, we need to use the “ANTIC number” for this mode, which is 7 for Graphics 2. Every book or article about display lists always included a handy chart (see “Display list mode instruction table”), which was invaluable to programmers working with this feature. We’ll be referring to this chart several times in this lesson. The first line of a display list is an instruction called a Load Memory Scan (LMS), which is created by adding 64 to the ANTIC number of our first mode (7+64 is 71) and POKEing that number into our DL address minus 1 (also line 1950). This may sound complex, and although I never fully understood what this meant as a teenager, I could still accomplish what I wanted to do by using example code.
We finish the top four lines of Graphics 2 by POKEing 7 into the 2nd through 4th memory locations after our DL address (lines 1950-1960). Now we want to leave the next six lines of Graphics 1 alone, since they are already part of our base mode, so we jump ahead to the 11th location and POKE 7 into the next four locations (line 1960). Now our modifications are complete, and we need to finish the display list with an instruction called a Jump Vertical Blank (JVB), which is accomplished by POKEing 65 into the location after our last modification—the 15th location after our DL address in this case. Finally, we tell the display list where it started in memory by putting the values found in locations 560 and 561 into the next two locations after the JVB (line 1970). The JVB uses this address just like a GOTO statement, so the ANTIC chip can draw and redraw our custom display list to the television screen over and over.
With our new display list up and running, we can finally add some text by using simple POSITION and PRINT (abbreviated as “?”) statements. However, since we are combining different graphics modes, we need to explicitly tell the ANTIC chip which mode we are using. This is done by POKEing the graphics mode number (not the ANTIC number, surprisingly) into register 87 before each PRINT to a new mode, as shown here.
After setting the colors we’ll be using for our text, we determine if the player’s score in SC should be the new high score in HSC (line 1980). Before we print some large Graphics 2 text, we POKE 87 with 2 to let ANTIC know we’re PRINTing some large text, then position and print “GAME OVER” using Input Output Control Block 6, as I discussed in Lesson Seven (line 1990). Then we switch back to Graphics 1 text to print our player’s score and the high score, and finally print our large “PRESS START” text using various combinations of inverse and lowercase text. Since ANTIC’s large text modes can only display uppercase text, lowercase and inverse mode combinations are used to specify a different display color from the available colors we established with SETCOLOR earlier.
350 PRINT “Marquee Magic”
Let’s take a break from the somewhat confusing topic of display lists and look at the horizontally scrolling text that gives our “game over” screen some life. If you did any HTML coding during the early days of the World Wide Web, you might remember the now-obsolete marquee tag, which caused text inside the tag to scroll or move in various ways. Let’s use some Atari BASIC string manipulation to code our own marquee text, circa 1983.
First we use the DIM statement like we saw in Lesson Four to declare a 60 character string variable called X$, and we fill that string with some cruel taunts for our player (line 2010). Next we declare two more strings called A$ and C$ with the same length as X$, and copy X$ into A$ (line 2020). A$ will be used to display a portion of X$ on the screen, and C$ will be used to “move” the contents of X$ through A$.
All of the string magic happens in line 2030. Graphics 1 can display 20 characters of medium text on a line, so we begin by printing the first 20 characters of A$, which is currently the same as the first 20 characters of X$. Then we assign C$ to the contents of A$, but starting at the 2nd character, and then set the last character of C$ to the first character of A$. Finally, we assign A$ to the contents of C$, so that A$ now contains text that has been “wrapped around” to the left by one character. By doing this over and over again, A$ is continuously wrapped and displayed, giving the appearance of scrolling text. Note that the statement that sets the last character of C$ to A$ takes advantage to Atari BASIC’s unusual string handling, which understands to copy only as much of A$ as the dimensioned length of C$ will allow, which is one character in this case.
Our alien sound effects are created by simply randomizing the voice, tone, and distortion parameters of the SOUND statement (using a constant volume of 10) that we learned in Lesson Seven, causing all four voices to create discordant sounds with no rhyme or reason (line 2040). We continue moving the marquee text and changing sounds until the Start key is detected by PEEKing location 53279, and when the player has had enough humiliation (or rejoicing over their high score), we silence all sounds and return to the start of program (line 2050), so the fun can begin again.
360 PRINT “Super Title Screen”
Now that we’ve seen how to make a simple custom display list combining two text modes, let’s go all out and create an entirely new title screen for Space Assault by combining three text modes along with bitmapped graphics. We’ll also use the marquee text technique to provide a little of the game’s backstory, so we can remove the slightly dull mission briefing that we coded in Lesson Seven. And since we replaced our alien ships with Space Invaders inspired designs, we’ll update the graphics to draw a huge spacecraft over the lush planet Kala below.
Just as we did for the “game over” screen, we start by breaking down our new title screen into the various graphics modes we want to use. We’re going to use Graphics 0, the standard 40-column text mode, not only for our marquee text, but also as “spacer” regions at the top and bottom of the screen.
From this diagram, it’s easy to count the number of “mode lines” for each of the text modes. At the top, we have one line of Graphics 0 (spacer), one line of Graphics 2 (large text), then another line of Graphics 0 (marquee text). At the bottom, we have two lines of Graphics 1 (medium text), then one line of Graphics 0 (spacer). Between these regions, we want to use Graphics 7, the same bitmapped graphics mode we’ve been using for all of our playfield drawing in previous lessons—but we need to determine how many mode lines of Graphics 7 are needed to create a complete screen. To calculate this, first we need to know that there are 192 scan lines visible on the typical television set that would be used with an Atari Home Computer. Each graphics mode line generates a specific number of scan lines, which is included in the reference table we used earlier. We can see that one Graphics 0 mode line generates 8 scan lines, and one Graphics 2 mode line generates 16 scan lines, for example. If we add up the scan lines generated by all the mode lines of our text graphics, we see that we’ve covered 56 scan lines. This means that we need to cover 136 more scan lines to complete the required 192. Since each mode line of Graphics 7 generates 2 scan lines, we know we need 68 mode lines to do the job. This calculation becomes important when we actually modify the display list.
We start with a full screen of Graphics 7 and establish our colors, then hide the cursor by POKEing register 752, which is necessary since we’ll be using Graphics 0 text (line 2330). We assign DL to the start of the current display list just like we did before, and POKE our LMS instruction, which is 66 this time (64 plus the ANTIC number for Graphics 0, which is 2). Then we finish POKEing the text mode lines at the top of our display list (line 2335). Now we need to skip the required number of Graphics 7 mode lines, which is why we had to compute this number earlier, so we start POKEing again 68 locations ahead and complete our text mode lines at the bottom. Finally we finish with our JVB instruction just as we did before (line 2340). Now we can start to draw and write on this amazing new display list!
However, there’s a new wrinkle to be aware of when using a display list combining text modes and bitmapped graphics. Familiar statements like PLOT and POSITION use coordinates that refer to the top of the screen as their origin coordinate, but this reference no longer makes sense because of the mixture of graphics modes. Remember on our “game over” screen we had to POKE 87 with the graphics mode for each PRINT. Now in addition to that step we need to “fool” the ANTIC chip into thinking the mode we are working with starts at the top of the screen, just to keep the coordinate system correct. We can get the location of the actual top of screen memory by PEEKing registers 88 and 89 (line 2345), and store that 16-bit address in a variable called TPS (for “top of screen”). We will be changing these registers many times as we create our title screen, so let’s use a subroutine.
Before calling GOSUB 4010, we need to set MODE to the graphics mode number we’ll be using. We also need to set OFFSET to the number of bytes to add to the “top of screen” location, which unfortunately involves another computation using our indispensable reference table. This time we need to know the number of bytes per mode line, since we want to end up at the exact place in memory where the graphics mode line we want to use begins. After we have this new “top of screen” address, we POKE it back into registers 88 and 89 using some math that converts a 16-bit address into two 8-bit numbers (line 4020), and now ANTIC will believe that the graphics mode we want to use starts at the top of the screen. This is an unusual concept to grasp, but it may make more sense when we see this subroutine in use.
First we want to PRINT the large “SPACE ASSAULT” title at the top of the screen, so we need to use our Graphics 2 line, and we need to skip over the Graphics 0 line that we’re using as a spacer. Since each Graphics 0 mode line uses 40 bytes, we set OFFSET to 40 before calling our subroutine (line 2350). When the subroutine returns, we can use POSITION 4,0 before PRINTing the title, because ANTIC thinks that our Graphics 2 line starts at the top of the screen (line 2355). Next we switch to our Graphics 0 mode line and PRINT nothing for now, since we’ll start our marquee loop when we finish drawing the rest of the screen (lines 2360-2365). After switching to Graphics 7 (line 2370), we plot a few random stars just like we did in Lesson One (line 2375), and then draw the planet Kala and our menacing alien ship, which is done in subroutines to keep the code separated for readability. Before we leave this block of code, note that after we finish drawing we switch to Graphics 1 with a large OFFSET due to the bytes required for all of those lines of Graphics 7 (line 2380), and then we finally PRINT the author credit and “PRESS START” text (line 2385). At this point, our display list madness is complete, and we can finish the lesson with some enjoyable drawing subroutines.
370 PRINT “No Trigonometry Required”
In my high school math seminar class, one of my classmate’s favorite programmer pastimes was figuring out the best way to draw a circle on the Apple II. We learned several ways to do it using trigonometry functions like SIN and COS, and even found a faster way using TAN. One method we never explored is the trigonometry-free midpoint circle algorithm, which I’m sure we would have marveled over, so I took the opportunity to use this interesting code to draw the planet Kala.
The complete algorithm draws a circle in eight segments simultaneously, but I’m only using two octants so that the planet will be “cropped” at the bottom of the screen. From each point on the circumference of the circle, we DRAWTO the middle pixel at the bottom of our Graphics 7 section (line 6040), which mostly fills in the planet’s surface with our green color, but serendipitously misses some pixels to leave an interesting moire pattern, making Kala look quite mysterious.
380 PRINT “Giant Pixel Drawing”
To create the huge alien ship in orbit, I decided to draw “pixels” as large boxes using a customizable subroutine. By changing variables for the horizontal and vertical size and position of the boxes, as well as bitmap data for the image itself, I was able to tweak the location and style of the alien ship until I was satisfied.
The DATA statements (lines 5050-5080) contain simple 1s and 0s to indicate that a box should be filled or empty. Each value is read in a loop into the BIT variable (line 5010), and if BIT is 1, the box is drawn by PLOT and DRAWTO as a series of horizontal lines, using our settings for size and position stored in other variables. Incidentally, this bitmap data is identical to what we used in our Player/Missile Graphics code back in Lesson Three. This same subroutine could be used to add additional enemy ships to the screen, but one huge alien seemed to be enough for me.
390 PRINT “Musical Marquee”
Now that our new title screen is completely rendered, we can add our marquee text, which is much longer than the text we used on the “game over” screen: now it covers Space Assault’s backstory.
Our marquee text is stored in TEXT$, and B1$ and B2$ will be used to manipulate the string and make it scroll (lines 2390-2405). After using our display list subroutine one last time to tell the ANTIC chip that our Graphics 0 mode line is the top of the screen (line 2410), we’re ready to move our text just like we did before. However, we also need to play our theme music at the same time! The solution to this problem is to simply handle both tasks in the same loop.
This block of code is a combination of the music playing loop from Lesson Seven and the marquee text technique we learned earlier. Each note of the music is READ and played as before (lines 2555-2565), but as the note plays we also move our marquee text (line 2570). This happens both in the loop used to fade in the music notes, and also in the loop to wait for the appropriate duration of each note (lines 2580-2595). If we didn’t do this inside both loops, the marquee text would start and stop and seem to stutter, rather than moving smoothly. Also note that string manipulation takes some processing time, so the note duration factor has been adjusted to keep the tempo lively while the marquee text scrolls along. It’s fun to watch the new title screen being drawn and see the results!
400 PRINT “End of Line”
This lesson brings us to the end of Adventures in Atari BASIC. Over the course of eight lessons, we’ve covered all of the major programming topics that you would find in Atari programming magazines of the era, including drawing playfield graphics, Player/Missile Graphics, joystick movement, sound generation, and finally combined graphics modes with advanced display list manipulation. One of the joys of amateur programming is continually modifying code to add new improvements and features, and I’ve certainly enjoyed creating a new version of Space Assault with updated graphics, a shield feature, and a new title screen and musical theme. It’s amazing that today’s emulation technology allows me to revisit this game from over 30 years ago, and hopefully you’ve enjoyed exploring what home programming was like in the early 1980s. In my opinion, the advancements in modern programming have lost a little too much of the accessibility that allowed any computer owner to create whatever they imagined, so it’s been wonderful to return to this era where it seemed anything was possible.
Mikey Walters lives in Austin, Texas, and has an entire room devoted to toys, including Mego figures, Japanese kaiju, and over 1,000 PEZ dispensers. He spends his time thinking about how great it is to be a geek who grew up in the 1970s.