4

PRINTing P/M Graphics

titlebar.gif

Sheldon Leemon


Using a PRINT statement to make multiple POKEs can speed up your programs. The technique is easily learned and will work especially well with player/missile graphics.

The PRINT statement is one of the easiest BASIC commands to learn, and one of the first mastered by the beginning programmer. POKE, on the other hand, seems very mysterious to those just starting out with computers. Just changing the value of certain memory locations can have many different effects, but the how and why often elude the novice.

The POKE and PRINT commands are alike in a number of ways. For example, it is fairly easy to make a character appear on the screen by POKEing a value to display memory. Since Atari screen memory isn't always in the same place, you first have to find the start of screen memory by entering the statement SM = PEEK(88) + 256*PEEK(89). Now you POKE SM,33, and the letter A will appear in the top-left corner of the screen. You might think of this as PRINTing with the POKE statement. The reason that you use a 33 to make an A appear is that it is the internal screen code value used to display that letter. A table of these screen codes appears on page 55 of the Atari BASIC Reference Manual.(The internal character set can also be found on page 120 of COMPUTE!'s First Book of Atari Graphicsand in COMPUTE!'s Third Book of Atari.)Try not to confuse this with the ATASCII values that appear in Appendix C of the manual. Those are the values that work with the CHR$ statement.

The fact that you can accomplish the same thing with both statements points out their fundamental similarity. When you get right down to it, all that the PRINT statement really does is to POKE a series of values into screen memory according to certain rules of cursor placement. The main advantage of using PRINT instead of POKE is its ease of use and speed, as compared to calculating a screen location and a numeric value for each character that you wish to display.

But if printing to the screen really involves only quickly POKEing a series of values into screen memory, it is not too different from a number of other situations in which the user must POKE a number of values into sequential memory locations. Examples of such situations include putting a machine language subroutine into place, installing a user-defined character set, or setting a number of music or graphics registers at once. If PRINT can facilitate the movement of a number of values to screen and color memory in one situation, might it not also be able to help out in some of these other situations?


Fooling the Computer

It is quite possible to use the PRINT statement for purposes other than printing to the screen. To do so, we have to make the computer think that the address we want POKEd to is the address of screen memory, and then PRINT a string of characters to that location whose POKE values correspond to the changes we wish to make to memory. The first part is possible because screen memory is not fixed in one set location in the Atari. Instead, the computer has a way of telling the display chip what spot in memory to display, and of letting the operating system know what area of memory is currently being shown on screen. Thus it knows the proper place to PRINT. Normally, the display chip reads and displays the same area of screen memory that the operating system (OS) writes. It is possible, however, to change the OS pointer so that the area of memory being PRINTed is different from the one being displayed.

Locations 88 and 89 hold the OS pointer to screen memory. The number in location 88 plus the number in location 89 multiplied by 256 equals the address of the first location which will be written to as screen memory. Let's try an experiment to see how this works. ENTER and RUN the following:

10 L=PEEK(88):H=PEEK(89) 
20 POKE 88,0:POKE 89,6 
30 POSITION 0,0:PRINT "A":PRINT "B" 
40 POKE 88,L:POKE 89,H

Nothing is printed on the screen, although the cursor does move to the top line. Where in memory did the PRINT statements write to?

We can figure out step by step what locations must have changed. When we POKEd 88 with a 0 and 89 with a 6, we changed what the computer thought the top of PRINT memory was to 0 + 6*256 or 1536. Using the POSITION statement, we home the cursor to the top left, which is the first character in screen memory. Therefore, the screen value of A must have been POKEd into 1536. If we type:

PRINT PEEK(1536) 

We find a 33, which is indeed the screen value of A. But where did the B go? Since after every PRINT statement, the cursor moves to the next line, the cursor would move at least 40 spaces in memory. In addition, the cursor also moves two more spaces for the right margin, making a total of 42. If we type:

PRINT PEEK(1536+42) 

We will find a 34, which is the screen value of B.


Using PRINT with P/M Graphics

One practical application for this technique is in displaying player/missile graphics. Normally, to move a player vertically you must POKE each byte of shape data into memory, one byte at a time, causing motion that is slow and jerky. But by changing the operating system PRINT pointers to the player area, we can use the speed of the PRINT statement to make the multiple POKEs appear to occur at the same time. This can be done by PRINTing a string of characters into player memory. This string will contain the data for the player. And, by combining data for several shapes into one long shape string, we can change the shape of the player at any time just by PRINTing a different segment of the string.

Program 1 shows just how easily a short BASIC program can move and animate a player. When the ship appears on the screen, insert a joystick into port 1. Use the joystick to move the ship around. You will notice that when you move the ship, its shape will change to point in the direction in which it is moving. The program has enough internal remarks to enable someone with a basic understanding of player/missile graphics to follow the program logic.


Player/Missile Graphics from PILOT

An added feature of this technique is that it is applicable to other languages besides BASIC. PILOT, for example, is a language that lacks built-in player/missile graphics commands. The T: statement in PILOT works the same way as PRINT in BASIC, so it is possible to use the same techniques to move a player in PILOT. Program 2 is a simplified program in PILOT which demonstrates moving a player with a joystick. Considering that PILOT allows only one statement per line, you can see that this program is extremely compact. When you type it in, pay careful attention to characters you enter for $SHIP. There are instructions in the comments at the end of the program to help you.


UnPRINTable Characters

One problem you should keep in mind is that not every value that you may need in screen memory can be placed there by a printing character. Some characters move the cursor rather than print anything on the screen, and in order to get them to print you must precede them with an ESCape character. For example, let's suppose you want to put into screen memory a value of 28, which corresponds to the cursor up arrow. Rather than moving the "cursor" up a line, you must print an ESCape and an up arrow in order for the character to be placed into memory. Program 1 has many instances in which such nonprinting characters are preceded by a 27 so that their number value will be placed in memory. Some characters, like the quote (internal value of 2) and the carriage return (internal value of 253) are even more difficult to PRINT. Keep a sharp eye out for such exceptions. Since perhaps the greatest drawback to this technique is in generating the strings to print, you might want to write a short program to do this for you.


Other Uses

I think you'll find this technique a useful one for controlling player/missile graphics from BASIC. But don't ignore the possibilities for using it to install nonrelocatable machine language into page six, for producing 16-bit sound, and for other applications where you have to move a number of bytes of data to a specific spot in memory quickly and efficiently.


Program 1. PRINTing Player/Missile Graphics from BASIC

Download P114L1.BAS (Saved BASIC)
Download / View P114L1.LST (Listed BASIC)

Program 2. PRINTing Player/Missile Graphics from PILOT

Download / View P114L2.PLT (PILOT)

Return to Table of Contents | Previous Section | Next Section