With P/M Graphics
Robert J, Powell
With P/M Graphics
Robert J, Powell
Here's an easy-to-grasp explanation of how to use the Atari computer's built-in system for advanced graphics animation. This month, Part 1 takes you step by step through the fundamentals of setting up player/missile graphics in BASIC. It's intended for those with an intermediate knowledge of BASIC programming.
One of the reasons you probably bought an Atari computer was for its fine graphics capabilities. By now, maybe you've tried to write some programs with graphics and discovered that it takes considerable work to achieve the special effects you've admired in commercial software. Smooth animation seems impossible with ordinary character graphics, and moving any object across the screen using BASIC is difficult and often disappointingly slow.
The alternative is that mysterious Atari feature known as player/missile graphics. With P/M graphics, you can create shapes in any color and move them smoothly around the screen with relative ease. You can simulate three-dimensional movement by making some shapes pass over or beneath other shapes and the screen background. You can even detect when a shape has collided with another shape or with anything else on the screen. P/M graphics is the key to sophisticated animation on Atari computers.
Unfortunately, too many people are intimidated by P/M graphics. Although it isn't the Atari's easiest to use feature, it. isn't the most difficult, either. The mystery surrounding P/M graphics started soon after the original Atari 400 and 800 computers were introduced in 1979. It was obvious from early commercial games like Star Raiders that some innovative graphics were involved, but Atari didn't even mention the feature in any of its manuals. Indeed, the first explanation of how P/M graphics works didn't appear until January 1981, when Atari programmer Chris Crawford wrote an article entitled "Player/Missile Graphics with the Atari Personal Computer System," which appeared in COMPUTE!. Until then, most programmers were in the dark.
A number of magazine articles and books followed, most notably De Re Atari by Crawford and his colleagues at Atari. But since the latest generation of Atari XL and XE owners has missed all this history, it's time for another look at P/M graphics and how it can help you add the professional touch to your programs.
A Layer Of Cellophane
First of all, P/M graphics isn't part of BASIC; there aren't even any Atari BASIC commands or keywords for handling P/M graphics. Instead, P/M graphics is built into the hardware of the computer, specifically the dedicated graphics chips unique to the Atari. Therefore, all P/M manipulation in BASIC must be done with PEEK and POKE statements.
A good way to think of P/M graphics is as a second video image overlapped onto the regular screen, like a layer of colored cellophane. That's why P/M objects can seem to travel over or behind other screen objects without erasing or disturbing them.
This system is known as sprite graphics on most other computers, such as the Commodore 64 and TI 99/4A. On these machines, each movable object is called a sprite; the Commodore can display up to eight at a time without special tricks, and the TI can display up to 32. Atari P/M graphics, an earlier system, consists of eight movable objects, but they're a little different than sprites. On the 64 and TI, sprites are all the same size and are roughly square (although they can be redefined as any shape, of course). On the Atari, there are four full-sized objects called players and four miniature objects called missiles. If you want, the four missiles can be grouped together to form a fifth player. And instead of being square, players and missiles are narrow strips taller than the height of the screen.
If you've never seen these strips, don't be surprised. Most programs that use P/M graphics render all but a small part of the strip invisible on the screen. The small visible part is the player or missile object you actually see. Its shape is determined by numbers POKEd by the program into a section of memory called P/M graphics memory. It's up to your program to set aside and protect this memory when it runs. When your program fills this memory with zeros, the whole P/M strip becomes invisible. By POKEing a few nonzero numbers into P/M memory, your program defines the shape of the visible part of the strip. This shape could be an alien, a spaceship, a cursor for a spreadsheet, or almost anything you want.
In P/M memory, each player strip is eight bits (one byte) wide, and each missile strip is two bits wide. (That's why grouping together the four two-bit missiles results in a fifth player.) All the strips are either 128 or 256 bytes tall (as described below) and extend off the visible screen in both directions. Later, we'll explain how to determine which numbers to POKE to redefine the strips into your own shapes.
Once defined, players and missiles can appear in any graphics or text mode and can be quickly moved about the screen without affecting the background graphics or text. Each player can be a different color, and P/M colors can be different than the regular screen colors - thus allowing more simultaneous colors than are normally available. With a few PEEKS, you can check for collisions between players, players and missiles, and players and screen objects (including characters). Before creating a player, let's take a look at how P/M memory is organized.
Your program must set up P/M memory to store the shape data for players. The amount of memory you set aside depends on the degree of P/M resolution desired. Two resolutions are available: single scan-line and double scan-line (a scan-line is the thinnest horizontal line visible on your video screen). Single-line resolution allows more detailed shapes but requires twice as much P/M memory. A single-line player is 256 bytes tall and a double-line player is 128 bytes tall. Single-line resolution requires a total of 2K, or 2,048 bytes; double-line resolution requires a total of 1K, or 1,024 bytes.
To protect P/M memory against intrusions, it's generally established near the top of user RAM just below screen memory. Another requirement is that P/M memory must start on an address that is a multiple of eight pages (2K) for single-line resolution or a multiple of four pages (1K) for double-line resolution. (A memory page equals 256 bytes.)
The accompanying figure shows a map of P/M memory. By custom, the starting address of P/M memory is assigned to the variable PMBASE. Since the exact memory address of PMBASE varies according to how much RAM is in the computer, which graphics mode you're using, and other factors, the map shows all other addresses as relative offsets from PMBASE. For single-line resolution, the missile data area occupies 256 bytes starting at PMBASE+768. Player data starts at PMBASE+1024 and requires 256 bytes for each player (numbered 0 through 3). For doubleline resolution, all these offsets would be halved, since only half as much memory is required. Missile data would start at PMBASE+384 and player data would start at PMBASE+512.
A Bunch Of POKES
For an example, let's write a program to set up single-line resolution P/M graphics. This requires a bunch of POKEs which may look confusing. Even if you don't fully understand the purpose of the POKEs, however, you can still use them in your programs.
First, you have to determine the number of memory pages to the starting address of P/M memory, or PMBASE. To do this, you use a memory address called RAMTOP. Logically enough, RAMTOP stores the address of the top of available RAM. That is, the computer looks at RAMTOP to calculate how much free memory is available and won't let BASIC use any memory above RAMTOP. By POKEing a lower value into RAMTOP, you can make the computer think there is less RAM and therefore free up some memory above RAMTOP (just as lowering your ceiling would create more room in your attic). The extra RAM freed up by this method is ideal for P/M memory because it's relatively safe from interference.
The value stored in RAMTOP is the number of memory pages available. How far should you lower RAMTOP? Remember that 1K is required for double-line resolution P/M graphics and 2K is required for single-line resolution P/M graphics. Since we're using single-line resolution in our example, we need to protect 2K (2,048 bytes) for P/M memory. That means we must subtract eight pages from the value in RAMTOP (8*256=2,048). The address for RAMTOP is 106 decimal, so the statement looks like this:
10 POKE 106,PEEK(106)-8
Second, you must store this new page number for RAMTOP in the P/M base register at memory location 54279:
20 POKE 54279,PEEK(106)
Third, select your graphics mode with the usual GRAPHICS statement, then establish the actual starting address for PMBASE. Let's stick with ordinary text mode and make the screen background black for maximum contrast:
30 GRAPHICS 0:SETCOLOR 2,0,0
Finally, two more POKES are required to enable the Direct Memory Access control register (559 decimal) and another address which turns on P/M graphics (53277 decimal):
50 POKE 559,62
60 POKE 53277,3
60 POKE 53277,3
(Note that for double-line P/M resolution, line 50 would be POKE 559,46.)
P/M graphics memory is now set up and activated. Before you can run the program and actually see the players, though, you have to define some shape data, assign colors, and position them on the visible part of the screen. These tasks require a few additional POKEs.
Revealing The Strips
Let's assign the colors first. There aren't any BASIC statements like COLOR or SETCOLOR for P/M graphics, so you have to POKE color values into certain memory locations instead. Each of the four players has its own color location, or player color register. These memory locations are 704 for player 0, 705 for player 1, 706 for player 2, and 707 for player 3. (Incidentally, the missiles lack independent color control, so missile 0 takes the same color as player 0, missile 1 takes the same color as player 1, etc.)
To determine which number to POKE into the player color registers, consult the accompanying table of Atari color numbers and use this formula:
|Atari Color Numbers
|0 Gray||8 Blue|
|1 Gold||9 Light blue|
|2 Orange||10 Turquoise|
|3 Red-orange||11 Green-blue|
|4 Pink||12 Green|
|5 Purple||13 Yellow-green|
|7 Blue||15 Light
P/M color = color number * 16 + luminance
Luminance means brightness; this should be an even number from 0 to 14. To make player 0 appear medium pink, you could POKE 704,72 (72=4*16+8). To make player 3 appear dark green, POKE 707,13*16+4. (The exact hue may vary according to how your TV or monitor is adjusted.) For our example program, we'll make the players red, green, light blue, and dark blue:
70 POKE 704,68:POKE 705,198:POKE
Next, we want to make sure the player strips are positioned where we can see them. In addition to a color register, each player also is controlled by a horizontal position register. This is a memory address that determines each player's horizontal location. The registers are 53248 for player 0, 53249 for player 1, 53250 for player 2, and 53251 for player 3. You can POKE any value into these registers from 0 to 255; lower values position the player to the left, and higher values position the player to the right. However, values less than 45 begin moving the player off the left edge of the visible screen, and values greater than 205 begin moving the player off the right edge of the screen.
For this example, let's group all four players together near the right edge of the screen:
80 POKE 53248,160:POKE 53249,170:
POKE 53250,180:POKE 53251,190
POKE 53250,180:POKE 53251,190
Finally, to make the player strips visible, we must fill P/M memory with shape data. For now, let's not worry about creating a fancy shape such as a spaceship. Instead, we'll reveal the players as they really are by completely filling P/M memory with 255:
90 FOR X=PMBASE+1024 TO
Now run the program. In a few seconds, you'll see the four player strips appear on screen as line 90 fills P/M memory with the shape data.
A Few Experiments
After the program stops, the READY prompt reappears and the four players remain on the screen. This is an ideal time to observe how P/M graphics works. Try these experiments:
• Type LIST. Notice how the program listing on the screen overlaps the players.
• Press SHIFT-CLEAR or CTRL-CLEAR. This clears the program listing off the screen but leaves the players undisturbed. P/M graphics, remember, are independent of regular screen graphics and text.
• In direct mode (without a line number), change the color of player 0 by POKEing a different value into the player 0 color register-for example, POKE 704,250. Also change the colors of players 1, 2, and 3 by POKEing color registers 705, 706, and 707.
• In direct mode, relocate player 0 to the left side of the screen by POKEing a lower value into the player 0 horizontal position register-say, POKE 53248,60. Relocate the other players, too, by POKEing their horizontal registers. Make a player disappear from the visible screen by POKEing a value from 0 to 45 or 205 to 255. Try stacking two players atop each other by POKEing the same value into their horizontal registers, and observe which one has display priority.
Next month, we'll show additional ways to manipulate P/M graphics and also how to transform the player strip into a shape of your own design.